rman 2.0.0-beta.2 → 2.0.0-beta.4
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 +2 -12
- package/{plugins/node/augmentation/rman.augmentation.d.ts → builtins/platforms/node/augmentation/rmanrc.augmentation.d.ts} +4 -5
- package/{plugins → builtins/platforms}/node/augmentation/system-info.augmentation.js +1 -1
- package/{plugins → builtins/platforms}/node/commands/ci.command.d.ts +5 -3
- package/{plugins → builtins/platforms}/node/commands/ci.command.js +6 -5
- package/{plugins → builtins/platforms}/node/commands/clean.command.d.ts +6 -4
- package/{plugins → builtins/platforms}/node/commands/clean.command.js +6 -5
- package/builtins/platforms/node/index.d.ts +8 -0
- package/builtins/platforms/node/index.js +8 -0
- package/{plugins → builtins/platforms}/node/node-config.interface.d.ts +1 -2
- package/{plugins → builtins/platforms}/node/node-manifest.provider.d.ts +3 -3
- package/{plugins → builtins/platforms}/node/node-manifest.provider.js +3 -3
- package/{plugins → builtins/platforms}/node/node.platform.d.ts +3 -3
- package/{plugins → builtins/platforms}/node/services/ci.service.d.ts +3 -3
- package/{plugins → builtins/platforms}/node/services/ci.service.js +4 -4
- package/{plugins → builtins/platforms}/node/services/clean.service.d.ts +3 -3
- package/{plugins → builtins/platforms}/node/services/clean.service.js +3 -3
- package/{plugins → builtins/platforms}/node/services/publish.service.d.ts +4 -4
- package/{plugins → builtins/platforms}/node/services/publish.service.js +13 -7
- package/{plugins → builtins/platforms}/node/services/version-plan.service.d.ts +3 -3
- package/{plugins → builtins/platforms}/node/services/version-plan.service.js +2 -2
- package/builtins/presets/index.d.ts +15 -0
- package/builtins/presets/index.js +57 -0
- package/builtins/presets/node.d.ts +16 -0
- package/builtins/presets/node.js +57 -0
- package/{services → builtins/publish-targets/docker}/docker-publish.service.d.ts +6 -6
- package/{services → builtins/publish-targets/docker}/docker-publish.service.js +9 -9
- package/{targets → builtins/publish-targets/docker}/docker.target.d.ts +6 -5
- package/{targets → builtins/publish-targets/docker}/docker.target.js +1 -1
- package/builtins/publish-targets/docker/index.d.ts +2 -0
- package/builtins/publish-targets/docker/index.js +2 -0
- package/builtins/publish-targets/npm/index.d.ts +2 -0
- package/builtins/publish-targets/npm/index.js +2 -0
- package/{plugins/node → builtins/publish-targets/npm}/npm-publish-target.d.ts +4 -4
- package/{plugins/node → builtins/publish-targets/npm}/npm-publish-target.js +4 -5
- package/cli.d.ts +3 -0
- package/cli.js +16 -7
- package/commands/changelog.command.d.ts +106 -2
- package/commands/changelog.command.js +40 -0
- package/commands/config.command.js +23 -5
- package/commands/list.command.js +1 -1
- package/commands/publish.command.d.ts +1 -1
- package/commands/publish.command.js +1 -1
- package/commands/run.command.js +1 -1
- package/commands/version.command.d.ts +16 -3
- package/commands/version.command.js +143 -9
- package/commands.d.ts +0 -1
- package/commands.js +0 -1
- package/constants.js +1 -1
- package/core/application.d.ts +10 -10
- package/core/application.js +28 -11
- package/core/{package.d.ts → classes/package.d.ts} +12 -4
- package/core/{package.js → classes/package.js} +17 -1
- package/core/{repository.d.ts → classes/repository.d.ts} +22 -36
- package/core/{repository.js → classes/repository.js} +112 -241
- package/core/{service.d.ts → classes/service.d.ts} +2 -2
- package/core/classes/workspace.d.ts +277 -0
- package/core/classes/workspace.js +585 -0
- package/core/command-builder.js +17 -1
- package/core/config/config-file-scope.d.ts +107 -0
- package/core/config/config-file-scope.js +226 -0
- package/core/config/config-interpolator.d.ts +164 -0
- package/core/config/config-interpolator.js +577 -0
- package/core/config/config-paths.d.ts +65 -0
- package/core/config/config-paths.js +78 -0
- package/core/config/config-reader.d.ts +215 -0
- package/core/config/config-reader.js +851 -0
- package/core/{merge-config.js → config/merge-config.js} +4 -8
- package/core/{custom-command.d.ts → interfaces/custom-command.d.ts} +5 -5
- package/core/{manifest.d.ts → interfaces/manifest.d.ts} +3 -3
- package/core/{manifest.js → interfaces/manifest.js} +2 -2
- package/core/{plugin.d.ts → interfaces/plugin.d.ts} +44 -27
- package/core/{plugin.js → interfaces/plugin.js} +48 -10
- package/core/{publish-target.d.ts → interfaces/publish-target.d.ts} +24 -12
- package/core/{publish-target.js → interfaces/publish-target.js} +16 -3
- package/core/{run-step.d.ts → interfaces/run-step.d.ts} +4 -4
- package/core/plugin-loader.d.ts +11 -51
- package/core/plugin-loader.js +21 -202
- package/index.d.ts +29 -28
- package/index.js +20 -46
- package/interfaces/config-scope.interface.d.ts +223 -0
- package/interfaces/config-scope.interface.js +1 -0
- package/interfaces/rman-config.interface.d.ts +100 -5
- package/interfaces/rman-config.interface.js +17 -0
- package/package.json +3 -2
- package/services/change-hash.service.d.ts +40 -6
- package/services/change-hash.service.js +90 -11
- package/services/changelog.service.d.ts +31 -3
- package/services/changelog.service.js +448 -65
- package/services/config-service.d.ts +8 -0
- package/services/config-service.js +3 -0
- package/services/exec.service.d.ts +2 -2
- package/services/exec.service.js +1 -1
- package/services/github-release.service.d.ts +3 -3
- package/services/github-release.service.js +3 -3
- package/services/import.service.d.ts +2 -2
- package/services/import.service.js +1 -1
- package/services/list.service.d.ts +9 -7
- package/services/list.service.js +2 -2
- package/services/run.service.d.ts +15 -11
- package/services/run.service.js +62 -18
- package/services/system-info.d.ts +1 -1
- package/services/version-plan.service.d.ts +8 -4
- package/services/version-plan.service.js +54 -21
- package/services/version.service.d.ts +5 -5
- package/services/version.service.js +7 -4
- package/services.d.ts +1 -1
- package/services.js +1 -1
- package/utils/branch-guard.d.ts +1 -1
- package/utils/color-yaml.d.ts +8 -0
- package/utils/color-yaml.js +86 -0
- package/utils/git.d.ts +26 -0
- package/utils/git.js +65 -0
- package/utils/logger.d.ts +1 -1
- package/utils/package-filter.d.ts +8 -1
- package/utils/package-filter.js +7 -0
- package/utils/printable-config.d.ts +8 -0
- package/utils/printable-config.js +45 -0
- package/utils/progress-panel.d.ts +9 -0
- package/utils/progress-panel.js +23 -1
- package/utils/release-version.d.ts +1 -1
- package/utils/run-options.js +1 -1
- package/utils/version-group.d.ts +31 -0
- package/utils/version-group.js +43 -0
- package/commands/changed.command.d.ts +0 -80
- package/commands/changed.command.js +0 -36
- package/core/config.d.ts +0 -530
- package/core/config.js +0 -1123
- package/core/core-services.d.ts +0 -14
- package/core/core-services.js +0 -30
- package/core/core-targets.d.ts +0 -14
- package/core/core-targets.js +0 -16
- package/core/extends-config.d.ts +0 -35
- package/core/extends-config.js +0 -129
- package/core/load-config-module.d.ts +0 -28
- package/core/load-config-module.js +0 -42
- package/core/workspace.d.ts +0 -119
- package/core/workspace.js +0 -124
- package/plugins/builtins.d.ts +0 -44
- package/plugins/builtins.js +0 -33
- package/plugins/detect.d.ts +0 -78
- package/plugins/detect.js +0 -70
- package/plugins/node/index.d.ts +0 -29
- package/plugins/node/index.js +0 -40
- /package/{core/run-step.js → builtins/platforms/node/augmentation/rmanrc.augmentation.js} +0 -0
- /package/{plugins → builtins/platforms}/node/augmentation/system-info.augmentation.d.ts +0 -0
- /package/{plugins → builtins/platforms}/node/node-config.interface.js +0 -0
- /package/{plugins → builtins/platforms}/node/node.platform.js +0 -0
- /package/{plugins → builtins/platforms}/node/utils/workspace-range.d.ts +0 -0
- /package/{plugins → builtins/platforms}/node/utils/workspace-range.js +0 -0
- /package/{plugins/node/utils → builtins/publish-targets/npm}/npm-view.d.ts +0 -0
- /package/{plugins/node/utils → builtins/publish-targets/npm}/npm-view.js +0 -0
- /package/core/{registry.d.ts → classes/registry.d.ts} +0 -0
- /package/core/{registry.js → classes/registry.js} +0 -0
- /package/core/{service.js → classes/service.js} +0 -0
- /package/core/{version-scheme.d.ts → classes/version-scheme.d.ts} +0 -0
- /package/core/{version-scheme.js → classes/version-scheme.js} +0 -0
- /package/core/{merge-config.d.ts → config/merge-config.d.ts} +0 -0
- /package/core/{resolve-target.d.ts → config/resolve-config-target.d.ts} +0 -0
- /package/core/{resolve-target.js → config/resolve-config-target.js} +0 -0
- /package/core/{custom-command.js → interfaces/custom-command.js} +0 -0
- /package/{plugins/node/augmentation/rman.augmentation.js → core/interfaces/run-step.js} +0 -0
package/utils/git.js
CHANGED
|
@@ -148,6 +148,32 @@ export class GitHelper {
|
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
150
|
/** Whether `tag` exists as an exact git tag name (not a glob - a literal ref check). */
|
|
151
|
+
/**
|
|
152
|
+
* Every tag matching `pattern`, paired with the **commit** it points at - newest version first,
|
|
153
|
+
* the same order `listTags` returns.
|
|
154
|
+
*
|
|
155
|
+
* `%(*objectname)` is the dereferenced target and is empty for a lightweight tag, so the commit
|
|
156
|
+
* is that or `%(objectname)`. rman's own tags are lightweight; a repository's existing ones may
|
|
157
|
+
* not be, and an annotated tag's `objectname` is the *tag object*, which matches no commit and
|
|
158
|
+
* would make the tag silently invisible to anything comparing shas.
|
|
159
|
+
*/
|
|
160
|
+
async listTagCommits(pattern) {
|
|
161
|
+
try {
|
|
162
|
+
const { stdout } = await execFileAsync('git', ['tag', '--list', pattern, '--sort=-v:refname', '--format=%(refname:short)%09%(objectname)%09%(*objectname)'], { cwd: this.cwd });
|
|
163
|
+
return stdout
|
|
164
|
+
.trim()
|
|
165
|
+
.split(/\r?\n/)
|
|
166
|
+
.filter(Boolean)
|
|
167
|
+
.map(line => {
|
|
168
|
+
const [tag, objectname, deref] = line.split('\t');
|
|
169
|
+
return { tag, sha: deref || objectname };
|
|
170
|
+
})
|
|
171
|
+
.filter(t => t.tag && t.sha);
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
return [];
|
|
175
|
+
}
|
|
176
|
+
}
|
|
151
177
|
async tagExists(tag) {
|
|
152
178
|
try {
|
|
153
179
|
await execFileAsync('git', ['rev-parse', '--verify', '--quiet', `refs/tags/${tag}`], { cwd: this.cwd });
|
|
@@ -197,6 +223,45 @@ export class GitHelper {
|
|
|
197
223
|
/** The repository's very first commit (the oldest root commit, for a history with several) -
|
|
198
224
|
* `undefined` for a repository with no commits at all. The "since the beginning" boundary for
|
|
199
225
|
* a package being released for the first time, with no earlier tag to measure from. */
|
|
226
|
+
/** HEAD's own sha, or `undefined` in a repository with no commits yet (or none at all) - the
|
|
227
|
+
* same "answer nothing rather than throw" shape `rootCommit` and `describeTag` take, because
|
|
228
|
+
* every caller here already has a "nothing to go on" branch. */
|
|
229
|
+
/** The date a ref points at, as `YYYY-MM-DD`. The **committer** date, not the author's: a
|
|
230
|
+
* rebased or cherry-picked release commit was authored earlier than it shipped, and what a
|
|
231
|
+
* changelog heading states is when the release happened. `undefined` for a ref that resolves to
|
|
232
|
+
* nothing. */
|
|
233
|
+
async commitDate(ref) {
|
|
234
|
+
try {
|
|
235
|
+
const { stdout } = await execFileAsync('git', ['log', '-1', '--format=%cI', ref], { cwd: this.cwd });
|
|
236
|
+
return stdout.trim().slice(0, 10) || undefined;
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
return undefined;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
/** The commit `ref` names - a sha, a tag, a branch - or `undefined` when git does not recognize
|
|
243
|
+
* it. `^{commit}` so an annotated tag answers with the commit rather than the tag object, and
|
|
244
|
+
* so a tree or blob answers with nothing rather than a sha that matches no commit. */
|
|
245
|
+
async resolveCommit(ref) {
|
|
246
|
+
try {
|
|
247
|
+
const { stdout } = await execFileAsync('git', ['rev-parse', '--verify', '--quiet', `${ref}^{commit}`], {
|
|
248
|
+
cwd: this.cwd,
|
|
249
|
+
});
|
|
250
|
+
return stdout.trim() || undefined;
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
return undefined;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
async headSha() {
|
|
257
|
+
try {
|
|
258
|
+
const { stdout } = await execFileAsync('git', ['rev-parse', 'HEAD'], { cwd: this.cwd });
|
|
259
|
+
return stdout.trim() || undefined;
|
|
260
|
+
}
|
|
261
|
+
catch {
|
|
262
|
+
return undefined;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
200
265
|
async rootCommit() {
|
|
201
266
|
try {
|
|
202
267
|
const { stdout } = await execFileAsync('git', ['rev-list', '--max-parents=0', 'HEAD'], { cwd: this.cwd });
|
package/utils/logger.d.ts
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import type { Argv } from 'yargs';
|
|
2
|
-
import type { Package } from '../core/package.js';
|
|
2
|
+
import type { Package } from '../core/classes/package.js';
|
|
3
3
|
/** Shared by every command that iterates packages (`run`/`build`/`test`/`exec`, `list`, `ci`,
|
|
4
4
|
* `clean`, `version`, `publish`, `changelog`) - narrows *which* packages a command applies to,
|
|
5
5
|
* independent of what the command actually does to them. The repository's own standing filter,
|
|
6
6
|
* `.rmanrc "skip"`, is applied by `filterPackages` itself rather than being an option here: it is
|
|
7
7
|
* the repository's statement, not the caller's. */
|
|
8
8
|
export interface PackageFilterOptions {
|
|
9
|
+
/**
|
|
10
|
+
* The technologies the **command itself** is for - `clean` and `ci` are npm's alone. Absent means
|
|
11
|
+
* every platform, which is what a command that speaks for no one in particular says.
|
|
12
|
+
*
|
|
13
|
+
* Declared as `CommandMetadata.platforms` and carried here; a repository never writes it.
|
|
14
|
+
*/
|
|
15
|
+
commandPlatforms?: string[];
|
|
9
16
|
/** Only include packages whose name matches at least one of these globs (e.g. `@scope/*`), or
|
|
10
17
|
* **`"/"`** for the repository's own root package - see `ROOT_SELECTOR`. */
|
|
11
18
|
scope?: string | string[];
|
package/utils/package-filter.js
CHANGED
|
@@ -131,6 +131,7 @@ export function readPackageFilterOptions(args) {
|
|
|
131
131
|
scope: args.scope,
|
|
132
132
|
ignore: args.ignore,
|
|
133
133
|
platform: args.platform,
|
|
134
|
+
commandPlatforms: args.commandPlatforms,
|
|
134
135
|
deps: args.deps,
|
|
135
136
|
dependents: args.dependents,
|
|
136
137
|
};
|
|
@@ -169,6 +170,12 @@ applySkip = true) {
|
|
|
169
170
|
const selects = selector(options.ignore);
|
|
170
171
|
matched = matched.filter(p => !selects(p));
|
|
171
172
|
}
|
|
173
|
+
/** The command's own technologies, before the user's `--platform`: a declaration is the hard
|
|
174
|
+
* limit and the flag narrows inside it. Silent where `--platform` is loud - see the field. */
|
|
175
|
+
if (options.commandPlatforms?.length) {
|
|
176
|
+
const wanted = new Set(options.commandPlatforms.map(n => n.toLowerCase()));
|
|
177
|
+
matched = matched.filter(p => wanted.has(p.provider.toLowerCase()));
|
|
178
|
+
}
|
|
172
179
|
if (options.platform !== undefined) {
|
|
173
180
|
const wanted = platformNames(options.platform, packages);
|
|
174
181
|
matched = matched.filter(p => wanted.has(p.provider.toLowerCase()));
|
|
@@ -13,3 +13,11 @@
|
|
|
13
13
|
* reads as `[Function]`, which is itself worth seeing.
|
|
14
14
|
*/
|
|
15
15
|
export declare function printableConfig<T>(config: T): T;
|
|
16
|
+
/**
|
|
17
|
+
* A resolved config with the **contribution keys** dropped - `plugins`, `platforms`, `commands`,
|
|
18
|
+
* `publishTargets` - for `rman config` and `--config`, which exist to show what a repository is
|
|
19
|
+
* *configured* to do.
|
|
20
|
+
*
|
|
21
|
+
* Returns a copy; the config itself is what every command reads and is never touched.
|
|
22
|
+
*/
|
|
23
|
+
export declare function withoutContributions<T extends object>(config: T): T;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CODE_SUBTREES } from '../core/config/config-paths.js';
|
|
1
2
|
/**
|
|
2
3
|
* A copy of a resolved config with every value a serializer cannot represent replaced by a short
|
|
3
4
|
* description of it - for `rman config` and `--config`, which exist to be *looked at*.
|
|
@@ -15,6 +16,50 @@
|
|
|
15
16
|
export function printableConfig(config) {
|
|
16
17
|
return walk(config, new WeakSet());
|
|
17
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* A resolved config with the **contribution keys** dropped - `plugins`, `platforms`, `commands`,
|
|
21
|
+
* `publishTargets` - for `rman config` and `--config`, which exist to show what a repository is
|
|
22
|
+
* *configured* to do.
|
|
23
|
+
*
|
|
24
|
+
* Returns a copy; the config itself is what every command reads and is never touched.
|
|
25
|
+
*/
|
|
26
|
+
/* **Those four are code, not settings** (`CODE_SUBTREES`), and printing them answers a question
|
|
27
|
+
* nobody asked: a platform dumps its manifest provider and version planner, a publish target its
|
|
28
|
+
* whole option table, and `commands` comes out as a list of `[Function]` - which is the clearest
|
|
29
|
+
* evidence of all that they do not belong in this output. Measured on this repository, where
|
|
30
|
+
* `rman config` printed forty lines of the npm target's flags above the two keys its `.rmanrc`
|
|
31
|
+
* actually sets.
|
|
32
|
+
*
|
|
33
|
+
* **And silently, which was argued the other way first.** The note that announced them read as the
|
|
34
|
+
* sibling of the `version.<slot>` one, and it is not: that note explains a *visible* oddity - an
|
|
35
|
+
* unresolved `${{ }}` sitting among resolved values, which without it reads as interpolation being
|
|
36
|
+
* broken - while this one announced an absence the reader was not looking for. The measurement that
|
|
37
|
+
* settled it: presets go under every root, so every config carries all four and the note was
|
|
38
|
+
* printed **every time**, which makes it a banner rather than a report. At this repository's root
|
|
39
|
+
* it was one of three lines. A reader asking which technologies are loaded is asking `rman info`,
|
|
40
|
+
* and one asking whether their command registered is asking `rman --help`.
|
|
41
|
+
*
|
|
42
|
+
* **`CODE_SUBTREES` itself, not a second copy of those four names.** `config-paths.ts` imports
|
|
43
|
+
* nothing, so there is no cycle to buy by reaching for it - and a printer quietly keeping its own
|
|
44
|
+
* list is how a key added to one side stops being dropped by the other. That exact shape was live
|
|
45
|
+
* in this tree an hour earlier: `presetNames()` held a hardcoded `['node']` beside a resolver that
|
|
46
|
+
* looked somewhere else, and the error message named the preset it had just failed to find.
|
|
47
|
+
*
|
|
48
|
+
* **Top level only, matching the runtime rule** (`ConfigInterpolator._isCodePath` checks
|
|
49
|
+
* `segments[0]`). `Resolved` skips these names at *every* level because the selector index
|
|
50
|
+
* re-enters the config, and the two have disagreed since - this is not the place to pick a side,
|
|
51
|
+
* and stripping them deeper would hide a script that happens to be called `commands`. By the time
|
|
52
|
+
* either printer runs the selector blocks are merged in anyway, so there is no deeper one to find.
|
|
53
|
+
*
|
|
54
|
+
* **Distinct from `printableConfig`, which makes a value serializable rather than deciding what is
|
|
55
|
+
* worth showing.** A step written as a function still prints as `[Function: copyDocs]` - that one
|
|
56
|
+
* *is* a setting. */
|
|
57
|
+
export function withoutContributions(config) {
|
|
58
|
+
const result = { ...config };
|
|
59
|
+
for (const key of CODE_SUBTREES)
|
|
60
|
+
delete result[key];
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
18
63
|
function walk(value, seen) {
|
|
19
64
|
if (typeof value === 'function')
|
|
20
65
|
return `[Function${value.name ? `: ${value.name}` : ''}]`;
|
|
@@ -6,6 +6,15 @@ export interface ProgressItem {
|
|
|
6
6
|
/** Label of the step currently running, for work with more than one step (e.g. `run`'s
|
|
7
7
|
* npm-script steps) - omit `stepsTotal` entirely for single-step work like a plain command. */
|
|
8
8
|
currentStep?: string;
|
|
9
|
+
/**
|
|
10
|
+
* **What the current step actually runs** - the shell command, or a function step's name - shown
|
|
11
|
+
* beside the label so a silent step says what it is.
|
|
12
|
+
*
|
|
13
|
+
* The label alone answers "which slot", which is what a reader already knows; a step sitting at
|
|
14
|
+
* `before (2/9)` for ten seconds with nothing on stdout is the case this exists for, and it is
|
|
15
|
+
* the common one for a build.
|
|
16
|
+
*/
|
|
17
|
+
currentCommand?: string;
|
|
9
18
|
stepIndex?: number;
|
|
10
19
|
stepsTotal?: number;
|
|
11
20
|
/** Last captured output line, shown dimmed under the item while it's running. */
|
package/utils/progress-panel.js
CHANGED
|
@@ -76,7 +76,15 @@ export class ProgressPanel {
|
|
|
76
76
|
const step = item.stepsTotal && item.stepsTotal > 1 && item.stepIndex != null
|
|
77
77
|
? `${item.currentStep} (${item.stepIndex + 1}/${item.stepsTotal})`
|
|
78
78
|
: item.currentStep || '';
|
|
79
|
-
|
|
79
|
+
/** Measured against the *plain* text: every piece below is wrapped in escape sequences, and
|
|
80
|
+
* `String.length` counts those, so budgeting on the rendered string wraps a row that fits. */
|
|
81
|
+
const fixed = ` ${item.name} ${step} ${elapsed}`.length;
|
|
82
|
+
const command = truncate(item.currentCommand ?? '', (process.stdout.columns || 80) - fixed - 2);
|
|
83
|
+
const group = [
|
|
84
|
+
`${spinner} ${colors.bold(item.name)} ${colors.gray(step)}` +
|
|
85
|
+
(command ? ` ${colors.cyan(command)}` : '') +
|
|
86
|
+
` ${colors.yellow(elapsed)}`,
|
|
87
|
+
];
|
|
80
88
|
if (item.lastLine)
|
|
81
89
|
group.push(` ${colors.dim(item.lastLine)}`);
|
|
82
90
|
if (used + group.length > budget)
|
|
@@ -141,6 +149,20 @@ export class ProgressPanel {
|
|
|
141
149
|
return { successCount, failedCount, skippedCount };
|
|
142
150
|
}
|
|
143
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* `text` cut to `width`, with a `…` in place of what was dropped.
|
|
154
|
+
*
|
|
155
|
+
* **Cut from the end, not the middle.** A command's information is front-loaded - `tsc -b
|
|
156
|
+
* packages/rman/tsconfig.json` says what it is in the first four characters, and a middle-ellipsis
|
|
157
|
+
* spends them on a tail nobody is reading at a glance. The one thing it must never do is wrap: a
|
|
158
|
+
* block taller than the terminal breaks the panel's cursor-up arithmetic, which is the same reason
|
|
159
|
+
* the row budget above exists.
|
|
160
|
+
*/
|
|
161
|
+
function truncate(text, width) {
|
|
162
|
+
if (!text || width <= 1)
|
|
163
|
+
return '';
|
|
164
|
+
return text.length <= width ? text : `${text.slice(0, width - 1)}…`;
|
|
165
|
+
}
|
|
144
166
|
/** Classic braille "dots" spinner (cli-spinners' default), one frame per render tick. */
|
|
145
167
|
const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
146
168
|
function renderProgressBar(done, total, width = 24) {
|
package/utils/run-options.js
CHANGED
|
@@ -53,7 +53,7 @@ export const runOptions = {
|
|
|
53
53
|
changed: {
|
|
54
54
|
target: 'cli',
|
|
55
55
|
alias: 'c',
|
|
56
|
-
describe: 'Only run in packages
|
|
56
|
+
describe: 'Only run in packages you have touched but not pushed - uncommitted, or committed and not yet on the upstream branch. Not a release question; see "version --json" for that',
|
|
57
57
|
type: 'boolean',
|
|
58
58
|
},
|
|
59
59
|
changedSince: {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Package } from '../core/classes/package.js';
|
|
2
|
+
/**
|
|
3
|
+
* The identity packages are batched by when `version` plans a release - `.rmanrc group`, cascaded
|
|
4
|
+
* like every unmarked key. `true` (the default) puts a package in the implicit repo-wide group, a
|
|
5
|
+
* non-empty string joins exactly the packages naming the same one, and `false` makes it a group of
|
|
6
|
+
* itself.
|
|
7
|
+
*
|
|
8
|
+
* **It lives here rather than on the planner because two unrelated things need the same answer.**
|
|
9
|
+
* `VersionPlanService.resolveGroupKey` batches the plan with it; `ChangeHashService.tagPattern`
|
|
10
|
+
* asks how many lines the repository releases along, which decides whether a repo-wide tag can
|
|
11
|
+
* name a release at all. Two copies of five lines would be easy to write and impossible to keep in
|
|
12
|
+
* step, and the failure they would produce is silent - a boundary computed under one answer and a
|
|
13
|
+
* tag written under the other.
|
|
14
|
+
*
|
|
15
|
+
* `resolveGroupKey` stays `protected` and delegates here, so a planner can still override the
|
|
16
|
+
* batching; what it cannot do is leave the tag pattern behind, which is the point.
|
|
17
|
+
*/
|
|
18
|
+
export declare function groupKeyOf(pkg: Package): string;
|
|
19
|
+
/**
|
|
20
|
+
* How many distinct version lines this package's repository releases along - 1 when every package
|
|
21
|
+
* moves together, more once anything is grouped apart.
|
|
22
|
+
*
|
|
23
|
+
* **Structural, exactly like `usesCalendarVersion`'s group count**, and for the same reason: two
|
|
24
|
+
* lines can hold the same number today and diverge tomorrow, so reading the versions would move
|
|
25
|
+
* the answer under the repository's feet.
|
|
26
|
+
*
|
|
27
|
+
* `1` for a package belonging to no repository yet - a bare `new Package(dir, app)`, which the test
|
|
28
|
+
* fixtures build. One line is the answer that changes nothing, which is what an unknown should
|
|
29
|
+
* resolve to here.
|
|
30
|
+
*/
|
|
31
|
+
export declare function versionLineCount(pkg: Package): number;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The identity packages are batched by when `version` plans a release - `.rmanrc group`, cascaded
|
|
3
|
+
* like every unmarked key. `true` (the default) puts a package in the implicit repo-wide group, a
|
|
4
|
+
* non-empty string joins exactly the packages naming the same one, and `false` makes it a group of
|
|
5
|
+
* itself.
|
|
6
|
+
*
|
|
7
|
+
* **It lives here rather than on the planner because two unrelated things need the same answer.**
|
|
8
|
+
* `VersionPlanService.resolveGroupKey` batches the plan with it; `ChangeHashService.tagPattern`
|
|
9
|
+
* asks how many lines the repository releases along, which decides whether a repo-wide tag can
|
|
10
|
+
* name a release at all. Two copies of five lines would be easy to write and impossible to keep in
|
|
11
|
+
* step, and the failure they would produce is silent - a boundary computed under one answer and a
|
|
12
|
+
* tag written under the other.
|
|
13
|
+
*
|
|
14
|
+
* `resolveGroupKey` stays `protected` and delegates here, so a planner can still override the
|
|
15
|
+
* batching; what it cannot do is leave the tag pattern behind, which is the point.
|
|
16
|
+
*/
|
|
17
|
+
export function groupKeyOf(pkg) {
|
|
18
|
+
const g = pkg.config?.group;
|
|
19
|
+
if (g === false)
|
|
20
|
+
return `solo:${pkg.name}`;
|
|
21
|
+
if (typeof g === 'string' && g)
|
|
22
|
+
return `named:${g}`;
|
|
23
|
+
return 'default';
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* How many distinct version lines this package's repository releases along - 1 when every package
|
|
27
|
+
* moves together, more once anything is grouped apart.
|
|
28
|
+
*
|
|
29
|
+
* **Structural, exactly like `usesCalendarVersion`'s group count**, and for the same reason: two
|
|
30
|
+
* lines can hold the same number today and diverge tomorrow, so reading the versions would move
|
|
31
|
+
* the answer under the repository's feet.
|
|
32
|
+
*
|
|
33
|
+
* `1` for a package belonging to no repository yet - a bare `new Package(dir, app)`, which the test
|
|
34
|
+
* fixtures build. One line is the answer that changes nothing, which is what an unknown should
|
|
35
|
+
* resolve to here.
|
|
36
|
+
*/
|
|
37
|
+
export function versionLineCount(pkg) {
|
|
38
|
+
const repository = pkg.repository;
|
|
39
|
+
const packages = repository?.packages;
|
|
40
|
+
if (!packages?.length)
|
|
41
|
+
return 1;
|
|
42
|
+
return new Set(packages.map(groupKeyOf)).size;
|
|
43
|
+
}
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { type RmanConfig } from '../interfaces/rman-config.interface.js';
|
|
2
|
-
declare const COMMAND: "changed";
|
|
3
|
-
declare const config: {
|
|
4
|
-
json: {
|
|
5
|
-
target: "cli";
|
|
6
|
-
alias: string;
|
|
7
|
-
describe: string;
|
|
8
|
-
type: "boolean";
|
|
9
|
-
};
|
|
10
|
-
scope: {
|
|
11
|
-
target: "cli";
|
|
12
|
-
describe: string;
|
|
13
|
-
type: "string";
|
|
14
|
-
};
|
|
15
|
-
ignore: {
|
|
16
|
-
target: "cli";
|
|
17
|
-
describe: string;
|
|
18
|
-
type: "string";
|
|
19
|
-
};
|
|
20
|
-
platform: {
|
|
21
|
-
target: "cli";
|
|
22
|
-
describe: string;
|
|
23
|
-
type: "string";
|
|
24
|
-
};
|
|
25
|
-
deps: {
|
|
26
|
-
target: "cli";
|
|
27
|
-
describe: string;
|
|
28
|
-
type: "boolean";
|
|
29
|
-
};
|
|
30
|
-
dependents: {
|
|
31
|
-
target: "cli";
|
|
32
|
-
describe: string;
|
|
33
|
-
type: "boolean";
|
|
34
|
-
};
|
|
35
|
-
};
|
|
36
|
-
type Args = RmanConfig.ArgsOf<typeof config, typeof COMMAND>;
|
|
37
|
-
/** Declares no `target: 'config'` option, so it contributes nothing to `RmanConfig` and writes no
|
|
38
|
-
* augmentation - a command that owns no config key simply has none. */
|
|
39
|
-
declare const changedCommand: (app: import("../index.js").RmanApplication) => {
|
|
40
|
-
command: "changed";
|
|
41
|
-
describe: string;
|
|
42
|
-
config: {
|
|
43
|
-
json: {
|
|
44
|
-
target: "cli";
|
|
45
|
-
alias: string;
|
|
46
|
-
describe: string;
|
|
47
|
-
type: "boolean";
|
|
48
|
-
};
|
|
49
|
-
scope: {
|
|
50
|
-
target: "cli";
|
|
51
|
-
describe: string;
|
|
52
|
-
type: "string";
|
|
53
|
-
};
|
|
54
|
-
ignore: {
|
|
55
|
-
target: "cli";
|
|
56
|
-
describe: string;
|
|
57
|
-
type: "string";
|
|
58
|
-
};
|
|
59
|
-
platform: {
|
|
60
|
-
target: "cli";
|
|
61
|
-
describe: string;
|
|
62
|
-
type: "string";
|
|
63
|
-
};
|
|
64
|
-
deps: {
|
|
65
|
-
target: "cli";
|
|
66
|
-
describe: string;
|
|
67
|
-
type: "boolean";
|
|
68
|
-
};
|
|
69
|
-
dependents: {
|
|
70
|
-
target: "cli";
|
|
71
|
-
describe: string;
|
|
72
|
-
type: "boolean";
|
|
73
|
-
};
|
|
74
|
-
};
|
|
75
|
-
examples: {
|
|
76
|
-
command: string;
|
|
77
|
-
}[];
|
|
78
|
-
handler: (args: Args) => Promise<void>;
|
|
79
|
-
};
|
|
80
|
-
export default changedCommand;
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import colors from 'ansi-colors';
|
|
2
|
-
import { registerCommand } from '../interfaces/rman-config.interface.js';
|
|
3
|
-
import { VersionPlanService } from '../services/version-plan.service.js';
|
|
4
|
-
import { packageFilterOptions, readPackageFilterOptions } from '../utils/package-filter.js';
|
|
5
|
-
const COMMAND = 'changed';
|
|
6
|
-
const config = {
|
|
7
|
-
...packageFilterOptions,
|
|
8
|
-
json: { target: 'cli', alias: 'j', describe: 'Print output as JSON', type: 'boolean' },
|
|
9
|
-
};
|
|
10
|
-
/** Declares no `target: 'config'` option, so it contributes nothing to `RmanConfig` and writes no
|
|
11
|
-
* augmentation - a command that owns no config key simply has none. */
|
|
12
|
-
const changedCommand = registerCommand(app => {
|
|
13
|
-
const repository = app.repository;
|
|
14
|
-
return {
|
|
15
|
-
command: COMMAND,
|
|
16
|
-
describe: 'Shows which packages the next "version" run would bump, without changing anything',
|
|
17
|
-
config,
|
|
18
|
-
examples: [{ command: '$0 changed' }, { command: '$0 changed --json' }],
|
|
19
|
-
handler: async (args) => {
|
|
20
|
-
const plan = await VersionPlanService.getPlanner(app).getPlan(repository, readPackageFilterOptions(args));
|
|
21
|
-
const changed = plan.filter(e => e.status === 'bump');
|
|
22
|
-
if (args.json) {
|
|
23
|
-
console.log(JSON.stringify(changed.map(e => ({ name: e.package.name, group: e.group, from: e.from, to: e.to, reason: e.reason })), undefined, 2));
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
if (!changed.length) {
|
|
27
|
-
console.log(colors.gray('Nothing has changed.'));
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
for (const e of changed) {
|
|
31
|
-
console.log(colors.green('changed'), colors.cyan(e.package.name), colors.gray(`(${e.group})`), e.from, '->', colors.yellow(e.to));
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
};
|
|
35
|
-
});
|
|
36
|
-
export default changedCommand;
|