Completed
Push — add/changelog-tooling ( c37726...963953 )
by
unknown
371:25 queued 360:46
created

Changelog::setEntries()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 10

Duplication

Lines 10
Ratio 100 %

Importance

Changes 0
Metric Value
cc 4
nc 4
nop 1
dl 10
loc 10
rs 9.9332
c 0
b 0
f 0
1
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
2
/**
3
 * Class representing a changelog.
4
 *
5
 * @package automattic/jetpack-changelogger
6
 */
7
8
// phpcs:disable WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
9
10
namespace Automattic\Jetpack\Changelog;
11
12
use InvalidArgumentException;
13
14
/**
15
 * Class representing a changelog.
16
 */
17
class Changelog {
18
19
	/**
20
	 * Content before the changelog itself.
21
	 *
22
	 * @var string
23
	 */
24
	protected $prologue = '';
25
26
	/**
27
	 * Content after the changelog itself.
28
	 *
29
	 * @var string
30
	 */
31
	protected $epilogue = '';
32
33
	/**
34
	 * Changelog entries, one per version.
35
	 *
36
	 * @var ChangelogEntry[]
37
	 */
38
	protected $entries = array();
39
40
	/**
41
	 * Get the prologue content.
42
	 *
43
	 * @return string
44
	 */
45
	public function getPrologue() {
46
		return $this->prologue;
47
	}
48
49
	/**
50
	 * Set the prologue content.
51
	 *
52
	 * @param string $prologue Prologue content to set.
53
	 * @return $this
54
	 */
55
	public function setPrologue( $prologue ) {
56
		$this->prologue = (string) $prologue;
57
		return $this;
58
	}
59
60
	/**
61
	 * Get the epilogue content.
62
	 *
63
	 * @return string
64
	 */
65
	public function getEpilogue() {
66
		return $this->epilogue;
67
	}
68
69
	/**
70
	 * Set the epilogue content.
71
	 *
72
	 * @param string $epilogue Epilogue content to set.
73
	 * @return $this
74
	 */
75
	public function setEpilogue( $epilogue ) {
76
		$this->epilogue = (string) $epilogue;
77
		return $this;
78
	}
79
80
	/**
81
	 * Get the list of changelog entries.
82
	 *
83
	 * @return ChangelogEntry[]
84
	 */
85
	public function getEntries() {
86
		return $this->entries;
87
	}
88
89
	/**
90
	 * Set the list of changelog entries.
91
	 *
92
	 * This replaces all existing entries.
93
	 *
94
	 * @param ChangelogEntry[] $entries Changelog entries.
95
	 * @return $this
96
	 * @throws InvalidArgumentException If an argument is invalid.
97
	 */
98 View Code Duplication
	public function setEntries( array $entries ) {
99
		foreach ( $entries as $i => $entry ) {
100
			if ( ! $entry instanceof ChangelogEntry ) {
101
				$what = is_object( $entry ) ? get_class( $entry ) : gettype( $entry );
102
				throw new InvalidArgumentException( __METHOD__ . ": Expected a ChangelogEntry, got $what at index $i" );
103
			}
104
		}
105
		$this->entries = array_values( $entries );
106
		return $this;
107
	}
108
109
	/**
110
	 * Get the latest changelog entry.
111
	 *
112
	 * @return ChangelogEntry|null
113
	 */
114
	public function getLatestEntry() {
115
		return isset( $this->entries[0] ) ? $this->entries[0] : null;
116
	}
117
118
	/**
119
	 * Add a new entry as the latest.
120
	 *
121
	 * If no new entry object is provided, one will be created. The version
122
	 * number on the new entry is selected as follows.
123
	 *
124
	 * - If there are no existing entries, the new entry is version "0.0.1-dev".
125
	 * - If the latest existing entry has a version number ending in something
126
	 *   like "-p1" (see `version_compare()`), the patch number is incremented.
127
	 * - Otherwise, "-p1" is appended.
128
	 *
129
	 * You'll probably want to chain to `ChangelogEntry::setVersion()` to
130
	 * replace that with something else.
131
	 *
132
	 * @param ChangelogEntry|null $entry New entry, or null to create an empty entry.
133
	 * @return ChangelogEntry The added entry. Always `$entry` if an entry was passed.
134
	 */
135
	public function addEntry( ChangelogEntry $entry = null ) {
136
		if ( null === $entry ) {
137
			$latest = $this->getLatestEntry();
138
			if ( $latest ) {
139
				$version = $latest->getVersion();
140
				if ( preg_match( '/[._+-]pl?[._+-]?(\d+)$/', $version, $m ) ) {
141
					$version = substr( $version, 0, -strlen( $m[1] ) ) . ( $m[1] + 1 );
142
				} else {
143
					$version .= '-p1';
144
				}
145
			} else {
146
				$version = '0.0.1-dev';
147
			}
148
			$entry = new ChangelogEntry( $version );
149
		}
150
		array_unshift( $this->entries, $entry );
151
		return $entry;
152
	}
153
154
	/**
155
	 * Get the list of versions in the changelog.
156
	 *
157
	 * @return string[]
158
	 */
159
	public function getVersions() {
160
		$ret = array();
161
		foreach ( $this->entries as $entry ) {
162
			$ret[] = $entry->getVersion();
163
		}
164
		return $ret;
165
	}
166
167
	/**
168
	 * Find an entry by version.
169
	 *
170
	 * @param string $version Version to search for.
171
	 * @param string $operator Operator as for `version_compare()`. Note the
172
	 *   passed `$version` is passed to `version_compare()` as the second
173
	 *   argument, and the first entry matching is returned.
174
	 * @return ChangelogEntry|null
175
	 */
176
	public function findEntryByVersion( $version, $operator = '==' ) {
177
		foreach ( $this->entries as $entry ) {
178
			if ( version_compare( $entry->getVersion(), $version, $operator ) ) {
179
				return $entry;
180
			}
181
		}
182
		return null;
183
	}
184
185
	/**
186
	 * Fetch all entries by a version check.
187
	 *
188
	 * @param array $constraints Version constraints. Keys are operations
189
	 *   recognized by `version_compare()`, values are the version to compare
190
	 *   with as the second argument.
191
	 * @return ChangelogEntry[]
192
	 */
193
	public function findEntriesByVersions( $constraints ) {
194
		$ret = array();
195
		foreach ( $this->entries as $entry ) {
196
			foreach ( $constraints as $op => $version ) {
197
				if ( ! version_compare( $entry->getVersion(), $version, $op ) ) {
198
					continue 2;
199
				}
200
			}
201
			$ret[] = $entry;
202
		}
203
		return $ret;
204
	}
205
206
}
207