breakage 0.8.5 → 0.9.1
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.
- package/README.md +163 -47
- package/dist/{breakage-B7dJsgcu.js → breakage-DJiIiLzL.js} +958 -221
- package/dist/breakage-DJiIiLzL.js.map +1 -0
- package/dist/breakage.d.ts +239 -71
- package/dist/breakage.d.ts.map +1 -1
- package/dist/breakage.js +3 -1
- package/dist/breakage.x.js +216 -79
- package/dist/breakage.x.js.map +1 -1
- package/dist/changesets.d.ts +8 -0
- package/dist/changesets.d.ts.map +1 -0
- package/dist/changesets.js +27 -0
- package/dist/changesets.js.map +1 -0
- package/dist/release-BsdIDT4g.js +69 -0
- package/dist/release-BsdIDT4g.js.map +1 -0
- package/dist/release-D47BqRuB.d.ts +40 -0
- package/dist/release-D47BqRuB.d.ts.map +1 -0
- package/npm.md +198 -44
- package/package.json +45 -6
- package/src/breakage.ts +142 -73
- package/src/breakage.x.ts +174 -127
- package/src/changesets.ts +51 -0
- package/src/config.ts +131 -0
- package/src/npm/check.ts +70 -50
- package/src/npm/cli.ts +30 -22
- package/src/npm/config.ts +38 -6
- package/src/npm/environment.ts +10 -10
- package/src/npm/matrix-cli.ts +170 -0
- package/src/npm/matrix-model.ts +395 -0
- package/src/npm/matrix.ts +657 -0
- package/src/npm/release.ts +9 -25
- package/src/npm/types.ts +5 -45
- package/src/release.ts +153 -0
- package/src/{npm/command.ts → task.ts} +2 -0
- package/dist/breakage-B7dJsgcu.js.map +0 -1
- package/dist/breakage.$configPath.schema.json +0 -33
- package/dist/breakage.help.schema.json +0 -6
- package/dist/breakage.main.schema.json +0 -33
- package/dist/breakage.npm.check.schema.json +0 -16
- package/dist/breakage.npm.help.schema.json +0 -6
- package/dist/breakage.npm.schema.json +0 -6
- package/dist/breakage.npm.test.$peer.$range.schema.json +0 -16
- package/dist/breakage.npm.test.schema.json +0 -16
- package/dist/breakage.prelude.$configPath.schema.json +0 -31
- package/dist/breakage.prelude.schema.json +0 -31
- package/dist/breakage.schema.schema.json +0 -10
package/dist/breakage.x.js
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as
|
|
2
|
+
import { _ as resolveConfig, a as npmVerify, b as breakagePrelude, c as npmCheck, d as configOptions, f as configPath, g as loadConfig, i as npmPlan, l as npmTest, m as defaultConfig, n as npmExecute, o as writeMatrixJson, p as configSchema, r as npmMatrix, s as formatNpmReport, t as breakage, u as configFields, x as errorMessage, y as validateConfig } from "./breakage-DJiIiLzL.js";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import logger from "takua";
|
|
5
|
-
import { readFile } from "node:fs/promises";
|
|
6
|
-
import { inspect } from "node:util";
|
|
5
|
+
import { glob, readFile } from "node:fs/promises";
|
|
7
6
|
import { type } from "arktype";
|
|
8
7
|
import { cli, completionResponse, encapsulate, help, logWarnings, noOptions, optional, options, parseBooleanOption, required } from "comline";
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
//#region src/npm/cli.ts
|
|
8
|
+
import { inspect } from "node:util";
|
|
9
|
+
// src/npm/cli.ts
|
|
12
10
|
const common = {
|
|
11
|
+
release: configOptions.optionConfigs.release,
|
|
12
|
+
npm: configOptions.optionConfigs.npm,
|
|
13
|
+
npmMatrix: configOptions.optionConfigs.npmMatrix,
|
|
13
14
|
config: {
|
|
15
|
+
schema: type(`string`),
|
|
14
16
|
required: false,
|
|
15
|
-
description: `Configuration file (defaults to breakage.config.ts
|
|
17
|
+
description: `Configuration file (defaults to breakage.config.ts).`,
|
|
16
18
|
example: `--config ./breakage.config.ts`,
|
|
17
19
|
completion: {
|
|
18
20
|
fileSystem: `files`,
|
|
@@ -20,6 +22,7 @@ const common = {
|
|
|
20
22
|
}
|
|
21
23
|
},
|
|
22
24
|
json: {
|
|
25
|
+
schema: type(`boolean`),
|
|
23
26
|
required: false,
|
|
24
27
|
description: `Emit the structured result.`,
|
|
25
28
|
example: `--json`,
|
|
@@ -29,10 +32,14 @@ const common = {
|
|
|
29
32
|
const npmCheckManual = options(`Check npm peer compatibility and changes in declared support.`, type({
|
|
30
33
|
"config?": `string`,
|
|
31
34
|
"json?": `boolean`,
|
|
32
|
-
"coverageOnly?": `boolean
|
|
35
|
+
"coverageOnly?": `boolean`,
|
|
36
|
+
"release?": configOptions.optionsSchema.get(`release`),
|
|
37
|
+
"npm?": configOptions.optionsSchema.get(`npm`),
|
|
38
|
+
"npmMatrix?": configOptions.optionsSchema.get(`npmMatrix`)
|
|
33
39
|
}), {
|
|
34
40
|
...common,
|
|
35
41
|
coverageOnly: {
|
|
42
|
+
schema: type(`boolean`),
|
|
36
43
|
aliases: [`coverage-only`],
|
|
37
44
|
required: false,
|
|
38
45
|
description: `Audit coverage and support changes without executing assertions.`,
|
|
@@ -43,10 +50,14 @@ const npmCheckManual = options(`Check npm peer compatibility and changes in decl
|
|
|
43
50
|
const npmTestManual = options(`Run current contracts in matching complete peer environments.`, type({
|
|
44
51
|
"config?": `string`,
|
|
45
52
|
"json?": `boolean`,
|
|
46
|
-
"representative?": `string
|
|
53
|
+
"representative?": `string`,
|
|
54
|
+
"release?": configOptions.optionsSchema.get(`release`),
|
|
55
|
+
"npm?": configOptions.optionsSchema.get(`npm`),
|
|
56
|
+
"npmMatrix?": configOptions.optionsSchema.get(`npmMatrix`)
|
|
47
57
|
}), {
|
|
48
58
|
...common,
|
|
49
59
|
representative: {
|
|
60
|
+
schema: type(`string`),
|
|
50
61
|
required: false,
|
|
51
62
|
description: `Select an exact configured representative path relative to the package.`,
|
|
52
63
|
example: `--representative peer-environments/react-19`,
|
|
@@ -56,14 +67,10 @@ const npmTestManual = options(`Run current contracts in matching complete peer e
|
|
|
56
67
|
}
|
|
57
68
|
}
|
|
58
69
|
});
|
|
59
|
-
function defaultConfig(directory) {
|
|
60
|
-
return path.join(directory, existsSync(path.join(directory, `breakage.config.ts`)) ? `breakage.config.ts` : `breakage.config.json`);
|
|
61
|
-
}
|
|
62
70
|
async function runNpmCli(action, opts, peerSelection) {
|
|
63
71
|
try {
|
|
64
72
|
const filename = path.resolve(opts.config ?? defaultConfig(process.cwd()));
|
|
65
|
-
const
|
|
66
|
-
const config = record(loaded) ? loaded.npm : void 0;
|
|
73
|
+
const config = (await loadConfig(filename)).npm;
|
|
67
74
|
validateConfig(config);
|
|
68
75
|
let selection;
|
|
69
76
|
if (action === `test`) {
|
|
@@ -87,18 +94,134 @@ async function runNpmCli(action, opts, peerSelection) {
|
|
|
87
94
|
return 2;
|
|
88
95
|
}
|
|
89
96
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
"
|
|
94
|
-
"
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
// src/npm/matrix-cli.ts
|
|
98
|
+
const hiddenSchema = {
|
|
99
|
+
"release?": configOptions.optionsSchema.get(`release`),
|
|
100
|
+
"npm?": configOptions.optionsSchema.get(`npm`),
|
|
101
|
+
"npmMatrix?": configOptions.optionsSchema.get(`npmMatrix`)
|
|
102
|
+
};
|
|
103
|
+
const hidden = {
|
|
104
|
+
release: { configOnly: true },
|
|
105
|
+
npm: { configOnly: true },
|
|
106
|
+
npmMatrix: { configOnly: true }
|
|
107
|
+
};
|
|
108
|
+
const root = {
|
|
109
|
+
schema: type(`string`),
|
|
110
|
+
required: false,
|
|
111
|
+
description: `Source Git checkout root (defaults to the current directory).`,
|
|
112
|
+
example: `--root .`,
|
|
113
|
+
completion: { fileSystem: `directories` }
|
|
114
|
+
};
|
|
115
|
+
const plan = {
|
|
116
|
+
schema: type(`string`),
|
|
117
|
+
required: true,
|
|
118
|
+
description: `Prepared plan.json; archives are read from its bundle directory.`,
|
|
119
|
+
example: `--plan .breakage/npm-plan/plan.json`,
|
|
120
|
+
completion: { fileSystem: `files` }
|
|
121
|
+
};
|
|
122
|
+
const npmPlanManual = options(`Audit the peer matrix and prepare a portable archive bundle; print matrix JSON.`, type({
|
|
123
|
+
...hiddenSchema,
|
|
124
|
+
"config?": `string`,
|
|
125
|
+
"root?": `string`,
|
|
126
|
+
"out?": `string`
|
|
100
127
|
}), {
|
|
128
|
+
...hidden,
|
|
129
|
+
root,
|
|
130
|
+
config: {
|
|
131
|
+
schema: type(`string`),
|
|
132
|
+
required: false,
|
|
133
|
+
description: `TypeScript configuration containing npmMatrix.`,
|
|
134
|
+
example: `--config breakage.config.ts`,
|
|
135
|
+
completion: { fileSystem: `files` }
|
|
136
|
+
},
|
|
137
|
+
out: {
|
|
138
|
+
schema: type(`string`),
|
|
139
|
+
required: false,
|
|
140
|
+
description: `Bundle directory (defaults to .breakage/npm-plan).`,
|
|
141
|
+
example: `--out .breakage/peer-bundle`,
|
|
142
|
+
completion: { fileSystem: `directories` }
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
const npmExecuteManual = options(`Execute one planned representative and write its receipt.`, type({
|
|
146
|
+
...hiddenSchema,
|
|
147
|
+
plan: `string`,
|
|
148
|
+
receipt: `string`,
|
|
149
|
+
"root?": `string`
|
|
150
|
+
}), {
|
|
151
|
+
...hidden,
|
|
152
|
+
root,
|
|
153
|
+
plan,
|
|
154
|
+
receipt: {
|
|
155
|
+
schema: type(`string`),
|
|
156
|
+
required: true,
|
|
157
|
+
description: `Output receipt filename.`,
|
|
158
|
+
example: `--receipt .breakage/receipts/environment.json`,
|
|
159
|
+
completion: { fileSystem: `files` }
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
const npmVerifyManual = options(`Verify the complete planned matrix against collected execution receipts.`, type({
|
|
163
|
+
...hiddenSchema,
|
|
164
|
+
plan: `string`,
|
|
165
|
+
receipts: `string`,
|
|
166
|
+
"root?": `string`
|
|
167
|
+
}), {
|
|
168
|
+
...hidden,
|
|
169
|
+
root,
|
|
170
|
+
plan,
|
|
171
|
+
receipts: {
|
|
172
|
+
schema: type(`string`),
|
|
173
|
+
required: true,
|
|
174
|
+
description: `Glob selecting all collected JSON receipts, relative to root.`,
|
|
175
|
+
example: `--receipts '.breakage/receipts/**/*.json'`,
|
|
176
|
+
completion: { fileSystem: `files` }
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
async function runNpmMatrixCli(action, opts, id) {
|
|
180
|
+
try {
|
|
181
|
+
const rootDirectory = path.resolve(opts.root ?? process.cwd());
|
|
182
|
+
if (action === `plan`) {
|
|
183
|
+
const config = await loadConfig(path.resolve(rootDirectory, opts.config ?? defaultConfig(rootDirectory)));
|
|
184
|
+
if (!config.npmMatrix) throw new Error(`Configure npmMatrix.configs and npmMatrix.prepare.`);
|
|
185
|
+
const prepared = await npmPlan(config.npmMatrix, {
|
|
186
|
+
rootDirectory,
|
|
187
|
+
...opts.out ? { bundleDirectory: opts.out } : {}
|
|
188
|
+
});
|
|
189
|
+
process.stdout.write(`${JSON.stringify(npmMatrix(prepared))}\n`);
|
|
190
|
+
return 0;
|
|
191
|
+
}
|
|
192
|
+
const filename = path.resolve(rootDirectory, opts.plan);
|
|
193
|
+
const value = JSON.parse(await readFile(filename, `utf8`));
|
|
194
|
+
const location = {
|
|
195
|
+
rootDirectory,
|
|
196
|
+
bundleDirectory: path.dirname(filename)
|
|
197
|
+
};
|
|
198
|
+
if (action === `execute`) {
|
|
199
|
+
const receipt = await npmExecute(value, id, location);
|
|
200
|
+
await writeMatrixJson(path.resolve(rootDirectory, opts.receipt), receipt);
|
|
201
|
+
if (receipt.report) process.stdout.write(formatNpmReport(receipt.report));
|
|
202
|
+
if (receipt.error) process.stderr.write(`${receipt.error}\n`);
|
|
203
|
+
return receipt.exitCode;
|
|
204
|
+
}
|
|
205
|
+
const receipts = [];
|
|
206
|
+
for await (const filename of glob(opts.receipts, { cwd: rootDirectory })) receipts.push(JSON.parse(await readFile(path.resolve(rootDirectory, filename), `utf8`)));
|
|
207
|
+
const result = await npmVerify(value, receipts, location);
|
|
208
|
+
if (result.errors.length) process.stderr.write(`${result.errors.join(`\n`)}\n`);
|
|
209
|
+
else process.stdout.write(`Verified passing receipts for all ${result.environments} planned environments.\n`);
|
|
210
|
+
return result.exitCode;
|
|
211
|
+
} catch (error) {
|
|
212
|
+
process.stderr.write(`npm matrix setup error: ${errorMessage(error)}\n`);
|
|
213
|
+
return 2;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// src/breakage.x.ts
|
|
217
|
+
const commandOverrides = /* @__PURE__ */ new Set();
|
|
218
|
+
const BREAKAGE_MANUAL = options(`Check for breaking changes in a package.`, configSchema, {
|
|
219
|
+
release: { configOnly: true },
|
|
220
|
+
npm: { configOnly: true },
|
|
221
|
+
npmMatrix: { configOnly: true },
|
|
222
|
+
out: { configOnly: true },
|
|
101
223
|
tagPattern: {
|
|
224
|
+
schema: configFields.tagPattern,
|
|
102
225
|
aliases: [`tag-pattern`],
|
|
103
226
|
completion: { repeatable: false },
|
|
104
227
|
flag: `g`,
|
|
@@ -107,6 +230,7 @@ const BREAKAGE_MANUAL = options(`Check for breaking changes in a package.`, type
|
|
|
107
230
|
example: `--tagPattern="my-library"`
|
|
108
231
|
},
|
|
109
232
|
baselineFile: {
|
|
233
|
+
schema: configFields.baselineFile,
|
|
110
234
|
aliases: [`baseline-file`],
|
|
111
235
|
completion: {
|
|
112
236
|
repeatable: false,
|
|
@@ -117,30 +241,41 @@ const BREAKAGE_MANUAL = options(`Check for breaking changes in a package.`, type
|
|
|
117
241
|
example: `--baseline-file=.breakage/baseline.json`
|
|
118
242
|
},
|
|
119
243
|
testPattern: {
|
|
244
|
+
schema: configFields.testPattern,
|
|
120
245
|
aliases: [`test-pattern`, `pattern`],
|
|
121
246
|
completion: { repeatable: false },
|
|
122
247
|
flag: `p`,
|
|
123
|
-
required:
|
|
248
|
+
required: false,
|
|
124
249
|
description: `The pattern to match test files that test the public API of the library.`,
|
|
125
250
|
example: `--pattern="*__public.test.ts"`
|
|
126
251
|
},
|
|
127
252
|
testCommand: {
|
|
253
|
+
parse: (value) => {
|
|
254
|
+
commandOverrides.add(`testCommand`);
|
|
255
|
+
return value;
|
|
256
|
+
},
|
|
257
|
+
schema: configFields.testCommand,
|
|
128
258
|
aliases: [`test-command`],
|
|
129
259
|
completion: { repeatable: false },
|
|
130
260
|
flag: `t`,
|
|
131
|
-
required:
|
|
261
|
+
required: false,
|
|
132
262
|
description: `Complete bash command that runs the tests for the library's public API.`,
|
|
133
263
|
example: `--testCommand="npm run test"`
|
|
134
264
|
},
|
|
135
|
-
|
|
136
|
-
|
|
265
|
+
test: {
|
|
266
|
+
parse: (value) => {
|
|
267
|
+
commandOverrides.add(`test`);
|
|
268
|
+
return value;
|
|
269
|
+
},
|
|
270
|
+
schema: configFields.test,
|
|
137
271
|
completion: { repeatable: false },
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
example: `--certifyCommand=\tsx scripts/certify-major-version-bump.node`
|
|
272
|
+
required: false,
|
|
273
|
+
description: `Shell command running the restored public contracts.`,
|
|
274
|
+
example: `--test="npm run test:public"`
|
|
142
275
|
},
|
|
143
276
|
baseDirname: {
|
|
277
|
+
parse: (value) => path.resolve(value),
|
|
278
|
+
schema: configFields.baseDirname,
|
|
144
279
|
aliases: [`base-dir`, `base-dirname`],
|
|
145
280
|
completion: {
|
|
146
281
|
repeatable: false,
|
|
@@ -152,6 +287,7 @@ const BREAKAGE_MANUAL = options(`Check for breaking changes in a package.`, type
|
|
|
152
287
|
example: `--baseDirname=./packages/my-package`
|
|
153
288
|
},
|
|
154
289
|
verbose: {
|
|
290
|
+
schema: configFields.verbose,
|
|
155
291
|
completion: { repeatable: false },
|
|
156
292
|
flag: `v`,
|
|
157
293
|
required: false,
|
|
@@ -160,16 +296,7 @@ const BREAKAGE_MANUAL = options(`Check for breaking changes in a package.`, type
|
|
|
160
296
|
parse: parseBooleanOption
|
|
161
297
|
}
|
|
162
298
|
});
|
|
163
|
-
const PRELUDE_MANUAL = options(`Resolve and fetch the release baseline for a cacheable compatibility check.`,
|
|
164
|
-
"tagPattern?": `string`,
|
|
165
|
-
"baseDirname?": `string`,
|
|
166
|
-
"out?": `string`,
|
|
167
|
-
"testPattern?": `string`,
|
|
168
|
-
"testCommand?": `string`,
|
|
169
|
-
"certifyCommand?": `string`,
|
|
170
|
-
"baselineFile?": `string`,
|
|
171
|
-
"verbose?": `boolean`
|
|
172
|
-
}), {
|
|
299
|
+
const PRELUDE_MANUAL = options(`Resolve and fetch the release baseline for a cacheable compatibility check.`, configSchema, {
|
|
173
300
|
...BREAKAGE_MANUAL.optionConfigs,
|
|
174
301
|
testPattern: {
|
|
175
302
|
...BREAKAGE_MANUAL.optionConfigs.testPattern,
|
|
@@ -179,11 +306,8 @@ const PRELUDE_MANUAL = options(`Resolve and fetch the release baseline for a cac
|
|
|
179
306
|
...BREAKAGE_MANUAL.optionConfigs.testCommand,
|
|
180
307
|
required: false
|
|
181
308
|
},
|
|
182
|
-
certifyCommand: {
|
|
183
|
-
...BREAKAGE_MANUAL.optionConfigs.certifyCommand,
|
|
184
|
-
required: false
|
|
185
|
-
},
|
|
186
309
|
out: {
|
|
310
|
+
schema: configFields.out,
|
|
187
311
|
completion: {
|
|
188
312
|
repeatable: false,
|
|
189
313
|
fileSystem: `files`
|
|
@@ -193,25 +317,23 @@ const PRELUDE_MANUAL = options(`Resolve and fetch the release baseline for a cac
|
|
|
193
317
|
example: `--out=.breakage/baseline.json`
|
|
194
318
|
}
|
|
195
319
|
});
|
|
196
|
-
|
|
197
|
-
aliases: [`out-dir`],
|
|
198
|
-
completion: {
|
|
199
|
-
repeatable: false,
|
|
200
|
-
fileSystem: `directories`
|
|
201
|
-
},
|
|
202
|
-
flag: `o`,
|
|
203
|
-
required: false,
|
|
204
|
-
description: `Directory to write the schema to.`,
|
|
205
|
-
example: `--outdir=./dist`
|
|
206
|
-
} });
|
|
320
|
+
let loadedConfigPath;
|
|
207
321
|
const parse = cli({
|
|
208
322
|
cliName: `breakage`,
|
|
323
|
+
discoverConfigPath: (segments) => {
|
|
324
|
+
if (segments[0] === `help` || segments[0] === `npm`) return void 0;
|
|
325
|
+
const explicit = segments[0] === `prelude` ? segments[1] : segments[0];
|
|
326
|
+
loadedConfigPath = configPath(explicit ?? defaultConfig(process.cwd()), explicit !== void 0);
|
|
327
|
+
return loadedConfigPath;
|
|
328
|
+
},
|
|
209
329
|
routes: optional({
|
|
210
330
|
help: null,
|
|
211
|
-
schema: null,
|
|
212
331
|
npm: optional({
|
|
213
332
|
help: null,
|
|
214
333
|
check: null,
|
|
334
|
+
plan: null,
|
|
335
|
+
execute: required({ $id: null }),
|
|
336
|
+
verify: null,
|
|
215
337
|
test: optional({ $peer: required({ $range: null }) })
|
|
216
338
|
}),
|
|
217
339
|
prelude: optional({ $configPath: null }),
|
|
@@ -221,10 +343,12 @@ const parse = cli({
|
|
|
221
343
|
"": BREAKAGE_MANUAL,
|
|
222
344
|
$configPath: BREAKAGE_MANUAL,
|
|
223
345
|
help: noOptions(`Show usage.`),
|
|
224
|
-
schema: SCHEMA_MANUAL,
|
|
225
346
|
npm: noOptions(`Show npm compatibility commands.`),
|
|
226
347
|
"npm/help": noOptions(`Show npm compatibility commands.`),
|
|
227
348
|
"npm/check": npmCheckManual,
|
|
349
|
+
"npm/plan": npmPlanManual,
|
|
350
|
+
"npm/execute/$id": npmExecuteManual,
|
|
351
|
+
"npm/verify": npmVerifyManual,
|
|
228
352
|
"npm/test": npmTestManual,
|
|
229
353
|
"npm/test/$peer/$range": npmTestManual,
|
|
230
354
|
prelude: PRELUDE_MANUAL,
|
|
@@ -233,10 +357,6 @@ const parse = cli({
|
|
|
233
357
|
positionalCompletions: {
|
|
234
358
|
$configPath: { fileSystem: `files` },
|
|
235
359
|
"prelude/$configPath": { fileSystem: `files` }
|
|
236
|
-
},
|
|
237
|
-
discoverConfigPath: (args) => {
|
|
238
|
-
if (args[0] === `help` || args[0] === `schema` || args[0] === `npm`) return;
|
|
239
|
-
return (args[0] === `prelude` ? args[1] : args[0]) ?? defaultConfig(process.cwd());
|
|
240
360
|
}
|
|
241
361
|
}, {
|
|
242
362
|
info: (message, ...data) => logger.info(`breakage`, message, data),
|
|
@@ -244,9 +364,10 @@ const parse = cli({
|
|
|
244
364
|
});
|
|
245
365
|
const completion = await completionResponse(parse.definition, process.argv);
|
|
246
366
|
if (completion !== void 0) process.stdout.write(completion);
|
|
247
|
-
else {
|
|
248
|
-
const { inputs, warnings
|
|
367
|
+
else try {
|
|
368
|
+
const { inputs, warnings } = await parse.async(process.argv);
|
|
249
369
|
logWarnings(warnings);
|
|
370
|
+
if (process.argv.slice(2).some((arg) => /^(?:--certifyCommand|--certify-command|-c)(?:=|$)/.test(arg))) throw new Error(`certifyCommand was removed. Configure release.resolveDelta and release.policy instead.`);
|
|
250
371
|
switch (inputs.case) {
|
|
251
372
|
case `npm`:
|
|
252
373
|
case `npm/help`:
|
|
@@ -256,42 +377,56 @@ else {
|
|
|
256
377
|
case `npm/check`:
|
|
257
378
|
process.exitCode = await runNpmCli(`check`, inputs.opts);
|
|
258
379
|
break;
|
|
380
|
+
case `npm/plan`:
|
|
381
|
+
process.exitCode = await runNpmMatrixCli(`plan`, inputs.opts);
|
|
382
|
+
break;
|
|
383
|
+
case `npm/execute/$id`:
|
|
384
|
+
process.exitCode = await runNpmMatrixCli(`execute`, inputs.opts, inputs.params.id);
|
|
385
|
+
break;
|
|
386
|
+
case `npm/verify`:
|
|
387
|
+
process.exitCode = await runNpmMatrixCli(`verify`, inputs.opts);
|
|
388
|
+
break;
|
|
259
389
|
case `npm/test`:
|
|
260
390
|
process.exitCode = await runNpmCli(`test`, inputs.opts);
|
|
261
391
|
break;
|
|
262
392
|
case `npm/test/$peer/$range`:
|
|
263
393
|
process.exitCode = await runNpmCli(`test`, inputs.opts, inputs.params);
|
|
264
394
|
break;
|
|
265
|
-
case `schema`:
|
|
266
|
-
{
|
|
267
|
-
const { outdir } = inputs.opts;
|
|
268
|
-
writeJsonSchema(outdir ?? `.`);
|
|
269
|
-
process.stdout.write(`📝 Wrote json.schema.`);
|
|
270
|
-
}
|
|
271
|
-
break;
|
|
272
395
|
case `prelude`:
|
|
273
396
|
case `prelude/$configPath`: {
|
|
397
|
+
const config = resolveConfig(inputs.opts, loadedConfigPath);
|
|
274
398
|
const baseline = await breakagePrelude({
|
|
275
|
-
...
|
|
276
|
-
out:
|
|
399
|
+
...config,
|
|
400
|
+
out: config.out ?? `.breakage/baseline.json`
|
|
277
401
|
});
|
|
278
402
|
process.stdout.write(`Pinned ${baseline.ref} at ${baseline.commit}.\n`);
|
|
279
403
|
break;
|
|
280
404
|
}
|
|
281
405
|
case ``:
|
|
282
406
|
case `$configPath`: {
|
|
283
|
-
const
|
|
407
|
+
const merged = resolveConfig(inputs.opts, loadedConfigPath);
|
|
408
|
+
if (commandOverrides.has(`testCommand`) && !commandOverrides.has(`test`)) delete merged.test;
|
|
409
|
+
if (commandOverrides.has(`test`) && !commandOverrides.has(`testCommand`)) delete merged.testCommand;
|
|
410
|
+
if (!merged.testPattern) throw new Error(`required arguments were not provided: testPattern.`);
|
|
411
|
+
const { returnValue } = await encapsulate(() => breakage({
|
|
412
|
+
...merged,
|
|
413
|
+
testPattern: merged.testPattern
|
|
414
|
+
}), {
|
|
284
415
|
console: true,
|
|
285
416
|
stdout: true
|
|
286
417
|
});
|
|
418
|
+
if (`release` in returnValue && returnValue.release) {
|
|
419
|
+
const { previousVersion, version, delta, breaking } = returnValue.release;
|
|
420
|
+
process.stdout.write(`Release: ${previousVersion} → ${version} (${delta}; ${breaking ? `breaking` : `compatible`}).\n`);
|
|
421
|
+
}
|
|
287
422
|
if (`testResult` in returnValue && returnValue.breakingChangesFound) process.stdout.write(returnValue.testResult);
|
|
288
423
|
if (`breakingChangesFound` in returnValue) {
|
|
289
424
|
if (returnValue.breakingChangesFound) {
|
|
290
|
-
if (returnValue.
|
|
291
|
-
process.stdout.write(`👷 Breaking changes
|
|
425
|
+
if (returnValue.release?.breaking) {
|
|
426
|
+
process.stdout.write(`👷 Breaking changes are covered by the breaking release.`);
|
|
292
427
|
process.exit(0);
|
|
293
428
|
} else {
|
|
294
|
-
process.stdout.write(`❌ Breaking changes
|
|
429
|
+
process.stdout.write(`❌ Breaking changes require a breaking release.`);
|
|
295
430
|
process.exit(1);
|
|
296
431
|
}
|
|
297
432
|
} else {
|
|
@@ -304,8 +439,10 @@ else {
|
|
|
304
439
|
}
|
|
305
440
|
}
|
|
306
441
|
}
|
|
442
|
+
} catch (error) {
|
|
443
|
+
process.stderr.write(`Breakage setup error: ${errorMessage(error)}\n`);
|
|
444
|
+
process.exitCode = 2;
|
|
307
445
|
}
|
|
308
|
-
//#endregion
|
|
309
446
|
export {};
|
|
310
447
|
|
|
311
448
|
//# sourceMappingURL=breakage.x.js.map
|
package/dist/breakage.x.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"breakage.x.js","names":[],"sources":["../src/npm/cli.ts","../src/breakage.x.ts"],"sourcesContent":["import { existsSync } from \"node:fs\"\nimport { readFile } from \"node:fs/promises\"\nimport path from \"node:path\"\nimport { pathToFileURL } from \"node:url\"\n\nimport { type } from \"arktype\"\nimport type { OptionsGroup } from \"comline\"\nimport { options, parseBooleanOption } from \"comline\"\n\nimport { formatNpmReport, npmCheck, npmTest } from \"./check.ts\"\nimport { errorMessage } from \"./command.ts\"\nimport { validateConfig } from \"./config.ts\"\nimport { record } from \"./manifest.ts\"\nimport type { NpmTestSelection } from \"./types.ts\"\n\ntype CommonOptions = { config?: string | undefined; json?: boolean | undefined }\ntype CheckOptions = CommonOptions & { coverageOnly?: boolean | undefined }\ntype TestOptions = CommonOptions & { representative?: string | undefined }\n\nconst common = {\n\tconfig: {\n\t\trequired: false,\n\t\tdescription: `Configuration file (defaults to breakage.config.ts, then .json).`,\n\t\texample: `--config ./breakage.config.ts`,\n\t\tcompletion: { fileSystem: `files` as const, repeatable: false },\n\t},\n\tjson: {\n\t\trequired: false,\n\t\tdescription: `Emit the structured result.`,\n\t\texample: `--json`,\n\t\tparse: parseBooleanOption,\n\t},\n}\n\nexport const npmCheckManual: OptionsGroup<CheckOptions> = options(\n\t`Check npm peer compatibility and changes in declared support.`,\n\ttype({ \"config?\": `string`, \"json?\": `boolean`, \"coverageOnly?\": `boolean` }),\n\t{\n\t\t...common,\n\t\tcoverageOnly: {\n\t\t\taliases: [`coverage-only`],\n\t\t\trequired: false,\n\t\t\tdescription: `Audit coverage and support changes without executing assertions.`,\n\t\t\texample: `--coverage-only`,\n\t\t\tparse: parseBooleanOption,\n\t\t},\n\t},\n)\n\nexport const npmTestManual: OptionsGroup<TestOptions> = options(\n\t`Run current contracts in matching complete peer environments.`,\n\ttype({\n\t\t\"config?\": `string`,\n\t\t\"json?\": `boolean`,\n\t\t\"representative?\": `string`,\n\t}),\n\t{\n\t\t...common,\n\t\trepresentative: {\n\t\t\trequired: false,\n\t\t\tdescription: `Select an exact configured representative path relative to the package.`,\n\t\t\texample: `--representative peer-environments/react-19`,\n\t\t\tcompletion: { fileSystem: `directories`, repeatable: false },\n\t\t},\n\t},\n)\n\nexport function defaultConfig(directory: string): string {\n\treturn path.join(\n\t\tdirectory,\n\t\texistsSync(path.join(directory, `breakage.config.ts`))\n\t\t\t? `breakage.config.ts`\n\t\t\t: `breakage.config.json`,\n\t)\n}\n\nexport async function runNpmCli(\n\taction: `check` | `test`,\n\topts: CheckOptions & TestOptions,\n\tpeerSelection?: { peer: string; range: string },\n): Promise<number> {\n\ttry {\n\t\tconst filename = path.resolve(opts.config ?? defaultConfig(process.cwd()))\n\t\tconst loaded: unknown = filename.endsWith(`.json`)\n\t\t\t? JSON.parse(await readFile(filename, `utf8`))\n\t\t\t: ((await import(pathToFileURL(filename).href)) as { default: unknown })\n\t\t\t\t\t.default\n\t\tconst config = record(loaded) ? loaded.npm : undefined\n\t\tvalidateConfig(config)\n\t\tlet selection: NpmTestSelection | undefined\n\t\tif (action === `test`) {\n\t\t\tif (peerSelection && opts.representative)\n\t\t\t\tthrow new Error(`Choose a peer range or a representative, not both.`)\n\t\t\tselection =\n\t\t\t\tpeerSelection ??\n\t\t\t\t(opts.representative\n\t\t\t\t\t? { representative: opts.representative }\n\t\t\t\t\t: undefined)\n\t\t\tif (!selection)\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Use npm test <peer> <range> or npm test --representative <path>.`,\n\t\t\t\t)\n\t\t}\n\t\tconst options = {\n\t\t\tbaseDirectory: path.dirname(filename),\n\t\t\tcoverageOnly: opts.coverageOnly ?? false,\n\t\t}\n\t\tconst report = selection\n\t\t\t? await npmTest(config, selection, options)\n\t\t\t: await npmCheck(config, options)\n\t\tprocess.stdout.write(\n\t\t\topts.json\n\t\t\t\t? `${JSON.stringify(report, null, 2)}\\n`\n\t\t\t\t: formatNpmReport(report),\n\t\t)\n\t\treturn report.exitCode\n\t} catch (error) {\n\t\tconst message = errorMessage(error)\n\t\tprocess.stdout.write(\n\t\t\topts.json\n\t\t\t\t? `${JSON.stringify({ exitCode: 2, errors: [message] })}\\n`\n\t\t\t\t: `npm setup error: ${message}\\n`,\n\t\t)\n\t\treturn 2\n\t}\n}\n","#!/usr/bin/env node\n\nimport { inspect } from \"node:util\"\n\nimport { type } from \"arktype\"\nimport type { OptionsGroup } from \"comline\"\nimport {\n\tcli,\n\tcompletionResponse,\n\tencapsulate,\n\thelp,\n\tlogWarnings,\n\tnoOptions,\n\toptional,\n\toptions,\n\tparseBooleanOption,\n\trequired,\n} from \"comline\"\nimport logger from \"takua\"\n\nimport type { BreakageOptions } from \"./breakage.ts\"\nimport { breakage, breakagePrelude } from \"./breakage.ts\"\nimport {\n\tdefaultConfig,\n\tnpmCheckManual,\n\tnpmTestManual,\n\trunNpmCli,\n} from \"./npm/cli.ts\"\n\nconst BREAKAGE_MANUAL = options(\n\t`Check for breaking changes in a package.`,\n\ttype({\n\t\t\"tagPattern?\": `string`,\n\t\t\"baselineFile?\": `string`,\n\t\ttestPattern: `string`,\n\t\ttestCommand: `string`,\n\t\tcertifyCommand: `string`,\n\t\t\"baseDirname?\": `string`,\n\t\t\"verbose?\": `boolean`,\n\t}),\n\t{\n\t\ttagPattern: {\n\t\t\taliases: [`tag-pattern`],\n\t\t\tcompletion: { repeatable: false },\n\t\t\tflag: `g`,\n\t\t\trequired: false,\n\t\t\tdescription: `RegExp which, if found matched to a git tag, will be considered a release tag for your library.`,\n\t\t\texample: `--tagPattern=\"my-library\"`,\n\t\t},\n\t\tbaselineFile: {\n\t\t\taliases: [`baseline-file`],\n\t\t\tcompletion: { repeatable: false, fileSystem: `files` },\n\t\t\trequired: false,\n\t\t\tdescription: `Use the exact locally fetched commit from a prelude snapshot instead of discovering remote tags.`,\n\t\t\texample: `--baseline-file=.breakage/baseline.json`,\n\t\t},\n\t\ttestPattern: {\n\t\t\taliases: [`test-pattern`, `pattern`],\n\t\t\tcompletion: { repeatable: false },\n\t\t\tflag: `p`,\n\t\t\trequired: true,\n\t\t\tdescription: `The pattern to match test files that test the public API of the library.`,\n\t\t\texample: `--pattern=\"*__public.test.ts\"`,\n\t\t},\n\t\ttestCommand: {\n\t\t\taliases: [`test-command`],\n\t\t\tcompletion: { repeatable: false },\n\t\t\tflag: `t`,\n\t\t\trequired: true,\n\t\t\tdescription: `Complete bash command that runs the tests for the library's public API.`,\n\t\t\texample: `--testCommand=\"npm run test\"`,\n\t\t},\n\t\tcertifyCommand: {\n\t\t\taliases: [`certify-command`],\n\t\t\tcompletion: { repeatable: false },\n\t\t\tflag: `c`,\n\t\t\trequired: true,\n\t\t\tdescription: `Complete bash command that determines whether a major version bump for your package is indicated in the workspace. Exit code 0 indicates that a major version bump is indicated, and exit code 1 indicates that no major version bump is indicated.`,\n\t\t\texample: `--certifyCommand=\\tsx scripts/certify-major-version-bump.node`,\n\t\t},\n\t\tbaseDirname: {\n\t\t\taliases: [`base-dir`, `base-dirname`],\n\t\t\tcompletion: { repeatable: false, fileSystem: `directories` },\n\t\t\tflag: `d`,\n\t\t\trequired: false,\n\t\t\tdescription: `The base directory to run the command from.`,\n\t\t\texample: `--baseDirname=./packages/my-package`,\n\t\t},\n\t\tverbose: {\n\t\t\tcompletion: { repeatable: false },\n\t\t\tflag: `v`,\n\t\t\trequired: false,\n\t\t\tdescription: `Prints out more information about the process.`,\n\t\t\texample: `--verbose`,\n\t\t\tparse: parseBooleanOption,\n\t\t},\n\t},\n) satisfies OptionsGroup<BreakageOptions>\n\nconst PRELUDE_MANUAL = options(\n\t`Resolve and fetch the release baseline for a cacheable compatibility check.`,\n\ttype({\n\t\t\"tagPattern?\": `string`,\n\t\t\"baseDirname?\": `string`,\n\t\t\"out?\": `string`,\n\t\t\"testPattern?\": `string`,\n\t\t\"testCommand?\": `string`,\n\t\t\"certifyCommand?\": `string`,\n\t\t\"baselineFile?\": `string`,\n\t\t\"verbose?\": `boolean`,\n\t}),\n\t{\n\t\t...BREAKAGE_MANUAL.optionConfigs,\n\t\ttestPattern: {\n\t\t\t...BREAKAGE_MANUAL.optionConfigs.testPattern,\n\t\t\trequired: false,\n\t\t},\n\t\ttestCommand: {\n\t\t\t...BREAKAGE_MANUAL.optionConfigs.testCommand,\n\t\t\trequired: false,\n\t\t},\n\t\tcertifyCommand: {\n\t\t\t...BREAKAGE_MANUAL.optionConfigs.certifyCommand,\n\t\t\trequired: false,\n\t\t},\n\t\tout: {\n\t\t\tcompletion: { repeatable: false, fileSystem: `files` },\n\t\t\trequired: false,\n\t\t\tdescription: `Gitignored snapshot path relative to the base directory (default: .breakage/baseline.json).`,\n\t\t\texample: `--out=.breakage/baseline.json`,\n\t\t},\n\t},\n)\n\nconst SCHEMA_MANUAL = options(\n\t`Create a copy of the schema for configuring breakage.`,\n\ttype({ \"outdir?\": `string` }),\n\t{\n\t\toutdir: {\n\t\t\taliases: [`out-dir`],\n\t\t\tcompletion: { repeatable: false, fileSystem: `directories` },\n\t\t\tflag: `o`,\n\t\t\trequired: false,\n\t\t\tdescription: `Directory to write the schema to.`,\n\t\t\texample: `--outdir=./dist`,\n\t\t},\n\t},\n)\n\nconst parse = cli(\n\t{\n\t\tcliName: `breakage`,\n\t\troutes: optional({\n\t\t\thelp: null,\n\t\t\tschema: null,\n\t\t\tnpm: optional({\n\t\t\t\thelp: null,\n\t\t\t\tcheck: null,\n\t\t\t\ttest: optional({ $peer: required({ $range: null }) }),\n\t\t\t}),\n\t\t\tprelude: optional({ $configPath: null }),\n\t\t\t$configPath: null,\n\t\t}),\n\t\trouteOptions: {\n\t\t\t\"\": BREAKAGE_MANUAL,\n\t\t\t$configPath: BREAKAGE_MANUAL,\n\t\t\thelp: noOptions(`Show usage.`),\n\t\t\tschema: SCHEMA_MANUAL,\n\t\t\tnpm: noOptions(`Show npm compatibility commands.`),\n\t\t\t\"npm/help\": noOptions(`Show npm compatibility commands.`),\n\t\t\t\"npm/check\": npmCheckManual,\n\t\t\t\"npm/test\": npmTestManual,\n\t\t\t\"npm/test/$peer/$range\": npmTestManual,\n\t\t\tprelude: PRELUDE_MANUAL,\n\t\t\t\"prelude/$configPath\": PRELUDE_MANUAL,\n\t\t},\n\t\tpositionalCompletions: {\n\t\t\t$configPath: { fileSystem: `files` },\n\t\t\t\"prelude/$configPath\": { fileSystem: `files` },\n\t\t},\n\t\tdiscoverConfigPath: (args: readonly string[]) => {\n\t\t\tif (args[0] === `help` || args[0] === `schema` || args[0] === `npm`) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst configPath =\n\t\t\t\t(args[0] === `prelude` ? args[1] : args[0]) ??\n\t\t\t\tdefaultConfig(process.cwd())\n\t\t\treturn configPath\n\t\t},\n\t},\n\t{\n\t\tinfo: (message, ...data) => logger.info(`breakage`, message, data),\n\t\terror: (message, ...data) => logger.error(`breakage`, message, data),\n\t},\n)\n\nconst completion = await completionResponse(parse.definition, process.argv)\nif (completion !== undefined) {\n\tprocess.stdout.write(completion)\n} else {\n\tconst { inputs, warnings, writeJsonSchema } = parse(process.argv)\n\tlogWarnings(warnings)\n\n\tswitch (inputs.case) {\n\t\tcase `npm`:\n\t\tcase `npm/help`:\n\t\tcase `help`:\n\t\t\tconsole.log(help(parse.definition))\n\t\t\tbreak\n\t\tcase `npm/check`:\n\t\t\tprocess.exitCode = await runNpmCli(`check`, inputs.opts)\n\t\t\tbreak\n\t\tcase `npm/test`:\n\t\t\tprocess.exitCode = await runNpmCli(`test`, inputs.opts)\n\t\t\tbreak\n\t\tcase `npm/test/$peer/$range`:\n\t\t\tprocess.exitCode = await runNpmCli(`test`, inputs.opts, inputs.params)\n\t\t\tbreak\n\t\tcase `schema`:\n\t\t\t{\n\t\t\t\tconst { outdir } = inputs.opts\n\t\t\t\twriteJsonSchema(outdir ?? `.`)\n\t\t\t\tprocess.stdout.write(`📝 Wrote json.schema.`)\n\t\t\t}\n\t\t\tbreak\n\t\tcase `prelude`:\n\t\tcase `prelude/$configPath`: {\n\t\t\tconst baseline = await breakagePrelude({\n\t\t\t\t...inputs.opts,\n\t\t\t\tout: inputs.opts.out ?? `.breakage/baseline.json`,\n\t\t\t})\n\t\t\tprocess.stdout.write(`Pinned ${baseline.ref} at ${baseline.commit}.\\n`)\n\t\t\tbreak\n\t\t}\n\t\tcase ``:\n\t\tcase `$configPath`: {\n\t\t\tconst { returnValue } = await encapsulate(() => breakage(inputs.opts), {\n\t\t\t\tconsole: true,\n\t\t\t\tstdout: true,\n\t\t\t})\n\t\t\tif (`testResult` in returnValue && returnValue.breakingChangesFound) {\n\t\t\t\tprocess.stdout.write(returnValue.testResult)\n\t\t\t}\n\t\t\tif (`breakingChangesFound` in returnValue) {\n\t\t\t\tif (returnValue.breakingChangesFound) {\n\t\t\t\t\tif (returnValue.breakingChangesCertified) {\n\t\t\t\t\t\tprocess.stdout.write(\n\t\t\t\t\t\t\t`👷 Breaking changes were found and certified.`,\n\t\t\t\t\t\t)\n\t\t\t\t\t\tprocess.exit(0)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tprocess.stdout.write(\n\t\t\t\t\t\t\t`❌ Breaking changes were found, but not certified.`,\n\t\t\t\t\t\t)\n\t\t\t\t\t\tprocess.exit(1)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tprocess.stdout.write(`✅ No breaking changes were found.`)\n\t\t\t\t\tprocess.exit(0)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tprocess.stdout.write(\n\t\t\t\t\t`💥 Breakage failed to determine breaking changes.` +\n\t\t\t\t\t\t`\\n` +\n\t\t\t\t\t\tinspect(returnValue),\n\t\t\t\t)\n\t\t\t\tprocess.exit(2)\n\t\t\t}\n\t\t}\n\t}\n}\n"],"mappings":";;;;;;;;;;;AAmBA,MAAM,SAAS;CACd,QAAQ;EACP,UAAU;EACV,aAAa;EACb,SAAS;EACT,YAAY;GAAE,YAAY;GAAkB,YAAY;EAAM;CAC/D;CACA,MAAM;EACL,UAAU;EACV,aAAa;EACb,SAAS;EACT,OAAO;CACR;AACD;AAEA,MAAa,iBAA6C,QACzD,iEACA,KAAK;CAAE,WAAW;CAAU,SAAS;CAAW,iBAAiB;AAAU,CAAC,GAC5E;CACC,GAAG;CACH,cAAc;EACb,SAAS,CAAC,eAAe;EACzB,UAAU;EACV,aAAa;EACb,SAAS;EACT,OAAO;CACR;AACD,CACD;AAEA,MAAa,gBAA2C,QACvD,iEACA,KAAK;CACJ,WAAW;CACX,SAAS;CACT,mBAAmB;AACpB,CAAC,GACD;CACC,GAAG;CACH,gBAAgB;EACf,UAAU;EACV,aAAa;EACb,SAAS;EACT,YAAY;GAAE,YAAY;GAAe,YAAY;EAAM;CAC5D;AACD,CACD;AAEA,SAAgB,cAAc,WAA2B;CACxD,OAAO,KAAK,KACX,WACA,WAAW,KAAK,KAAK,WAAW,oBAAoB,CAAC,IAClD,uBACA,sBACJ;AACD;AAEA,eAAsB,UACrB,QACA,MACA,eACkB;CAClB,IAAI;EACH,MAAM,WAAW,KAAK,QAAQ,KAAK,UAAU,cAAc,QAAQ,IAAI,CAAC,CAAC;EACzE,MAAM,SAAkB,SAAS,SAAS,OAAO,IAC9C,KAAK,MAAM,MAAM,SAAS,UAAU,MAAM,CAAC,KACzC,MAAM,OAAO,cAAc,QAAQ,CAAC,CAAC,MAAA,CACtC;EACJ,MAAM,SAAS,OAAO,MAAM,IAAI,OAAO,MAAM,KAAA;EAC7C,eAAe,MAAM;EACrB,IAAI;EACJ,IAAI,WAAW,QAAQ;GACtB,IAAI,iBAAiB,KAAK,gBACzB,MAAM,IAAI,MAAM,oDAAoD;GACrE,YACC,kBACC,KAAK,iBACH,EAAE,gBAAgB,KAAK,eAAe,IACtC,KAAA;GACJ,IAAI,CAAC,WACJ,MAAM,IAAI,MACT,kEACD;EACF;EACA,MAAM,UAAU;GACf,eAAe,KAAK,QAAQ,QAAQ;GACpC,cAAc,KAAK,gBAAgB;EACpC;EACA,MAAM,SAAS,YACZ,MAAM,QAAQ,QAAQ,WAAW,OAAO,IACxC,MAAM,SAAS,QAAQ,OAAO;EACjC,QAAQ,OAAO,MACd,KAAK,OACF,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,MACnC,gBAAgB,MAAM,CAC1B;EACA,OAAO,OAAO;CACf,SAAS,OAAO;EACf,MAAM,UAAU,aAAa,KAAK;EAClC,QAAQ,OAAO,MACd,KAAK,OACF,GAAG,KAAK,UAAU;GAAE,UAAU;GAAG,QAAQ,CAAC,OAAO;EAAE,CAAC,EAAE,MACtD,oBAAoB,QAAQ,GAChC;EACA,OAAO;CACR;AACD;;;AChGA,MAAM,kBAAkB,QACvB,4CACA,KAAK;CACJ,eAAe;CACf,iBAAiB;CACjB,aAAa;CACb,aAAa;CACb,gBAAgB;CAChB,gBAAgB;CAChB,YAAY;AACb,CAAC,GACD;CACC,YAAY;EACX,SAAS,CAAC,aAAa;EACvB,YAAY,EAAE,YAAY,MAAM;EAChC,MAAM;EACN,UAAU;EACV,aAAa;EACb,SAAS;CACV;CACA,cAAc;EACb,SAAS,CAAC,eAAe;EACzB,YAAY;GAAE,YAAY;GAAO,YAAY;EAAQ;EACrD,UAAU;EACV,aAAa;EACb,SAAS;CACV;CACA,aAAa;EACZ,SAAS,CAAC,gBAAgB,SAAS;EACnC,YAAY,EAAE,YAAY,MAAM;EAChC,MAAM;EACN,UAAU;EACV,aAAa;EACb,SAAS;CACV;CACA,aAAa;EACZ,SAAS,CAAC,cAAc;EACxB,YAAY,EAAE,YAAY,MAAM;EAChC,MAAM;EACN,UAAU;EACV,aAAa;EACb,SAAS;CACV;CACA,gBAAgB;EACf,SAAS,CAAC,iBAAiB;EAC3B,YAAY,EAAE,YAAY,MAAM;EAChC,MAAM;EACN,UAAU;EACV,aAAa;EACb,SAAS;CACV;CACA,aAAa;EACZ,SAAS,CAAC,YAAY,cAAc;EACpC,YAAY;GAAE,YAAY;GAAO,YAAY;EAAc;EAC3D,MAAM;EACN,UAAU;EACV,aAAa;EACb,SAAS;CACV;CACA,SAAS;EACR,YAAY,EAAE,YAAY,MAAM;EAChC,MAAM;EACN,UAAU;EACV,aAAa;EACb,SAAS;EACT,OAAO;CACR;AACD,CACD;AAEA,MAAM,iBAAiB,QACtB,+EACA,KAAK;CACJ,eAAe;CACf,gBAAgB;CAChB,QAAQ;CACR,gBAAgB;CAChB,gBAAgB;CAChB,mBAAmB;CACnB,iBAAiB;CACjB,YAAY;AACb,CAAC,GACD;CACC,GAAG,gBAAgB;CACnB,aAAa;EACZ,GAAG,gBAAgB,cAAc;EACjC,UAAU;CACX;CACA,aAAa;EACZ,GAAG,gBAAgB,cAAc;EACjC,UAAU;CACX;CACA,gBAAgB;EACf,GAAG,gBAAgB,cAAc;EACjC,UAAU;CACX;CACA,KAAK;EACJ,YAAY;GAAE,YAAY;GAAO,YAAY;EAAQ;EACrD,UAAU;EACV,aAAa;EACb,SAAS;CACV;AACD,CACD;AAEA,MAAM,gBAAgB,QACrB,yDACA,KAAK,EAAE,WAAW,SAAS,CAAC,GAC5B,EACC,QAAQ;CACP,SAAS,CAAC,SAAS;CACnB,YAAY;EAAE,YAAY;EAAO,YAAY;CAAc;CAC3D,MAAM;CACN,UAAU;CACV,aAAa;CACb,SAAS;AACV,EACD,CACD;AAEA,MAAM,QAAQ,IACb;CACC,SAAS;CACT,QAAQ,SAAS;EAChB,MAAM;EACN,QAAQ;EACR,KAAK,SAAS;GACb,MAAM;GACN,OAAO;GACP,MAAM,SAAS,EAAE,OAAO,SAAS,EAAE,QAAQ,KAAK,CAAC,EAAE,CAAC;EACrD,CAAC;EACD,SAAS,SAAS,EAAE,aAAa,KAAK,CAAC;EACvC,aAAa;CACd,CAAC;CACD,cAAc;EACb,IAAI;EACJ,aAAa;EACb,MAAM,UAAU,aAAa;EAC7B,QAAQ;EACR,KAAK,UAAU,kCAAkC;EACjD,YAAY,UAAU,kCAAkC;EACxD,aAAa;EACb,YAAY;EACZ,yBAAyB;EACzB,SAAS;EACT,uBAAuB;CACxB;CACA,uBAAuB;EACtB,aAAa,EAAE,YAAY,QAAQ;EACnC,uBAAuB,EAAE,YAAY,QAAQ;CAC9C;CACA,qBAAqB,SAA4B;EAChD,IAAI,KAAK,OAAO,UAAU,KAAK,OAAO,YAAY,KAAK,OAAO,OAC7D;EAKD,QAFE,KAAK,OAAO,YAAY,KAAK,KAAK,KAAK,OACxC,cAAc,QAAQ,IAAI,CAAC;CAE7B;AACD,GACA;CACC,OAAO,SAAS,GAAG,SAAS,OAAO,KAAK,YAAY,SAAS,IAAI;CACjE,QAAQ,SAAS,GAAG,SAAS,OAAO,MAAM,YAAY,SAAS,IAAI;AACpE,CACD;AAEA,MAAM,aAAa,MAAM,mBAAmB,MAAM,YAAY,QAAQ,IAAI;AAC1E,IAAI,eAAe,KAAA,GAClB,QAAQ,OAAO,MAAM,UAAU;KACzB;CACN,MAAM,EAAE,QAAQ,UAAU,oBAAoB,MAAM,QAAQ,IAAI;CAChE,YAAY,QAAQ;CAEpB,QAAQ,OAAO,MAAf;EACC,KAAK;EACL,KAAK;EACL,KAAK;GACJ,QAAQ,IAAI,KAAK,MAAM,UAAU,CAAC;GAClC;EACD,KAAK;GACJ,QAAQ,WAAW,MAAM,UAAU,SAAS,OAAO,IAAI;GACvD;EACD,KAAK;GACJ,QAAQ,WAAW,MAAM,UAAU,QAAQ,OAAO,IAAI;GACtD;EACD,KAAK;GACJ,QAAQ,WAAW,MAAM,UAAU,QAAQ,OAAO,MAAM,OAAO,MAAM;GACrE;EACD,KAAK;GACJ;IACC,MAAM,EAAE,WAAW,OAAO;IAC1B,gBAAgB,UAAU,GAAG;IAC7B,QAAQ,OAAO,MAAM,uBAAuB;GAC7C;GACA;EACD,KAAK;EACL,KAAK,uBAAuB;GAC3B,MAAM,WAAW,MAAM,gBAAgB;IACtC,GAAG,OAAO;IACV,KAAK,OAAO,KAAK,OAAO;GACzB,CAAC;GACD,QAAQ,OAAO,MAAM,UAAU,SAAS,IAAI,MAAM,SAAS,OAAO,IAAI;GACtE;EACD;EACA,KAAK;EACL,KAAK,eAAe;GACnB,MAAM,EAAE,gBAAgB,MAAM,kBAAkB,SAAS,OAAO,IAAI,GAAG;IACtE,SAAS;IACT,QAAQ;GACT,CAAC;GACD,IAAI,gBAAgB,eAAe,YAAY,sBAC9C,QAAQ,OAAO,MAAM,YAAY,UAAU;GAE5C,IAAI,0BAA0B,aAAa;IAC1C,IAAI,YAAY,sBAAsB;KACrC,IAAI,YAAY,0BAA0B;MACzC,QAAQ,OAAO,MACd,+CACD;MACA,QAAQ,KAAK,CAAC;KACf,OAAO;MACN,QAAQ,OAAO,MACd,mDACD;MACA,QAAQ,KAAK,CAAC;KACf;IACD,OAAO;KACN,QAAQ,OAAO,MAAM,mCAAmC;KACxD,QAAQ,KAAK,CAAC;IACf;GACD,OAAO;IACN,QAAQ,OAAO,MACd,wDAEC,QAAQ,WAAW,CACrB;IACA,QAAQ,KAAK,CAAC;GACf;EACD;CACD;AACD"}
|
|
1
|
+
{"version":3,"file":"breakage.x.js","names":[],"sources":["../src/npm/cli.ts","../src/npm/matrix-cli.ts","../src/breakage.x.ts"],"sourcesContent":["import path from \"node:path\"\n\nimport { type } from \"arktype\"\nimport type { OptionsGroup } from \"comline\"\nimport { options, parseBooleanOption } from \"comline\"\n\nimport { configOptions, defaultConfig, loadConfig } from \"../config.ts\"\n\nimport { formatNpmReport, npmCheck, npmTest } from \"./check.ts\"\nimport { errorMessage } from \"../task.ts\"\nimport { validateConfig } from \"./config.ts\"\nimport type { NpmTestSelection } from \"./types.ts\"\n\ntype CommonOptions = {\n\tconfig?: string | undefined\n\tjson?: boolean | undefined\n\trelease?: import(\"../release.ts\").ReleaseConfig\n\tnpm?: import(\"./types.ts\").NpmConfig\n\tnpmMatrix?: import(\"./matrix-model.ts\").NpmMatrixConfig\n}\ntype CheckOptions = CommonOptions & { coverageOnly?: boolean | undefined }\ntype TestOptions = CommonOptions & { representative?: string | undefined }\n\nconst common = {\n\trelease: configOptions.optionConfigs.release,\n\tnpm: configOptions.optionConfigs.npm,\n\tnpmMatrix: configOptions.optionConfigs.npmMatrix,\n\tconfig: {\n\t\tschema: type(`string`),\n\t\trequired: false,\n\t\tdescription: `Configuration file (defaults to breakage.config.ts).`,\n\t\texample: `--config ./breakage.config.ts`,\n\t\tcompletion: { fileSystem: `files` as const, repeatable: false },\n\t},\n\tjson: {\n\t\tschema: type(`boolean`),\n\t\trequired: false,\n\t\tdescription: `Emit the structured result.`,\n\t\texample: `--json`,\n\t\tparse: parseBooleanOption,\n\t},\n}\n\nexport const npmCheckManual: OptionsGroup<CheckOptions> = options(\n\t`Check npm peer compatibility and changes in declared support.`,\n\ttype({\n\t\t\"config?\": `string`,\n\t\t\"json?\": `boolean`,\n\t\t\"coverageOnly?\": `boolean`,\n\t\t\"release?\": configOptions.optionsSchema.get(`release`),\n\t\t\"npm?\": configOptions.optionsSchema.get(`npm`),\n\t\t\"npmMatrix?\": configOptions.optionsSchema.get(`npmMatrix`),\n\t}),\n\t{\n\t\t...common,\n\t\tcoverageOnly: {\n\t\t\tschema: type(`boolean`),\n\t\t\taliases: [`coverage-only`],\n\t\t\trequired: false,\n\t\t\tdescription: `Audit coverage and support changes without executing assertions.`,\n\t\t\texample: `--coverage-only`,\n\t\t\tparse: parseBooleanOption,\n\t\t},\n\t},\n)\n\nexport const npmTestManual: OptionsGroup<TestOptions> = options(\n\t`Run current contracts in matching complete peer environments.`,\n\ttype({\n\t\t\"config?\": `string`,\n\t\t\"json?\": `boolean`,\n\t\t\"representative?\": `string`,\n\t\t\"release?\": configOptions.optionsSchema.get(`release`),\n\t\t\"npm?\": configOptions.optionsSchema.get(`npm`),\n\t\t\"npmMatrix?\": configOptions.optionsSchema.get(`npmMatrix`),\n\t}),\n\t{\n\t\t...common,\n\t\trepresentative: {\n\t\t\tschema: type(`string`),\n\t\t\trequired: false,\n\t\t\tdescription: `Select an exact configured representative path relative to the package.`,\n\t\t\texample: `--representative peer-environments/react-19`,\n\t\t\tcompletion: { fileSystem: `directories`, repeatable: false },\n\t\t},\n\t},\n)\n\nexport async function runNpmCli(\n\taction: `check` | `test`,\n\topts: CheckOptions & TestOptions,\n\tpeerSelection?: { peer: string; range: string },\n): Promise<number> {\n\ttry {\n\t\tconst filename = path.resolve(opts.config ?? defaultConfig(process.cwd()))\n\t\tconst config = (await loadConfig(filename)).npm\n\t\tvalidateConfig(config)\n\t\tlet selection: NpmTestSelection | undefined\n\t\tif (action === `test`) {\n\t\t\tif (peerSelection && opts.representative)\n\t\t\t\tthrow new Error(`Choose a peer range or a representative, not both.`)\n\t\t\tselection =\n\t\t\t\tpeerSelection ??\n\t\t\t\t(opts.representative\n\t\t\t\t\t? { representative: opts.representative }\n\t\t\t\t\t: undefined)\n\t\t\tif (!selection)\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Use npm test <peer> <range> or npm test --representative <path>.`,\n\t\t\t\t)\n\t\t}\n\t\tconst options = {\n\t\t\tbaseDirectory: path.dirname(filename),\n\t\t\tcoverageOnly: opts.coverageOnly ?? false,\n\t\t}\n\t\tconst report = selection\n\t\t\t? await npmTest(config, selection, options)\n\t\t\t: await npmCheck(config, options)\n\t\tprocess.stdout.write(\n\t\t\topts.json\n\t\t\t\t? `${JSON.stringify(report, null, 2)}\\n`\n\t\t\t\t: formatNpmReport(report),\n\t\t)\n\t\treturn report.exitCode\n\t} catch (error) {\n\t\tconst message = errorMessage(error)\n\t\tprocess.stdout.write(\n\t\t\topts.json\n\t\t\t\t? `${JSON.stringify({ exitCode: 2, errors: [message] })}\\n`\n\t\t\t\t: `npm setup error: ${message}\\n`,\n\t\t)\n\t\treturn 2\n\t}\n}\n","import { glob, readFile } from \"node:fs/promises\"\nimport path from \"node:path\"\nimport { type } from \"arktype\"\nimport { options } from \"comline\"\nimport { configOptions, defaultConfig, loadConfig } from \"../config.ts\"\nimport { errorMessage } from \"../task.ts\"\nimport { formatNpmReport } from \"./check.ts\"\nimport {\n\tnpmPlan,\n\tnpmExecute,\n\tnpmVerify,\n\tnpmMatrix,\n\twriteMatrixJson,\n} from \"./matrix.ts\"\n\nconst hiddenSchema = {\n\t\"release?\": configOptions.optionsSchema.get(`release`),\n\t\"npm?\": configOptions.optionsSchema.get(`npm`),\n\t\"npmMatrix?\": configOptions.optionsSchema.get(`npmMatrix`),\n}\nconst hidden = {\n\trelease: { configOnly: true },\n\tnpm: { configOnly: true },\n\tnpmMatrix: { configOnly: true },\n} as const\nconst root = {\n\tschema: type(`string`),\n\trequired: false,\n\tdescription: `Source Git checkout root (defaults to the current directory).`,\n\texample: `--root .`,\n\tcompletion: { fileSystem: `directories` as const },\n}\nconst plan = {\n\tschema: type(`string`),\n\trequired: true,\n\tdescription: `Prepared plan.json; archives are read from its bundle directory.`,\n\texample: `--plan .breakage/npm-plan/plan.json`,\n\tcompletion: { fileSystem: `files` as const },\n}\n\nexport const npmPlanManual = options(\n\t`Audit the peer matrix and prepare a portable archive bundle; print matrix JSON.`,\n\ttype({\n\t\t...hiddenSchema,\n\t\t\"config?\": `string`,\n\t\t\"root?\": `string`,\n\t\t\"out?\": `string`,\n\t}),\n\t{\n\t\t...hidden,\n\t\troot,\n\t\tconfig: {\n\t\t\tschema: type(`string`),\n\t\t\trequired: false,\n\t\t\tdescription: `TypeScript configuration containing npmMatrix.`,\n\t\t\texample: `--config breakage.config.ts`,\n\t\t\tcompletion: { fileSystem: `files` },\n\t\t},\n\t\tout: {\n\t\t\tschema: type(`string`),\n\t\t\trequired: false,\n\t\t\tdescription: `Bundle directory (defaults to .breakage/npm-plan).`,\n\t\t\texample: `--out .breakage/peer-bundle`,\n\t\t\tcompletion: { fileSystem: `directories` },\n\t\t},\n\t},\n)\nexport const npmExecuteManual = options(\n\t`Execute one planned representative and write its receipt.`,\n\ttype({\n\t\t...hiddenSchema,\n\t\tplan: `string`,\n\t\treceipt: `string`,\n\t\t\"root?\": `string`,\n\t}),\n\t{\n\t\t...hidden,\n\t\troot,\n\t\tplan,\n\t\treceipt: {\n\t\t\tschema: type(`string`),\n\t\t\trequired: true,\n\t\t\tdescription: `Output receipt filename.`,\n\t\t\texample: `--receipt .breakage/receipts/environment.json`,\n\t\t\tcompletion: { fileSystem: `files` },\n\t\t},\n\t},\n)\nexport const npmVerifyManual = options(\n\t`Verify the complete planned matrix against collected execution receipts.`,\n\ttype({\n\t\t...hiddenSchema,\n\t\tplan: `string`,\n\t\treceipts: `string`,\n\t\t\"root?\": `string`,\n\t}),\n\t{\n\t\t...hidden,\n\t\troot,\n\t\tplan,\n\t\treceipts: {\n\t\t\tschema: type(`string`),\n\t\t\trequired: true,\n\t\t\tdescription: `Glob selecting all collected JSON receipts, relative to root.`,\n\t\t\texample: `--receipts '.breakage/receipts/**/*.json'`,\n\t\t\tcompletion: { fileSystem: `files` },\n\t\t},\n\t},\n)\n\nexport async function runNpmMatrixCli(\n\taction: `plan` | `execute` | `verify`,\n\topts: {\n\t\troot?: string\n\t\tconfig?: string\n\t\tout?: string\n\t\tplan?: string\n\t\treceipt?: string\n\t\treceipts?: string\n\t},\n\tid?: string,\n): Promise<number> {\n\ttry {\n\t\tconst rootDirectory = path.resolve(opts.root ?? process.cwd())\n\t\tif (action === `plan`) {\n\t\t\tconst config = await loadConfig(\n\t\t\t\tpath.resolve(\n\t\t\t\t\trootDirectory,\n\t\t\t\t\topts.config ?? defaultConfig(rootDirectory),\n\t\t\t\t),\n\t\t\t)\n\t\t\tif (!config.npmMatrix)\n\t\t\t\tthrow new Error(`Configure npmMatrix.configs and npmMatrix.prepare.`)\n\t\t\tconst prepared = await npmPlan(config.npmMatrix, {\n\t\t\t\trootDirectory,\n\t\t\t\t...(opts.out ? { bundleDirectory: opts.out } : {}),\n\t\t\t})\n\t\t\tprocess.stdout.write(`${JSON.stringify(npmMatrix(prepared))}\\n`)\n\t\t\treturn 0\n\t\t}\n\t\tconst filename = path.resolve(rootDirectory, opts.plan!)\n\t\tconst value: unknown = JSON.parse(await readFile(filename, `utf8`))\n\t\tconst location = { rootDirectory, bundleDirectory: path.dirname(filename) }\n\t\tif (action === `execute`) {\n\t\t\tconst receipt = await npmExecute(value, id!, location)\n\t\t\tawait writeMatrixJson(path.resolve(rootDirectory, opts.receipt!), receipt)\n\t\t\tif (receipt.report) process.stdout.write(formatNpmReport(receipt.report))\n\t\t\tif (receipt.error) process.stderr.write(`${receipt.error}\\n`)\n\t\t\treturn receipt.exitCode\n\t\t}\n\t\tconst receipts: unknown[] = []\n\t\tfor await (const filename of glob(opts.receipts!, { cwd: rootDirectory }))\n\t\t\treceipts.push(\n\t\t\t\tJSON.parse(\n\t\t\t\t\tawait readFile(path.resolve(rootDirectory, filename), `utf8`),\n\t\t\t\t),\n\t\t\t)\n\t\tconst result = await npmVerify(value, receipts, location)\n\t\tif (result.errors.length)\n\t\t\tprocess.stderr.write(`${result.errors.join(`\\n`)}\\n`)\n\t\telse\n\t\t\tprocess.stdout.write(\n\t\t\t\t`Verified passing receipts for all ${result.environments} planned environments.\\n`,\n\t\t\t)\n\t\treturn result.exitCode\n\t} catch (error) {\n\t\tprocess.stderr.write(`npm matrix setup error: ${errorMessage(error)}\\n`)\n\t\treturn 2\n\t}\n}\n","#!/usr/bin/env node\n\nimport path from \"node:path\"\nimport { inspect } from \"node:util\"\n\nimport {\n\tcli,\n\tcompletionResponse,\n\tencapsulate,\n\thelp,\n\tlogWarnings,\n\tnoOptions,\n\toptional,\n\toptions,\n\tparseBooleanOption,\n\trequired,\n} from \"comline\"\nimport logger from \"takua\"\n\nimport {\n\tdefaultConfig,\n\tconfigPath,\n\tresolveConfig,\n\tconfigSchema,\n\tconfigFields,\n} from \"./config.ts\"\nimport { breakage, breakagePrelude } from \"./breakage.ts\"\nimport { errorMessage } from \"./task.ts\"\nimport { npmCheckManual, npmTestManual, runNpmCli } from \"./npm/cli.ts\"\nimport {\n\tnpmPlanManual,\n\tnpmExecuteManual,\n\tnpmVerifyManual,\n\trunNpmMatrixCli,\n} from \"./npm/matrix-cli.ts\"\n\n// Either command spelling can override the other spelling in a config file.\nconst commandOverrides = new Set<`test` | `testCommand`>()\n\nconst BREAKAGE_MANUAL = options(\n\t`Check for breaking changes in a package.`,\n\tconfigSchema,\n\t{\n\t\trelease: { configOnly: true },\n\t\tnpm: { configOnly: true },\n\t\tnpmMatrix: { configOnly: true },\n\t\tout: { configOnly: true },\n\t\ttagPattern: {\n\t\t\tschema: configFields.tagPattern,\n\t\t\taliases: [`tag-pattern`],\n\t\t\tcompletion: { repeatable: false },\n\t\t\tflag: `g`,\n\t\t\trequired: false,\n\t\t\tdescription: `RegExp which, if found matched to a git tag, will be considered a release tag for your library.`,\n\t\t\texample: `--tagPattern=\"my-library\"`,\n\t\t},\n\t\tbaselineFile: {\n\t\t\tschema: configFields.baselineFile,\n\t\t\taliases: [`baseline-file`],\n\t\t\tcompletion: { repeatable: false, fileSystem: `files` },\n\t\t\trequired: false,\n\t\t\tdescription: `Use the exact locally fetched commit from a prelude snapshot instead of discovering remote tags.`,\n\t\t\texample: `--baseline-file=.breakage/baseline.json`,\n\t\t},\n\t\ttestPattern: {\n\t\t\tschema: configFields.testPattern,\n\t\t\taliases: [`test-pattern`, `pattern`],\n\t\t\tcompletion: { repeatable: false },\n\t\t\tflag: `p`,\n\t\t\trequired: false,\n\t\t\tdescription: `The pattern to match test files that test the public API of the library.`,\n\t\t\texample: `--pattern=\"*__public.test.ts\"`,\n\t\t},\n\t\ttestCommand: {\n\t\t\tparse: (value) => {\n\t\t\t\tcommandOverrides.add(`testCommand`)\n\t\t\t\treturn value\n\t\t\t},\n\t\t\tschema: configFields.testCommand,\n\t\t\taliases: [`test-command`],\n\t\t\tcompletion: { repeatable: false },\n\t\t\tflag: `t`,\n\t\t\trequired: false,\n\t\t\tdescription: `Complete bash command that runs the tests for the library's public API.`,\n\t\t\texample: `--testCommand=\"npm run test\"`,\n\t\t},\n\t\ttest: {\n\t\t\tparse: (value) => {\n\t\t\t\tcommandOverrides.add(`test`)\n\t\t\t\treturn value\n\t\t\t},\n\t\t\tschema: configFields.test,\n\t\t\tcompletion: { repeatable: false },\n\t\t\trequired: false,\n\t\t\tdescription: `Shell command running the restored public contracts.`,\n\t\t\texample: `--test=\"npm run test:public\"`,\n\t\t},\n\t\tbaseDirname: {\n\t\t\tparse: (value) => path.resolve(value),\n\t\t\tschema: configFields.baseDirname,\n\t\t\taliases: [`base-dir`, `base-dirname`],\n\t\t\tcompletion: { repeatable: false, fileSystem: `directories` },\n\t\t\tflag: `d`,\n\t\t\trequired: false,\n\t\t\tdescription: `The base directory to run the command from.`,\n\t\t\texample: `--baseDirname=./packages/my-package`,\n\t\t},\n\t\tverbose: {\n\t\t\tschema: configFields.verbose,\n\t\t\tcompletion: { repeatable: false },\n\t\t\tflag: `v`,\n\t\t\trequired: false,\n\t\t\tdescription: `Prints out more information about the process.`,\n\t\t\texample: `--verbose`,\n\t\t\tparse: parseBooleanOption,\n\t\t},\n\t},\n)\n\nconst PRELUDE_MANUAL = options(\n\t`Resolve and fetch the release baseline for a cacheable compatibility check.`,\n\tconfigSchema,\n\t{\n\t\t...BREAKAGE_MANUAL.optionConfigs,\n\t\ttestPattern: {\n\t\t\t...BREAKAGE_MANUAL.optionConfigs.testPattern,\n\t\t\trequired: false,\n\t\t},\n\t\ttestCommand: {\n\t\t\t...BREAKAGE_MANUAL.optionConfigs.testCommand,\n\t\t\trequired: false,\n\t\t},\n\t\tout: {\n\t\t\tschema: configFields.out,\n\t\t\tcompletion: { repeatable: false, fileSystem: `files` },\n\t\t\trequired: false,\n\t\t\tdescription: `Gitignored snapshot path relative to the base directory (default: .breakage/baseline.json).`,\n\t\t\texample: `--out=.breakage/baseline.json`,\n\t\t},\n\t},\n)\n\nlet loadedConfigPath: string | undefined\nconst parse = cli(\n\t{\n\t\tcliName: `breakage`,\n\t\tdiscoverConfigPath: (segments: readonly string[]) => {\n\t\t\tif (segments[0] === `help` || segments[0] === `npm`) return undefined\n\t\t\tconst explicit = segments[0] === `prelude` ? segments[1] : segments[0]\n\t\t\tloadedConfigPath = configPath(\n\t\t\t\texplicit ?? defaultConfig(process.cwd()),\n\t\t\t\texplicit !== undefined,\n\t\t\t)\n\t\t\treturn loadedConfigPath\n\t\t},\n\t\troutes: optional({\n\t\t\thelp: null,\n\t\t\tnpm: optional({\n\t\t\t\thelp: null,\n\t\t\t\tcheck: null,\n\t\t\t\tplan: null,\n\t\t\t\texecute: required({ $id: null }),\n\t\t\t\tverify: null,\n\t\t\t\ttest: optional({ $peer: required({ $range: null }) }),\n\t\t\t}),\n\t\t\tprelude: optional({ $configPath: null }),\n\t\t\t$configPath: null,\n\t\t}),\n\t\trouteOptions: {\n\t\t\t\"\": BREAKAGE_MANUAL,\n\t\t\t$configPath: BREAKAGE_MANUAL,\n\t\t\thelp: noOptions(`Show usage.`),\n\t\t\tnpm: noOptions(`Show npm compatibility commands.`),\n\t\t\t\"npm/help\": noOptions(`Show npm compatibility commands.`),\n\t\t\t\"npm/check\": npmCheckManual,\n\t\t\t\"npm/plan\": npmPlanManual,\n\t\t\t\"npm/execute/$id\": npmExecuteManual,\n\t\t\t\"npm/verify\": npmVerifyManual,\n\t\t\t\"npm/test\": npmTestManual,\n\t\t\t\"npm/test/$peer/$range\": npmTestManual,\n\t\t\tprelude: PRELUDE_MANUAL,\n\t\t\t\"prelude/$configPath\": PRELUDE_MANUAL,\n\t\t},\n\t\tpositionalCompletions: {\n\t\t\t$configPath: { fileSystem: `files` },\n\t\t\t\"prelude/$configPath\": { fileSystem: `files` },\n\t\t},\n\t},\n\t{\n\t\tinfo: (message, ...data) => logger.info(`breakage`, message, data),\n\t\terror: (message, ...data) => logger.error(`breakage`, message, data),\n\t},\n)\n\nconst completion = await completionResponse(parse.definition, process.argv)\nif (completion !== undefined) {\n\tprocess.stdout.write(completion)\n} else {\n\ttry {\n\t\tconst { inputs, warnings } = await parse.async(process.argv)\n\t\tlogWarnings(warnings)\n\t\tif (\n\t\t\tprocess.argv\n\t\t\t\t.slice(2)\n\t\t\t\t.some((arg) =>\n\t\t\t\t\t/^(?:--certifyCommand|--certify-command|-c)(?:=|$)/.test(arg),\n\t\t\t\t)\n\t\t)\n\t\t\tthrow new Error(\n\t\t\t\t`certifyCommand was removed. Configure release.resolveDelta and release.policy instead.`,\n\t\t\t)\n\n\t\tswitch (inputs.case) {\n\t\t\tcase `npm`:\n\t\t\tcase `npm/help`:\n\t\t\tcase `help`:\n\t\t\t\tconsole.log(help(parse.definition))\n\t\t\t\tbreak\n\t\t\tcase `npm/check`:\n\t\t\t\tprocess.exitCode = await runNpmCli(`check`, inputs.opts)\n\t\t\t\tbreak\n\t\t\tcase `npm/plan`:\n\t\t\t\tprocess.exitCode = await runNpmMatrixCli(`plan`, inputs.opts)\n\t\t\t\tbreak\n\t\t\tcase `npm/execute/$id`:\n\t\t\t\tprocess.exitCode = await runNpmMatrixCli(\n\t\t\t\t\t`execute`,\n\t\t\t\t\tinputs.opts,\n\t\t\t\t\tinputs.params.id,\n\t\t\t\t)\n\t\t\t\tbreak\n\t\t\tcase `npm/verify`:\n\t\t\t\tprocess.exitCode = await runNpmMatrixCli(`verify`, inputs.opts)\n\t\t\t\tbreak\n\t\t\tcase `npm/test`:\n\t\t\t\tprocess.exitCode = await runNpmCli(`test`, inputs.opts)\n\t\t\t\tbreak\n\t\t\tcase `npm/test/$peer/$range`:\n\t\t\t\tprocess.exitCode = await runNpmCli(`test`, inputs.opts, inputs.params)\n\t\t\t\tbreak\n\t\t\tcase `prelude`:\n\t\t\tcase `prelude/$configPath`: {\n\t\t\t\tconst config = resolveConfig(inputs.opts, loadedConfigPath)\n\t\t\t\tconst baseline = await breakagePrelude({\n\t\t\t\t\t...config,\n\t\t\t\t\tout: config.out ?? `.breakage/baseline.json`,\n\t\t\t\t})\n\t\t\t\tprocess.stdout.write(`Pinned ${baseline.ref} at ${baseline.commit}.\\n`)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase ``:\n\t\t\tcase `$configPath`: {\n\t\t\t\tconst merged = resolveConfig(inputs.opts, loadedConfigPath)\n\t\t\t\tif (\n\t\t\t\t\tcommandOverrides.has(`testCommand`) &&\n\t\t\t\t\t!commandOverrides.has(`test`)\n\t\t\t\t)\n\t\t\t\t\tdelete merged.test\n\t\t\t\tif (\n\t\t\t\t\tcommandOverrides.has(`test`) &&\n\t\t\t\t\t!commandOverrides.has(`testCommand`)\n\t\t\t\t)\n\t\t\t\t\tdelete merged.testCommand\n\t\t\t\tif (!merged.testPattern)\n\t\t\t\t\tthrow new Error(`required arguments were not provided: testPattern.`)\n\t\t\t\tconst { returnValue } = await encapsulate(\n\t\t\t\t\t() =>\n\t\t\t\t\t\tbreakage({\n\t\t\t\t\t\t\t...merged,\n\t\t\t\t\t\t\ttestPattern: merged.testPattern!,\n\t\t\t\t\t\t}),\n\t\t\t\t\t{\n\t\t\t\t\t\tconsole: true,\n\t\t\t\t\t\tstdout: true,\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t\tif (`release` in returnValue && returnValue.release) {\n\t\t\t\t\tconst { previousVersion, version, delta, breaking } =\n\t\t\t\t\t\treturnValue.release\n\t\t\t\t\tprocess.stdout.write(\n\t\t\t\t\t\t`Release: ${previousVersion} → ${version} (${delta}; ${breaking ? `breaking` : `compatible`}).\\n`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tif (`testResult` in returnValue && returnValue.breakingChangesFound) {\n\t\t\t\t\tprocess.stdout.write(returnValue.testResult)\n\t\t\t\t}\n\t\t\t\tif (`breakingChangesFound` in returnValue) {\n\t\t\t\t\tif (returnValue.breakingChangesFound) {\n\t\t\t\t\t\tif (returnValue.release?.breaking) {\n\t\t\t\t\t\t\tprocess.stdout.write(\n\t\t\t\t\t\t\t\t`👷 Breaking changes are covered by the breaking release.`,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tprocess.exit(0)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tprocess.stdout.write(\n\t\t\t\t\t\t\t\t`❌ Breaking changes require a breaking release.`,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tprocess.exit(1)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tprocess.stdout.write(`✅ No breaking changes were found.`)\n\t\t\t\t\t\tprocess.exit(0)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tprocess.stdout.write(\n\t\t\t\t\t\t`💥 Breakage failed to determine breaking changes.` +\n\t\t\t\t\t\t\t`\\n` +\n\t\t\t\t\t\t\tinspect(returnValue),\n\t\t\t\t\t)\n\t\t\t\t\tprocess.exit(2)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tprocess.stderr.write(`Breakage setup error: ${errorMessage(error)}\\n`)\n\t\tprocess.exitCode = 2\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { c as VersionTransition, n as ReleaseDeltaContext } from "./release-D47BqRuB.js";
|
|
2
|
+
/** Read the actual Changesets plan, including dependent bumps and prerelease state. */
|
|
3
|
+
export declare function readChangesetsReleasePlan(directory?: string): Promise<ReadonlyMap<string, string>>;
|
|
4
|
+
/** Compare the selected baseline (or current manifest) with the planned or versioned release. */
|
|
5
|
+
export declare function changesetsReleaseDelta({ directory }?: {
|
|
6
|
+
directory?: string;
|
|
7
|
+
}): (context: ReleaseDeltaContext) => Promise<VersionTransition>;
|
|
8
|
+
//# sourceMappingURL=changesets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"changesets.d.ts","names":[],"sources":["../src/changesets.ts"],"mappings":";;wBAasB,0BACrB,qBACE,QAAQ;;wBAkBK,yBACf;EACI;KACJ,SAAS,wBACL,QAAQ"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { s as versionTransition } from "./release-BsdIDT4g.js";
|
|
2
|
+
import { assembleReleasePlan } from "@changesets/assemble-release-plan";
|
|
3
|
+
import { readConfig } from "@changesets/config";
|
|
4
|
+
import { readPreState } from "@changesets/pre";
|
|
5
|
+
import { readChangesets } from "@changesets/read";
|
|
6
|
+
import { getPackages } from "@manypkg/get-packages";
|
|
7
|
+
// src/changesets.ts
|
|
8
|
+
/** Read the actual Changesets plan, including dependent bumps and prerelease state. */
|
|
9
|
+
async function readChangesetsReleasePlan(directory = process.cwd()) {
|
|
10
|
+
const packages = await getPackages(directory);
|
|
11
|
+
const root = packages.rootDir;
|
|
12
|
+
const { config, errors } = await readConfig(root, packages);
|
|
13
|
+
if (errors) throw new Error(errors.join(`\n`));
|
|
14
|
+
const [changesets, preState] = await Promise.all([readChangesets(root), readPreState(root)]);
|
|
15
|
+
const plan = assembleReleasePlan(changesets, packages, config, preState);
|
|
16
|
+
return new Map(plan.releases.flatMap(({ name, newVersion }) => newVersion === void 0 ? [] : [[name, newVersion]]));
|
|
17
|
+
}
|
|
18
|
+
/** Compare the selected baseline (or current manifest) with the planned or versioned release. */
|
|
19
|
+
function changesetsReleaseDelta({ directory } = {}) {
|
|
20
|
+
return async ({ packageName, packageDirectory, currentVersion, baseline }) => {
|
|
21
|
+
const version = (await readChangesetsReleasePlan(directory ?? packageDirectory)).get(packageName) ?? currentVersion;
|
|
22
|
+
return versionTransition(baseline?.version ?? currentVersion, version);
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export { changesetsReleaseDelta, readChangesetsReleasePlan };
|
|
26
|
+
|
|
27
|
+
//# sourceMappingURL=changesets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"changesets.js","names":[],"sources":["../src/changesets.ts"],"sourcesContent":["import { assembleReleasePlan } from \"@changesets/assemble-release-plan\"\nimport { readConfig } from \"@changesets/config\"\nimport { readPreState } from \"@changesets/pre\"\nimport { readChangesets } from \"@changesets/read\"\nimport { getPackages } from \"@manypkg/get-packages\"\n\nimport {\n\tversionTransition,\n\ttype ReleaseDeltaContext,\n\ttype VersionTransition,\n} from \"./release.ts\"\n\n/** Read the actual Changesets plan, including dependent bumps and prerelease state. */\nexport async function readChangesetsReleasePlan(\n\tdirectory: string = process.cwd(),\n): Promise<ReadonlyMap<string, string>> {\n\tconst packages = await getPackages(directory)\n\tconst root = packages.rootDir\n\tconst { config, errors } = await readConfig(root, packages)\n\tif (errors) throw new Error(errors.join(`\\n`))\n\tconst [changesets, preState] = await Promise.all([\n\t\treadChangesets(root),\n\t\treadPreState(root),\n\t])\n\tconst plan = assembleReleasePlan(changesets, packages, config, preState)\n\treturn new Map(\n\t\tplan.releases.flatMap(({ name, newVersion }) =>\n\t\t\tnewVersion === undefined ? [] : [[name, newVersion] as const],\n\t\t),\n\t)\n}\n\n/** Compare the selected baseline (or current manifest) with the planned or versioned release. */\nexport function changesetsReleaseDelta({\n\tdirectory,\n}: { directory?: string } = {}): (\n\tcontext: ReleaseDeltaContext,\n) => Promise<VersionTransition> {\n\treturn async ({\n\t\tpackageName,\n\t\tpackageDirectory,\n\t\tcurrentVersion,\n\t\tbaseline,\n\t}) => {\n\t\tconst version =\n\t\t\t(await readChangesetsReleasePlan(directory ?? packageDirectory)).get(\n\t\t\t\tpackageName,\n\t\t\t) ?? currentVersion\n\t\treturn versionTransition(baseline?.version ?? currentVersion, version)\n\t}\n}\n"],"mappings":";;;;;;;;AAaA,eAAsB,0BACrB,YAAoB,QAAQ,IAAI,GACO;CACvC,MAAM,WAAW,MAAM,YAAY,SAAS;CAC5C,MAAM,OAAO,SAAS;CACtB,MAAM,EAAE,QAAQ,WAAW,MAAM,WAAW,MAAM,QAAQ;CAC1D,IAAI,QAAQ,MAAM,IAAI,MAAM,OAAO,KAAK,IAAI,CAAC;CAC7C,MAAM,CAAC,YAAY,YAAY,MAAM,QAAQ,IAAI,CAChD,eAAe,IAAI,GACnB,aAAa,IAAI,CAClB,CAAC;CACD,MAAM,OAAO,oBAAoB,YAAY,UAAU,QAAQ,QAAQ;CACvE,OAAO,IAAI,IACV,KAAK,SAAS,SAAS,EAAE,MAAM,iBAC9B,eAAe,KAAA,IAAY,CAAC,IAAI,CAAC,CAAC,MAAM,UAAU,CAAU,CAC7D,CACD;AACD;;AAGA,SAAgB,uBAAuB,EACtC,cAC2B,CAAC,GAEG;CAC/B,OAAO,OAAO,EACb,aACA,kBACA,gBACA,eACK;EACL,MAAM,WACJ,MAAM,0BAA0B,aAAa,gBAAgB,EAAA,CAAG,IAChE,WACD,KAAK;EACN,OAAO,kBAAkB,UAAU,WAAW,gBAAgB,OAAO;CACtE;AACD"}
|