@ethlete/cli 2.1.0-next.7 → 2.1.0-next.9
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/CHANGELOG.md +24 -0
- package/README.md +35 -0
- package/design/define-call.ts +92 -0
- package/design/web/env.d.ts +11 -0
- package/design/web/frame.html +17 -0
- package/design/web/frame.ts +38 -0
- package/design/web/host.css +494 -0
- package/design/web/host.ts +445 -0
- package/design/web/index.html +11 -0
- package/package.json +12 -1
- package/src/index.js +25 -0
- package/src/index.js.map +1 -1
- package/src/lib/config/diagnose.js +9 -0
- package/src/lib/config/diagnose.js.map +1 -1
- package/src/lib/config/local-config.d.ts +2 -0
- package/src/lib/config/local-config.js +6 -1
- package/src/lib/config/local-config.js.map +1 -1
- package/src/lib/design/calls-tsconfig.d.ts +6 -0
- package/src/lib/design/calls-tsconfig.js +37 -0
- package/src/lib/design/calls-tsconfig.js.map +1 -0
- package/src/lib/design/check.d.ts +11 -0
- package/src/lib/design/check.js +192 -0
- package/src/lib/design/check.js.map +1 -0
- package/src/lib/design/design-command.d.ts +10 -0
- package/src/lib/design/design-command.js +32 -0
- package/src/lib/design/design-command.js.map +1 -0
- package/src/lib/design/index.d.ts +5 -0
- package/src/lib/design/index.js +9 -0
- package/src/lib/design/index.js.map +1 -0
- package/src/lib/design/paths.d.ts +24 -0
- package/src/lib/design/paths.js +31 -0
- package/src/lib/design/paths.js.map +1 -0
- package/src/lib/design/serve.d.ts +7 -0
- package/src/lib/design/serve.js +144 -0
- package/src/lib/design/serve.js.map +1 -0
- package/src/lib/doctor/doctor-command.d.ts +3 -1
- package/src/lib/doctor/doctor-command.js +5 -5
- package/src/lib/doctor/doctor-command.js.map +1 -1
- package/src/lib/index.d.ts +2 -0
- package/src/lib/index.js +2 -0
- package/src/lib/index.js.map +1 -1
- package/src/lib/release.js +21 -3
- package/src/lib/release.js.map +1 -1
- package/src/lib/update/ai.d.ts +30 -0
- package/src/lib/update/ai.js +44 -0
- package/src/lib/update/ai.js.map +1 -0
- package/src/lib/update/args.d.ts +21 -0
- package/src/lib/update/args.js +89 -0
- package/src/lib/update/args.js.map +1 -0
- package/src/lib/update/index.d.ts +12 -0
- package/src/lib/update/index.js +16 -0
- package/src/lib/update/index.js.map +1 -0
- package/src/lib/update/migration-manifest.d.ts +40 -0
- package/src/lib/update/migration-manifest.js +137 -0
- package/src/lib/update/migration-manifest.js.map +1 -0
- package/src/lib/update/package-manager.d.ts +23 -0
- package/src/lib/update/package-manager.js +47 -0
- package/src/lib/update/package-manager.js.map +1 -0
- package/src/lib/update/packages.d.ts +65 -0
- package/src/lib/update/packages.js +147 -0
- package/src/lib/update/packages.js.map +1 -0
- package/src/lib/update/pending.d.ts +21 -0
- package/src/lib/update/pending.js +41 -0
- package/src/lib/update/pending.js.map +1 -0
- package/src/lib/update/plan.d.ts +51 -0
- package/src/lib/update/plan.js +101 -0
- package/src/lib/update/plan.js.map +1 -0
- package/src/lib/update/registry.d.ts +31 -0
- package/src/lib/update/registry.js +54 -0
- package/src/lib/update/registry.js.map +1 -0
- package/src/lib/update/run-migrations.d.ts +44 -0
- package/src/lib/update/run-migrations.js +73 -0
- package/src/lib/update/run-migrations.js.map +1 -0
- package/src/lib/update/semver.d.ts +19 -0
- package/src/lib/update/semver.js +79 -0
- package/src/lib/update/semver.js.map +1 -0
- package/src/lib/update/tasks.d.ts +58 -0
- package/src/lib/update/tasks.js +174 -0
- package/src/lib/update/tasks.js.map +1 -0
- package/src/lib/update/update-command.d.ts +12 -0
- package/src/lib/update/update-command.js +304 -0
- package/src/lib/update/update-command.js.map +1 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.versionOfRange = exports.rangePrefix = exports.prereleaseTag = exports.isValidVersion = exports.isInUpdateRange = exports.isNewer = exports.compareVersions = void 0;
|
|
4
|
+
const NUMERIC = /^\d+$/;
|
|
5
|
+
const parseVersion = (version) => {
|
|
6
|
+
const [core = '', ...prereleaseParts] = version.split('-');
|
|
7
|
+
const prerelease = prereleaseParts.join('-');
|
|
8
|
+
return {
|
|
9
|
+
numbers: core.split('.').map((part) => Number.parseInt(part, 10) || 0),
|
|
10
|
+
prerelease: prerelease === '' ? [] : prerelease.split('.'),
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
const comparePrerelease = (left, right) => {
|
|
14
|
+
// Semver: a version without a prerelease outranks the same version with one.
|
|
15
|
+
if (left.length === 0 && right.length === 0)
|
|
16
|
+
return 0;
|
|
17
|
+
if (left.length === 0)
|
|
18
|
+
return 1;
|
|
19
|
+
if (right.length === 0)
|
|
20
|
+
return -1;
|
|
21
|
+
for (let index = 0; index < Math.max(left.length, right.length); index += 1) {
|
|
22
|
+
const leftPart = left[index];
|
|
23
|
+
const rightPart = right[index];
|
|
24
|
+
if (leftPart === undefined)
|
|
25
|
+
return -1;
|
|
26
|
+
if (rightPart === undefined)
|
|
27
|
+
return 1;
|
|
28
|
+
if (NUMERIC.test(leftPart) && NUMERIC.test(rightPart)) {
|
|
29
|
+
const leftNumber = Number.parseInt(leftPart, 10);
|
|
30
|
+
const rightNumber = Number.parseInt(rightPart, 10);
|
|
31
|
+
if (leftNumber !== rightNumber)
|
|
32
|
+
return leftNumber < rightNumber ? -1 : 1;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (leftPart !== rightPart)
|
|
36
|
+
return leftPart < rightPart ? -1 : 1;
|
|
37
|
+
}
|
|
38
|
+
return 0;
|
|
39
|
+
};
|
|
40
|
+
/** `-1`, `0` or `1`, prerelease-aware for the `x.y.z-next.N` versions this repo publishes. */
|
|
41
|
+
const compareVersions = (left, right) => {
|
|
42
|
+
var _a, _b;
|
|
43
|
+
const parsedLeft = parseVersion(left);
|
|
44
|
+
const parsedRight = parseVersion(right);
|
|
45
|
+
for (let index = 0; index < Math.max(parsedLeft.numbers.length, parsedRight.numbers.length); index += 1) {
|
|
46
|
+
const leftNumber = (_a = parsedLeft.numbers[index]) !== null && _a !== void 0 ? _a : 0;
|
|
47
|
+
const rightNumber = (_b = parsedRight.numbers[index]) !== null && _b !== void 0 ? _b : 0;
|
|
48
|
+
if (leftNumber !== rightNumber)
|
|
49
|
+
return leftNumber < rightNumber ? -1 : 1;
|
|
50
|
+
}
|
|
51
|
+
return comparePrerelease(parsedLeft.prerelease, parsedRight.prerelease);
|
|
52
|
+
};
|
|
53
|
+
exports.compareVersions = compareVersions;
|
|
54
|
+
const isNewer = (candidate, than) => (0, exports.compareVersions)(candidate, than) > 0;
|
|
55
|
+
exports.isNewer = isNewer;
|
|
56
|
+
/** True when `version` sits inside `(after, upTo]`, the range a pending migration is selected by. */
|
|
57
|
+
const isInUpdateRange = (options) => (0, exports.compareVersions)(options.version, options.after) > 0 && (0, exports.compareVersions)(options.version, options.upTo) <= 0;
|
|
58
|
+
exports.isInUpdateRange = isInUpdateRange;
|
|
59
|
+
const isValidVersion = (version) => /^\d+\.\d+\.\d+(?:[-+].*)?$/.test(version);
|
|
60
|
+
exports.isValidVersion = isValidVersion;
|
|
61
|
+
/**
|
|
62
|
+
* The dist tag a prerelease belongs to, for example `next` for `5.0.0-next.46`. A stable version has
|
|
63
|
+
* none, and neither has a prerelease that only numbers its identifiers.
|
|
64
|
+
*/
|
|
65
|
+
const prereleaseTag = (version) => parseVersion(version).prerelease.find((part) => !NUMERIC.test(part));
|
|
66
|
+
exports.prereleaseTag = prereleaseTag;
|
|
67
|
+
/** The `^` or `~` a range keeps, or `''` for an exact one. `undefined` for a range with no single version. */
|
|
68
|
+
const rangePrefix = (range) => {
|
|
69
|
+
const match = /^([\^~]?)(\d+\.\d+\.\d+(?:[-+][\w.-]+)?)$/.exec(range.trim());
|
|
70
|
+
return match ? match[1] : undefined;
|
|
71
|
+
};
|
|
72
|
+
exports.rangePrefix = rangePrefix;
|
|
73
|
+
/** The version a range points at, for example `5.0.0-next.46` for `^5.0.0-next.46`. */
|
|
74
|
+
const versionOfRange = (range) => {
|
|
75
|
+
const match = /^[\^~]?(\d+\.\d+\.\d+(?:[-+][\w.-]+)?)$/.exec(range.trim());
|
|
76
|
+
return match === null || match === void 0 ? void 0 : match[1];
|
|
77
|
+
};
|
|
78
|
+
exports.versionOfRange = versionOfRange;
|
|
79
|
+
//# sourceMappingURL=semver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semver.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/update/semver.ts"],"names":[],"mappings":";;;AAAA,MAAM,OAAO,GAAG,OAAO,CAAC;AAOxB,MAAM,YAAY,GAAG,CAAC,OAAe,EAAiB,EAAE;IACtD,MAAM,CAAC,IAAI,GAAG,EAAE,EAAE,GAAG,eAAe,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3D,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAE7C,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;QACtE,UAAU,EAAE,UAAU,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC;KAC3D,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,IAAc,EAAE,KAAe,EAAE,EAAE;IAC5D,6EAA6E;IAC7E,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACtD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAChC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC,CAAC;IAElC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAC5E,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7B,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QAE/B,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,CAAC,CAAC,CAAC;QACtC,IAAI,SAAS,KAAK,SAAS;YAAE,OAAO,CAAC,CAAC;QAEtC,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACtD,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YACjD,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;YAEnD,IAAI,UAAU,KAAK,WAAW;gBAAE,OAAO,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACzE,SAAS;QACX,CAAC;QAED,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AAEF,8FAA8F;AACvF,MAAM,eAAe,GAAG,CAAC,IAAY,EAAE,KAAa,EAAE,EAAE;;IAC7D,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,WAAW,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IAExC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACxG,MAAM,UAAU,GAAG,MAAA,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,mCAAI,CAAC,CAAC;QAClD,MAAM,WAAW,GAAG,MAAA,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,mCAAI,CAAC,CAAC;QAEpD,IAAI,UAAU,KAAK,WAAW;YAAE,OAAO,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED,OAAO,iBAAiB,CAAC,UAAU,CAAC,UAAU,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;AAC1E,CAAC,CAAC;AAZW,QAAA,eAAe,mBAY1B;AAEK,MAAM,OAAO,GAAG,CAAC,SAAiB,EAAE,IAAY,EAAE,EAAE,CAAC,IAAA,uBAAe,EAAC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;AAApF,QAAA,OAAO,WAA6E;AAEjG,qGAAqG;AAC9F,MAAM,eAAe,GAAG,CAAC,OAAyD,EAAE,EAAE,CAC3F,IAAA,uBAAe,EAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,IAAA,uBAAe,EAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AADhG,QAAA,eAAe,mBACiF;AAEtG,MAAM,cAAc,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,4BAA4B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAAjF,QAAA,cAAc,kBAAmE;AAE9F;;;GAGG;AACI,MAAM,aAAa,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAA1G,QAAA,aAAa,iBAA6F;AAEvH,8GAA8G;AACvG,MAAM,WAAW,GAAG,CAAC,KAAa,EAAE,EAAE;IAC3C,MAAM,KAAK,GAAG,2CAA2C,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAE7E,OAAO,KAAK,CAAC,CAAC,CAAE,KAAK,CAAC,CAAC,CAAY,CAAC,CAAC,CAAC,SAAS,CAAC;AAClD,CAAC,CAAC;AAJW,QAAA,WAAW,eAItB;AAEF,uFAAuF;AAChF,MAAM,cAAc,GAAG,CAAC,KAAa,EAAE,EAAE;IAC9C,MAAM,KAAK,GAAG,yCAAyC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAE3E,OAAO,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAG,CAAC,CAAC,CAAC;AACpB,CAAC,CAAC;AAJW,QAAA,cAAc,kBAIzB"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { PackageManager } from './package-manager';
|
|
2
|
+
import { UpdatedPackage } from './plan';
|
|
3
|
+
import { MigrationOutcome } from './run-migrations';
|
|
4
|
+
export declare const UPDATE_DIR: string;
|
|
5
|
+
export declare const TASKS_FILE = "tasks.md";
|
|
6
|
+
export declare const TASKS_DATA_FILE = "tasks.json";
|
|
7
|
+
export declare const DOCS_BASE_URL = "https://ethlete-sdk-docs.web.app";
|
|
8
|
+
export type UpdateTask = {
|
|
9
|
+
packageName: string;
|
|
10
|
+
name: string;
|
|
11
|
+
version: string;
|
|
12
|
+
kind: 'manual' | 'assisted' | 'unsupported';
|
|
13
|
+
description: string;
|
|
14
|
+
/** Repo-relative path of the copied instructions, when the migration ships any. */
|
|
15
|
+
instructionsFile?: string;
|
|
16
|
+
docsUrl?: string;
|
|
17
|
+
/** For an `unsupported` auto migration: the generator command to run by hand. */
|
|
18
|
+
command?: string;
|
|
19
|
+
};
|
|
20
|
+
export declare const taskFileName: (options: {
|
|
21
|
+
packageName: string;
|
|
22
|
+
name: string;
|
|
23
|
+
}) => string;
|
|
24
|
+
/** The tasks an update leaves behind: what needs a decision, a prompt, or a command Nx could not run. */
|
|
25
|
+
export declare const collectTasks: (options: {
|
|
26
|
+
outcomes: readonly MigrationOutcome[];
|
|
27
|
+
manager: PackageManager;
|
|
28
|
+
}) => UpdateTask[];
|
|
29
|
+
export declare const renderTasks: (options: {
|
|
30
|
+
updates: readonly UpdatedPackage[];
|
|
31
|
+
outcomes: readonly MigrationOutcome[];
|
|
32
|
+
tasks: readonly UpdateTask[];
|
|
33
|
+
}) => string;
|
|
34
|
+
/**
|
|
35
|
+
* One task as its own file: what moved and where to read more, then the instructions the package ships.
|
|
36
|
+
* The header is what makes the file readable on its own once the update is over.
|
|
37
|
+
*/
|
|
38
|
+
export declare const renderTaskFile: (options: {
|
|
39
|
+
task: UpdateTask;
|
|
40
|
+
instructions: string;
|
|
41
|
+
}) => string;
|
|
42
|
+
export type WrittenTasks = {
|
|
43
|
+
/** Repo-relative path of the report. */
|
|
44
|
+
reportPath: string;
|
|
45
|
+
dataPath: string;
|
|
46
|
+
tasks: UpdateTask[];
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Writes the report, the machine-readable task list an agent reads, and a copy of every instructions
|
|
50
|
+
* file, so the whole task list stands on its own once `node_modules` changes again.
|
|
51
|
+
*/
|
|
52
|
+
export declare const writeUpdateTasks: (options: {
|
|
53
|
+
root: string;
|
|
54
|
+
updates: readonly UpdatedPackage[];
|
|
55
|
+
outcomes: readonly MigrationOutcome[];
|
|
56
|
+
manager: PackageManager;
|
|
57
|
+
generatedAt: string;
|
|
58
|
+
}) => WrittenTasks;
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.writeUpdateTasks = exports.renderTaskFile = exports.renderTasks = exports.collectTasks = exports.taskFileName = exports.DOCS_BASE_URL = exports.TASKS_DATA_FILE = exports.TASKS_FILE = exports.UPDATE_DIR = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const migration_manifest_1 = require("./migration-manifest");
|
|
7
|
+
const run_migrations_1 = require("./run-migrations");
|
|
8
|
+
exports.UPDATE_DIR = (0, path_1.join)('.ethlete', 'update');
|
|
9
|
+
exports.TASKS_FILE = 'tasks.md';
|
|
10
|
+
exports.TASKS_DATA_FILE = 'tasks.json';
|
|
11
|
+
exports.DOCS_BASE_URL = 'https://ethlete-sdk-docs.web.app';
|
|
12
|
+
const withoutScope = (packageName) => packageName.replace('@ethlete/', '');
|
|
13
|
+
const taskFileName = (options) => `${withoutScope(options.packageName)}-${options.name}.md`;
|
|
14
|
+
exports.taskFileName = taskFileName;
|
|
15
|
+
/** The tasks an update leaves behind: what needs a decision, a prompt, or a command Nx could not run. */
|
|
16
|
+
const collectTasks = (options) => {
|
|
17
|
+
const { outcomes, manager } = options;
|
|
18
|
+
const tasks = [];
|
|
19
|
+
for (const outcome of outcomes) {
|
|
20
|
+
const { migration, packageName, manifestPath } = outcome.pending;
|
|
21
|
+
const source = (0, migration_manifest_1.instructionsPath)({ manifestPath, migration });
|
|
22
|
+
const shared = {
|
|
23
|
+
packageName,
|
|
24
|
+
name: migration.name,
|
|
25
|
+
version: migration.version,
|
|
26
|
+
description: migration.description,
|
|
27
|
+
instructionsFile: source ? (0, path_1.join)(exports.UPDATE_DIR, (0, exports.taskFileName)({ packageName, name: migration.name })) : undefined,
|
|
28
|
+
docsUrl: migration.docs ? `${exports.DOCS_BASE_URL}${migration.docs}` : undefined,
|
|
29
|
+
};
|
|
30
|
+
if (outcome.state === 'unsupported') {
|
|
31
|
+
tasks.push(Object.assign(Object.assign({}, shared), { kind: 'unsupported', command: (0, run_migrations_1.manualGeneratorCommand)({ manager, migration }) }));
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (outcome.state !== 'task')
|
|
35
|
+
continue;
|
|
36
|
+
if (migration.kind === 'manual' || migration.kind === 'assisted')
|
|
37
|
+
tasks.push(Object.assign(Object.assign({}, shared), { kind: migration.kind }));
|
|
38
|
+
}
|
|
39
|
+
return tasks;
|
|
40
|
+
};
|
|
41
|
+
exports.collectTasks = collectTasks;
|
|
42
|
+
const KIND_HEADINGS = {
|
|
43
|
+
unsupported: 'Codemods to run by hand',
|
|
44
|
+
manual: 'Changes that need a decision',
|
|
45
|
+
assisted: 'Changes an agent can make',
|
|
46
|
+
};
|
|
47
|
+
const renderTask = (task) => [
|
|
48
|
+
`### ${task.packageName} — ${task.name}`,
|
|
49
|
+
'',
|
|
50
|
+
`Landed in ${task.version}. ${task.description}`,
|
|
51
|
+
...(task.command ? ['', `Run: \`${task.command}\``] : []),
|
|
52
|
+
...(task.instructionsFile ? ['', `Instructions: \`${task.instructionsFile}\``] : []),
|
|
53
|
+
...(task.docsUrl ? ['', `Docs: ${task.docsUrl}`] : []),
|
|
54
|
+
'',
|
|
55
|
+
].join('\n');
|
|
56
|
+
const renderGroup = (kind, tasks) => {
|
|
57
|
+
const group = tasks.filter((task) => task.kind === kind);
|
|
58
|
+
if (group.length === 0)
|
|
59
|
+
return [];
|
|
60
|
+
return [`## ${KIND_HEADINGS[kind]}`, '', ...group.map(renderTask)];
|
|
61
|
+
};
|
|
62
|
+
const renderTasks = (options) => {
|
|
63
|
+
const { updates, outcomes, tasks } = options;
|
|
64
|
+
const applied = outcomes.filter((outcome) => outcome.state === 'applied');
|
|
65
|
+
const failed = outcomes.filter((outcome) => outcome.state === 'failed');
|
|
66
|
+
return [
|
|
67
|
+
'# Ethlete update: what is left to do',
|
|
68
|
+
'',
|
|
69
|
+
'`et update` moved these packages:',
|
|
70
|
+
'',
|
|
71
|
+
...updates.map((update) => { var _a; return `- \`${update.name}\`: ${(_a = update.from) !== null && _a !== void 0 ? _a : 'not installed'} → ${update.to}`; }),
|
|
72
|
+
'',
|
|
73
|
+
...(applied.length > 0
|
|
74
|
+
? [
|
|
75
|
+
'It applied these codemods:',
|
|
76
|
+
'',
|
|
77
|
+
...applied.map((outcome) => `- \`${outcome.pending.packageName}\` ${outcome.pending.migration.name} (${outcome.pending.migration.generator})`),
|
|
78
|
+
'',
|
|
79
|
+
]
|
|
80
|
+
: []),
|
|
81
|
+
...(failed.length > 0
|
|
82
|
+
? [
|
|
83
|
+
'These codemods failed. Run each one again by hand and read its output:',
|
|
84
|
+
'',
|
|
85
|
+
...failed.map((outcome) => `- \`${outcome.pending.packageName}\` ${outcome.pending.migration.name} — ${outcome.reason}`),
|
|
86
|
+
'',
|
|
87
|
+
]
|
|
88
|
+
: []),
|
|
89
|
+
...(tasks.length === 0
|
|
90
|
+
? ['Nothing else needs a decision.', '']
|
|
91
|
+
: [
|
|
92
|
+
'Everything below needs a decision the codemods cannot make.',
|
|
93
|
+
'',
|
|
94
|
+
...renderGroup('unsupported', tasks),
|
|
95
|
+
...renderGroup('manual', tasks),
|
|
96
|
+
...renderGroup('assisted', tasks),
|
|
97
|
+
]),
|
|
98
|
+
].join('\n');
|
|
99
|
+
};
|
|
100
|
+
exports.renderTasks = renderTasks;
|
|
101
|
+
/**
|
|
102
|
+
* One task as its own file: what moved and where to read more, then the instructions the package ships.
|
|
103
|
+
* The header is what makes the file readable on its own once the update is over.
|
|
104
|
+
*/
|
|
105
|
+
const renderTaskFile = (options) => {
|
|
106
|
+
const { task, instructions } = options;
|
|
107
|
+
return [
|
|
108
|
+
`<!-- Written by et update. ${task.packageName} ${task.version}, migration "${task.name}". -->`,
|
|
109
|
+
'',
|
|
110
|
+
...(task.kind === 'assisted'
|
|
111
|
+
? ['> Hand this file to an agent. It describes one change to apply across this repository.', '']
|
|
112
|
+
: []),
|
|
113
|
+
`- Package: \`${task.packageName}\``,
|
|
114
|
+
`- Landed in: ${task.version}`,
|
|
115
|
+
`- Summary: ${task.description}`,
|
|
116
|
+
...(task.docsUrl ? [`- Docs: ${task.docsUrl}`] : []),
|
|
117
|
+
'',
|
|
118
|
+
'---',
|
|
119
|
+
'',
|
|
120
|
+
instructions.trim(),
|
|
121
|
+
].join('\n');
|
|
122
|
+
};
|
|
123
|
+
exports.renderTaskFile = renderTaskFile;
|
|
124
|
+
/**
|
|
125
|
+
* Writes the report, the machine-readable task list an agent reads, and a copy of every instructions
|
|
126
|
+
* file, so the whole task list stands on its own once `node_modules` changes again.
|
|
127
|
+
*/
|
|
128
|
+
const writeUpdateTasks = (options) => {
|
|
129
|
+
const { root, updates, outcomes, manager, generatedAt } = options;
|
|
130
|
+
const tasks = (0, exports.collectTasks)({ outcomes, manager });
|
|
131
|
+
const directory = (0, path_1.join)(root, exports.UPDATE_DIR);
|
|
132
|
+
(0, fs_1.mkdirSync)(directory, { recursive: true });
|
|
133
|
+
for (const outcome of outcomes) {
|
|
134
|
+
const source = (0, migration_manifest_1.instructionsPath)({
|
|
135
|
+
manifestPath: outcome.pending.manifestPath,
|
|
136
|
+
migration: outcome.pending.migration,
|
|
137
|
+
});
|
|
138
|
+
const task = tasks.find((candidate) => candidate.packageName === outcome.pending.packageName && candidate.name === outcome.pending.migration.name);
|
|
139
|
+
if (!source || !task)
|
|
140
|
+
continue;
|
|
141
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(directory, (0, exports.taskFileName)({ packageName: task.packageName, name: task.name })), `${(0, exports.renderTaskFile)({ task, instructions: (0, fs_1.readFileSync)(source, 'utf8') })}\n`, 'utf8');
|
|
142
|
+
}
|
|
143
|
+
const reportPath = (0, path_1.join)(exports.UPDATE_DIR, exports.TASKS_FILE);
|
|
144
|
+
const dataPath = (0, path_1.join)(exports.UPDATE_DIR, exports.TASKS_DATA_FILE);
|
|
145
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(root, reportPath), `${(0, exports.renderTasks)({ updates, outcomes, tasks })}\n`, 'utf8');
|
|
146
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(root, dataPath), `${JSON.stringify({
|
|
147
|
+
generatedAt,
|
|
148
|
+
updates: updates.map((update) => { var _a; return ({ package: update.name, from: (_a = update.from) !== null && _a !== void 0 ? _a : null, to: update.to }); }),
|
|
149
|
+
applied: outcomes
|
|
150
|
+
.filter((outcome) => outcome.state === 'applied')
|
|
151
|
+
.map((outcome) => {
|
|
152
|
+
var _a;
|
|
153
|
+
return ({
|
|
154
|
+
package: outcome.pending.packageName,
|
|
155
|
+
name: outcome.pending.migration.name,
|
|
156
|
+
generator: (_a = outcome.pending.migration.generator) !== null && _a !== void 0 ? _a : null,
|
|
157
|
+
});
|
|
158
|
+
}),
|
|
159
|
+
failed: outcomes
|
|
160
|
+
.filter((outcome) => outcome.state === 'failed')
|
|
161
|
+
.map((outcome) => {
|
|
162
|
+
var _a;
|
|
163
|
+
return ({
|
|
164
|
+
package: outcome.pending.packageName,
|
|
165
|
+
name: outcome.pending.migration.name,
|
|
166
|
+
reason: (_a = outcome.reason) !== null && _a !== void 0 ? _a : null,
|
|
167
|
+
});
|
|
168
|
+
}),
|
|
169
|
+
tasks,
|
|
170
|
+
}, null, 2)}\n`, 'utf8');
|
|
171
|
+
return { reportPath, dataPath, tasks };
|
|
172
|
+
};
|
|
173
|
+
exports.writeUpdateTasks = writeUpdateTasks;
|
|
174
|
+
//# sourceMappingURL=tasks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/update/tasks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type UpdateCommandOptions = {
|
|
2
|
+
/** Arguments after `update`, for example `['core', '--tag', 'next']`. */
|
|
3
|
+
argv: string[];
|
|
4
|
+
root?: string;
|
|
5
|
+
/** How the caller is invoked, used in the usage line. */
|
|
6
|
+
invocation?: string;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Moves this repo's `@ethlete/*` dependencies to a newer version and runs the migrations those versions
|
|
10
|
+
* ship. Everything the codemods cannot decide is written to a task list under `.ethlete/update`.
|
|
11
|
+
*/
|
|
12
|
+
export declare const updateCommand: ({ argv, root, invocation, }: UpdateCommandOptions) => Promise<number>;
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.updateCommand = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const git_1 = require("../api/git");
|
|
6
|
+
const local_config_1 = require("../config/local-config");
|
|
7
|
+
const ai_1 = require("./ai");
|
|
8
|
+
const args_1 = require("./args");
|
|
9
|
+
const migration_manifest_1 = require("./migration-manifest");
|
|
10
|
+
const package_manager_1 = require("./package-manager");
|
|
11
|
+
const packages_1 = require("./packages");
|
|
12
|
+
const plan_1 = require("./plan");
|
|
13
|
+
const pending_1 = require("./pending");
|
|
14
|
+
const registry_1 = require("./registry");
|
|
15
|
+
const run_migrations_1 = require("./run-migrations");
|
|
16
|
+
const tasks_1 = require("./tasks");
|
|
17
|
+
const usage = (invocation) => [
|
|
18
|
+
`Usage: ${invocation} [packages...] [flags]`,
|
|
19
|
+
'',
|
|
20
|
+
'Moves the @ethlete/* packages this repo declares to a newer version, then runs the migrations',
|
|
21
|
+
'those versions ship: the codemods by itself, and a report for everything that needs a decision.',
|
|
22
|
+
'',
|
|
23
|
+
'Every package.json in the repo is rewritten, not only the root one, so a library manifest that',
|
|
24
|
+
'pins @ethlete/* moves with it.',
|
|
25
|
+
'',
|
|
26
|
+
'A package may be named short (`core`) or in full (`@ethlete/core`). With no name, every',
|
|
27
|
+
'@ethlete/* dependency is updated.',
|
|
28
|
+
'',
|
|
29
|
+
'Flags',
|
|
30
|
+
' --check Print what would change and exit 1 when an update is pending. Writes nothing',
|
|
31
|
+
' --dry-run Print the plan, and the migrations the installed versions know about',
|
|
32
|
+
' --tag <tag> Dist tag to update to. Defaults to the tag the installed prerelease is on',
|
|
33
|
+
' --to <version> Exact version for the one package you name',
|
|
34
|
+
' --from <p@ver> The version a package migrates from, when the installed one is already newer',
|
|
35
|
+
' --no-install Write package.json, then stop. Install yourself and re-run with --continue',
|
|
36
|
+
' --continue Run the migrations of an update that was written but never finished',
|
|
37
|
+
' --ai Hand every agent-assisted task to the command in updateAgentCommand',
|
|
38
|
+
' --force Update even when the working tree has uncommitted changes',
|
|
39
|
+
].join('\n');
|
|
40
|
+
const padded = (value, width) => value.padEnd(width);
|
|
41
|
+
const printUpdates = (updates) => {
|
|
42
|
+
var _a;
|
|
43
|
+
const width = Math.max(...updates.map((update) => update.name.length));
|
|
44
|
+
for (const update of updates) {
|
|
45
|
+
const tag = update.tag ? ` (${update.tag})` : '';
|
|
46
|
+
console.log(` ${padded(update.name, width)} ${(_a = update.from) !== null && _a !== void 0 ? _a : 'not installed'} → ${update.to}${tag}`);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const problemsOf = (updates) => updates.flatMap((update) => update.unwritable.map((site) => `${site.manifestPath} declares ${update.name} as "${site.range}", which no single version can be ` +
|
|
50
|
+
`written into. Change it to ${update.to} by hand.`));
|
|
51
|
+
const resolveUpdates = (options) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
52
|
+
const { declared, version, tag } = options;
|
|
53
|
+
const registry = (0, registry_1.registryUrl)();
|
|
54
|
+
const result = { updates: [], problems: [], upToDate: [] };
|
|
55
|
+
const lookups = yield Promise.all(declared.map((entry) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
56
|
+
return ({
|
|
57
|
+
entry,
|
|
58
|
+
lookup: yield (0, registry_1.fetchRegistryPackage)({ packageName: entry.name, registry }),
|
|
59
|
+
});
|
|
60
|
+
})));
|
|
61
|
+
for (const { entry, lookup } of lookups) {
|
|
62
|
+
if (!lookup.ok) {
|
|
63
|
+
result.problems.push(`${entry.name}: ${lookup.reason}`);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const choice = (0, plan_1.chooseTarget)({ declared: entry, registry: lookup.package, request: { version, tag } });
|
|
67
|
+
if ('problem' in choice) {
|
|
68
|
+
result.problems.push(choice.problem);
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if ('upToDate' in choice) {
|
|
72
|
+
result.upToDate.push(entry.name);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
result.updates.push(choice.update);
|
|
76
|
+
}
|
|
77
|
+
return result;
|
|
78
|
+
});
|
|
79
|
+
const collectMigrations = (options) => {
|
|
80
|
+
var _a;
|
|
81
|
+
const { root, updates, from } = options;
|
|
82
|
+
const collected = { pending: [], notes: [], problems: [] };
|
|
83
|
+
for (const update of updates) {
|
|
84
|
+
const start = (_a = from[update.name]) !== null && _a !== void 0 ? _a : update.from;
|
|
85
|
+
if (start === undefined) {
|
|
86
|
+
collected.notes.push(`${update.name} was not installed before, so it has nothing to migrate.`);
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
const packageMigrations = (0, migration_manifest_1.readPackageMigrations)({ root, packageName: update.name });
|
|
90
|
+
collected.problems.push(...packageMigrations.problems);
|
|
91
|
+
collected.pending.push(...(0, plan_1.pendingMigrations)({ packageMigrations, from: start, to: update.to }));
|
|
92
|
+
}
|
|
93
|
+
collected.pending = (0, plan_1.orderMigrations)(collected.pending);
|
|
94
|
+
return collected;
|
|
95
|
+
};
|
|
96
|
+
const printMigrations = (pending) => {
|
|
97
|
+
for (const entry of pending) {
|
|
98
|
+
console.log(` ${entry.migration.version} ${entry.packageName} ${entry.migration.name} (${entry.migration.kind})`);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
const printOutcomes = (outcomes) => {
|
|
102
|
+
const applied = outcomes.filter((outcome) => outcome.state === 'applied').length;
|
|
103
|
+
const failed = outcomes.filter((outcome) => outcome.state === 'failed');
|
|
104
|
+
const tasks = outcomes.filter((outcome) => outcome.state === 'task' || outcome.state === 'unsupported').length;
|
|
105
|
+
console.log(`\n ${applied} codemod(s) applied, ${tasks} task(s) left, ${failed.length} failed`);
|
|
106
|
+
for (const outcome of failed) {
|
|
107
|
+
console.error(` - ${outcome.pending.packageName} ${outcome.pending.migration.name}: ${outcome.reason}`);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
const runMigrationPhase = (options) => {
|
|
111
|
+
const { root, manager, updates, from, dryRun, ai } = options;
|
|
112
|
+
const collected = collectMigrations({ root, updates, from });
|
|
113
|
+
for (const note of collected.notes)
|
|
114
|
+
console.log(` ${note}`);
|
|
115
|
+
for (const problem of collected.problems)
|
|
116
|
+
console.error(` ${problem}`);
|
|
117
|
+
if (collected.pending.length === 0) {
|
|
118
|
+
console.log('\nNo migration is pending for those versions.');
|
|
119
|
+
return { failed: collected.problems.length > 0 };
|
|
120
|
+
}
|
|
121
|
+
console.log(`\n${collected.pending.length} migration(s) to run:\n`);
|
|
122
|
+
printMigrations(collected.pending);
|
|
123
|
+
if (!(0, run_migrations_1.hasNx)(root)) {
|
|
124
|
+
console.log('\n This repo has no Nx, so every codemod is reported as a command to run by hand.');
|
|
125
|
+
}
|
|
126
|
+
const outcomes = (0, run_migrations_1.runPendingMigrations)({ root, manager, pending: collected.pending, dryRun });
|
|
127
|
+
printOutcomes(outcomes);
|
|
128
|
+
if (dryRun) {
|
|
129
|
+
console.log('\nDry run: no report was written.');
|
|
130
|
+
return { failed: false };
|
|
131
|
+
}
|
|
132
|
+
const written = (0, tasks_1.writeUpdateTasks)({
|
|
133
|
+
root,
|
|
134
|
+
updates,
|
|
135
|
+
outcomes,
|
|
136
|
+
manager,
|
|
137
|
+
generatedAt: new Date().toISOString(),
|
|
138
|
+
});
|
|
139
|
+
if (written.tasks.length > 0) {
|
|
140
|
+
console.log(`\n ${written.tasks.length} task(s) written to ${written.reportPath}`);
|
|
141
|
+
console.log(` The same list for an agent: ${written.dataPath}`);
|
|
142
|
+
}
|
|
143
|
+
if (ai) {
|
|
144
|
+
const template = (0, local_config_1.readLocalConfig)(root).config.updateAgentCommand;
|
|
145
|
+
const assisted = (0, ai_1.assistedTasks)(written.tasks);
|
|
146
|
+
if (assisted.length === 0)
|
|
147
|
+
console.log('\n --ai had nothing to do: no task is agent-assisted.');
|
|
148
|
+
else if (!template) {
|
|
149
|
+
console.error(`\n --ai needs "${ai_1.AGENT_COMMAND_KEY}" in ethlete.config.local.json, for example "claude -p".`);
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
const runs = (0, ai_1.runAgentTasks)({ root, template, tasks: written.tasks });
|
|
153
|
+
const failed = runs.filter((run) => !run.ok);
|
|
154
|
+
for (const run of failed)
|
|
155
|
+
console.error(` ${run.task.name}: ${run.reason}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return { failed: outcomes.some((outcome) => outcome.state === 'failed') || collected.problems.length > 0 };
|
|
159
|
+
};
|
|
160
|
+
const resume = (options) => {
|
|
161
|
+
var _a;
|
|
162
|
+
const { root, manager, argv } = options;
|
|
163
|
+
const pending = (0, pending_1.readPendingUpdate)(root);
|
|
164
|
+
if (!pending) {
|
|
165
|
+
console.error(`Nothing to continue: ${pending_1.PENDING_FILE} is not there.`);
|
|
166
|
+
return 1;
|
|
167
|
+
}
|
|
168
|
+
console.log(`\nContinuing the update started at ${pending.startedAt}:\n`);
|
|
169
|
+
const updates = pending.packages.map((entry) => {
|
|
170
|
+
var _a;
|
|
171
|
+
return ({
|
|
172
|
+
name: entry.name,
|
|
173
|
+
from: (_a = entry.from) !== null && _a !== void 0 ? _a : undefined,
|
|
174
|
+
to: entry.to,
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
for (const update of updates) {
|
|
178
|
+
console.log(` ${update.name} ${(_a = update.from) !== null && _a !== void 0 ? _a : 'not installed'} → ${update.to}`);
|
|
179
|
+
}
|
|
180
|
+
const result = runMigrationPhase({
|
|
181
|
+
root,
|
|
182
|
+
manager,
|
|
183
|
+
updates,
|
|
184
|
+
from: argv.from,
|
|
185
|
+
dryRun: argv.dryRun,
|
|
186
|
+
ai: argv.ai,
|
|
187
|
+
});
|
|
188
|
+
if (!result.failed && !argv.dryRun)
|
|
189
|
+
(0, pending_1.clearPendingUpdate)(root);
|
|
190
|
+
return result.failed ? 1 : 0;
|
|
191
|
+
};
|
|
192
|
+
/**
|
|
193
|
+
* Moves this repo's `@ethlete/*` dependencies to a newer version and runs the migrations those versions
|
|
194
|
+
* ship. Everything the codemods cannot decide is written to a task list under `.ethlete/update`.
|
|
195
|
+
*/
|
|
196
|
+
const updateCommand = (_a) => tslib_1.__awaiter(void 0, [_a], void 0, function* ({ argv, root = process.cwd(), invocation = 'et update', }) {
|
|
197
|
+
var _b;
|
|
198
|
+
const args = (0, args_1.parseUpdateArgs)(argv);
|
|
199
|
+
if (args.help) {
|
|
200
|
+
console.log(usage(invocation));
|
|
201
|
+
return 0;
|
|
202
|
+
}
|
|
203
|
+
if (args.problems.length > 0) {
|
|
204
|
+
console.error(`${args.problems.join('\n')}\n\n${usage(invocation)}`);
|
|
205
|
+
return 1;
|
|
206
|
+
}
|
|
207
|
+
const manifest = (0, packages_1.readManifest)(root);
|
|
208
|
+
if (!manifest) {
|
|
209
|
+
console.error(`${(0, packages_1.manifestPath)(root)} cannot be read, so there is nothing to update.`);
|
|
210
|
+
return 1;
|
|
211
|
+
}
|
|
212
|
+
const manager = (0, package_manager_1.detectPackageManager)({ root, manifest });
|
|
213
|
+
if (args.resume)
|
|
214
|
+
return resume({ root, manager, argv: args });
|
|
215
|
+
const manifests = (0, packages_1.findManifests)(root);
|
|
216
|
+
const all = (0, packages_1.declaredEthletePackages)({ root, manifests });
|
|
217
|
+
const named = args.packages.filter((name) => !all.some((entry) => entry.name === name));
|
|
218
|
+
if (named.length > 0) {
|
|
219
|
+
console.error(`This repo declares no ${named.join(', ')}.`);
|
|
220
|
+
return 1;
|
|
221
|
+
}
|
|
222
|
+
const declared = args.packages.length === 0 ? all : all.filter((entry) => args.packages.includes(entry.name));
|
|
223
|
+
if (declared.length === 0) {
|
|
224
|
+
console.log('This repo declares no @ethlete/* dependency.');
|
|
225
|
+
return 0;
|
|
226
|
+
}
|
|
227
|
+
const resolved = yield resolveUpdates({ declared, version: args.version, tag: args.tag });
|
|
228
|
+
for (const problem of resolved.problems)
|
|
229
|
+
console.error(` ${problem}`);
|
|
230
|
+
if (resolved.updates.length === 0) {
|
|
231
|
+
console.log(`\nEvery @ethlete package is on its newest version (${resolved.upToDate.length} checked).`);
|
|
232
|
+
return resolved.problems.length > 0 ? 1 : 0;
|
|
233
|
+
}
|
|
234
|
+
console.log('');
|
|
235
|
+
if (manifests.length > 1)
|
|
236
|
+
console.log(` ${manifests.length} package.json files scanned.\n`);
|
|
237
|
+
printUpdates(resolved.updates);
|
|
238
|
+
for (const update of resolved.updates.filter(plan_1.isDowngrade)) {
|
|
239
|
+
console.log(`\n ${update.name} moves back to ${update.to}, which is older than the installed ${update.from}.`);
|
|
240
|
+
}
|
|
241
|
+
const rangeProblems = problemsOf(resolved.updates);
|
|
242
|
+
for (const problem of rangeProblems)
|
|
243
|
+
console.error(`\n ${problem}`);
|
|
244
|
+
const writable = resolved.updates.filter((update) => update.writes.length > 0);
|
|
245
|
+
if (args.check) {
|
|
246
|
+
console.log(`\nRun \`${invocation}\` to apply this.`);
|
|
247
|
+
return 1;
|
|
248
|
+
}
|
|
249
|
+
if (args.dryRun) {
|
|
250
|
+
console.log('\nMigrations the installed versions know about. The target may ship more:\n');
|
|
251
|
+
printMigrations(collectMigrations({ root, updates: writable, from: args.from }).pending);
|
|
252
|
+
console.log('\nDry run: nothing was written.');
|
|
253
|
+
return 0;
|
|
254
|
+
}
|
|
255
|
+
if (writable.length === 0) {
|
|
256
|
+
console.error('\nNo range could be written. Nothing was changed.');
|
|
257
|
+
return 1;
|
|
258
|
+
}
|
|
259
|
+
if (!args.force && (0, git_1.hasUncommittedChanges)(root)) {
|
|
260
|
+
console.error('\nThe working tree has uncommitted changes, and the codemods rewrite files.\n' +
|
|
261
|
+
'Commit or stash them first, or re-run with --force.');
|
|
262
|
+
return 1;
|
|
263
|
+
}
|
|
264
|
+
const changedManifests = (0, packages_1.writeRanges)({ root, writes: writable.flatMap((update) => update.writes) });
|
|
265
|
+
(0, pending_1.writePendingUpdate)({
|
|
266
|
+
root,
|
|
267
|
+
pending: {
|
|
268
|
+
startedAt: new Date().toISOString(),
|
|
269
|
+
packages: writable.map((update) => { var _a; return ({ name: update.name, from: (_a = update.from) !== null && _a !== void 0 ? _a : null, to: update.to }); }),
|
|
270
|
+
},
|
|
271
|
+
});
|
|
272
|
+
const manifestNote = changedManifests.length === 1
|
|
273
|
+
? ((_b = changedManifests[0]) !== null && _b !== void 0 ? _b : packages_1.ROOT_MANIFEST)
|
|
274
|
+
: `${changedManifests.length} package.json files`;
|
|
275
|
+
console.log(`\n ${manifestNote} updated. The migration plan is in ${pending_1.PENDING_FILE}.`);
|
|
276
|
+
if (!args.install) {
|
|
277
|
+
console.log(`\nInstall the new versions, then run \`${invocation} --continue\`.`);
|
|
278
|
+
return 0;
|
|
279
|
+
}
|
|
280
|
+
console.log(`\n ${manager.install.join(' ')}\n`);
|
|
281
|
+
const installed = (0, run_migrations_1.runInstall)({ root, manager });
|
|
282
|
+
if (!installed.ok) {
|
|
283
|
+
console.error(`\nThe install failed: ${installed.reason}\n` +
|
|
284
|
+
`Fix it, then run \`${invocation} --continue\` to run the migrations.`);
|
|
285
|
+
return 1;
|
|
286
|
+
}
|
|
287
|
+
const result = runMigrationPhase({
|
|
288
|
+
root,
|
|
289
|
+
manager,
|
|
290
|
+
updates: writable,
|
|
291
|
+
from: args.from,
|
|
292
|
+
dryRun: false,
|
|
293
|
+
ai: args.ai,
|
|
294
|
+
});
|
|
295
|
+
if (result.failed) {
|
|
296
|
+
console.error(`\nRun \`${invocation} --continue\` again once the failures above are fixed.`);
|
|
297
|
+
return 1;
|
|
298
|
+
}
|
|
299
|
+
(0, pending_1.clearPendingUpdate)(root);
|
|
300
|
+
console.log(`\nDone. Read ${tasks_1.UPDATE_DIR} for anything left to do.`);
|
|
301
|
+
return rangeProblems.length > 0 ? 1 : 0;
|
|
302
|
+
});
|
|
303
|
+
exports.updateCommand = updateCommand;
|
|
304
|
+
//# sourceMappingURL=update-command.js.map
|