@wpelevator/wp-release 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,6 +4,7 @@ import ignore from 'ignore';
4
4
  import { normalizeTag } from "./deploy-options.js";
5
5
  import { ValidationError } from "./errors.js";
6
6
  import { selectFiles } from "./file-selection.js";
7
+ import { findFileHeaderLine, findReadmeHeaderLine, getLineNumber, readFileStart, } from "./package-meta.js";
7
8
  export const GIT_TAG_FORMAT = '{version}';
8
9
  const TAG_REF_PREFIX = 'refs/tags/';
9
10
  /**
@@ -11,6 +12,39 @@ const TAG_REF_PREFIX = 'refs/tags/';
11
12
  * dependencies with their own versions.
12
13
  */
13
14
  const CONSTANT_SEARCH_IGNORE = ['node_modules/', 'vendor/', '.*'];
15
+ /**
16
+ * Get the problems of version mismatches, with their files relative to the
17
+ * working directory instead of the plugin directory.
18
+ *
19
+ * @param sourceDir Directory that the mismatch files are relative to.
20
+ * @param mismatches Mismatches from findVersionMismatches().
21
+ * @return Problems.
22
+ */
23
+ export function getVersionMismatchProblems(sourceDir, mismatches) {
24
+ return mismatches.map(({ message, file, line }) => ({
25
+ message,
26
+ file: file ? join(sourceDir, file) : null,
27
+ line,
28
+ title: 'Version mismatch',
29
+ }));
30
+ }
31
+ /**
32
+ * Versions that don't agree, thrown by a deploy before anything is written.
33
+ * The message lists every mismatch, and the problems have their files and
34
+ * lines.
35
+ */
36
+ export class VersionMismatchError extends ValidationError {
37
+ name = 'VersionMismatchError';
38
+ /** Directory that the mismatch files are relative to. */
39
+ sourceDir;
40
+ /** Every mismatch. */
41
+ mismatches;
42
+ constructor(sourceDir, mismatches) {
43
+ super(mismatches.map(({ message }) => message).join('\n'), getVersionMismatchProblems(sourceDir, mismatches));
44
+ this.sourceDir = sourceDir;
45
+ this.mismatches = mismatches;
46
+ }
47
+ }
14
48
  /**
15
49
  * Get the version from a git tag with a format like v{version} or
16
50
  * {slug}-{version}. A leading "v" is stripped from the version, like for
@@ -44,6 +78,17 @@ function escapeRegExp(text) {
44
78
  * @return Values in the order they appear.
45
79
  */
46
80
  export function findConstantValues(contents, name) {
81
+ return findConstantDefinitions(contents, name).map(({ value }) => value);
82
+ }
83
+ /**
84
+ * Find the definitions of a PHP constant set with define( 'NAME', '1.2.0' )
85
+ * or const NAME = '1.2.0'.
86
+ *
87
+ * @param contents PHP code.
88
+ * @param name Constant name.
89
+ * @return Values and their line numbers, in the order they appear.
90
+ */
91
+ export function findConstantDefinitions(contents, name) {
47
92
  const quotedName = `(['"])${escapeRegExp(name)}\\1`;
48
93
  const patterns = [
49
94
  new RegExp(`\\bdefine\\s*\\(\\s*${quotedName}\\s*,\\s*(['"])(.*?)\\2\\s*[,)]`, 'g'),
@@ -52,7 +97,10 @@ export function findConstantValues(contents, name) {
52
97
  return patterns
53
98
  .flatMap((pattern) => [...contents.matchAll(pattern)])
54
99
  .sort((a, b) => (a.index ?? 0) - (b.index ?? 0))
55
- .map((match) => match[3] ?? '');
100
+ .map((match) => ({
101
+ value: match[3] ?? '',
102
+ line: getLineNumber(contents, match.index ?? 0),
103
+ }));
56
104
  }
57
105
  /**
58
106
  * Compare a version with the expected one.
@@ -100,16 +148,17 @@ async function compareConstants(sourceDir, constants, expected) {
100
148
  })));
101
149
  return constants.flatMap((name) => {
102
150
  const source = `Constant ${name}`;
103
- const definitions = sources.flatMap(({ file, contents }) => findConstantValues(contents, name).map((actual) => ({
151
+ const definitions = sources.flatMap(({ file, contents }) => findConstantDefinitions(contents, name).map(({ value, line }) => ({
104
152
  source,
105
153
  file,
106
- actual,
154
+ line,
155
+ actual: value,
107
156
  })));
108
157
  if (definitions.length) {
109
158
  return definitions.map((definition) => compareVersion(definition, expected));
110
159
  }
111
160
  return [
112
- compareVersion({ source, file: null, actual: null }, expected),
161
+ compareVersion({ source, file: null, line: null, actual: null }, expected),
113
162
  ];
114
163
  });
115
164
  }
@@ -127,11 +176,12 @@ function compareGitTag(input, expected) {
127
176
  return {
128
177
  source: 'Git tag',
129
178
  file: null,
179
+ line: null,
130
180
  actual: tag,
131
181
  message: `Git tag ${tag} doesn't match the format ${input.gitTagFormat}.`,
132
182
  };
133
183
  }
134
- return compareVersion({ source: `Git tag ${tag}`, file: null, actual }, expected);
184
+ return compareVersion({ source: `Git tag ${tag}`, file: null, line: null, actual }, expected);
135
185
  }
136
186
  /**
137
187
  * Check that the Version header, readme Stable tag, PHP constants and git tag
@@ -152,6 +202,7 @@ export async function findVersionMismatches(input) {
152
202
  {
153
203
  source: 'Version header',
154
204
  file: meta.mainFile,
205
+ line: null,
155
206
  actual: null,
156
207
  message: `Version header is missing in ${meta.mainFile}.`,
157
208
  },
@@ -164,12 +215,14 @@ export async function findVersionMismatches(input) {
164
215
  compareVersion({
165
216
  source: 'Version header',
166
217
  file: meta.mainFile,
218
+ line: findFileHeaderLine((await readFileStart(join(sourceDir, meta.mainFile))) ?? '', 'Version'),
167
219
  actual: meta.version,
168
220
  }, expected),
169
221
  checkStableTag && !readme
170
222
  ? {
171
223
  source: 'Stable tag',
172
224
  file: null,
225
+ line: null,
173
226
  actual: null,
174
227
  message: `Readme is missing, expected Stable tag ${expected}.`,
175
228
  }
@@ -178,6 +231,7 @@ export async function findVersionMismatches(input) {
178
231
  ? compareVersion({
179
232
  source: 'Stable tag',
180
233
  file: readme.file,
234
+ line: findReadmeHeaderLine(await readFile(join(sourceDir, readme.file), 'utf8'), 'Stable tag'),
181
235
  actual: readme.headers['Stable tag'] ?? null,
182
236
  }, expected)
183
237
  : null,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wpelevator/wp-release",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Package, checksum, sign, verify and version-check WordPress plugins and themes, and deploy plugins to WordPress.org SVN",
5
5
  "license": "MIT",
6
6
  "repository": {