rman 1.3.0 → 2.0.0-beta.3
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 +65 -31
- package/builtins/platforms/node/augmentation/rmanrc.augmentation.d.ts +83 -0
- package/builtins/platforms/node/augmentation/system-info.augmentation.d.ts +26 -0
- package/builtins/platforms/node/augmentation/system-info.augmentation.js +79 -0
- package/builtins/platforms/node/commands/ci.command.d.ts +133 -0
- package/builtins/platforms/node/commands/ci.command.js +60 -0
- package/builtins/platforms/node/commands/clean.command.d.ts +185 -0
- package/builtins/platforms/node/commands/clean.command.js +74 -0
- package/builtins/platforms/node/index.d.ts +8 -0
- package/builtins/platforms/node/index.js +8 -0
- package/builtins/platforms/node/node-config.interface.d.ts +76 -0
- package/builtins/platforms/node/node-config.interface.js +7 -0
- package/builtins/platforms/node/node-manifest.provider.d.ts +68 -0
- package/builtins/platforms/node/node-manifest.provider.js +125 -0
- package/builtins/platforms/node/node.platform.d.ts +53 -0
- package/builtins/platforms/node/node.platform.js +134 -0
- package/builtins/platforms/node/services/ci.service.d.ts +47 -0
- package/builtins/platforms/node/services/ci.service.js +213 -0
- package/builtins/platforms/node/services/clean.service.d.ts +53 -0
- package/builtins/platforms/node/services/clean.service.js +237 -0
- package/builtins/platforms/node/services/publish.service.d.ts +114 -0
- package/builtins/platforms/node/services/publish.service.js +371 -0
- package/builtins/platforms/node/services/version-plan.service.d.ts +44 -0
- package/builtins/platforms/node/services/version-plan.service.js +58 -0
- package/builtins/platforms/node/utils/workspace-range.d.ts +26 -0
- package/builtins/platforms/node/utils/workspace-range.js +28 -0
- 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 +52 -31
- package/{services → builtins/publish-targets/docker}/docker-publish.service.js +49 -26
- package/builtins/publish-targets/docker/docker.target.d.ts +54 -0
- package/builtins/publish-targets/docker/docker.target.js +40 -0
- 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/builtins/publish-targets/npm/npm-publish-target.d.ts +73 -0
- package/builtins/publish-targets/npm/npm-publish-target.js +95 -0
- package/builtins/publish-targets/npm/npm-view.d.ts +48 -0
- package/builtins/publish-targets/npm/npm-view.js +71 -0
- package/cli.d.ts +8 -0
- package/cli.js +228 -93
- package/commands/build.command.d.ts +177 -3
- package/commands/build.command.js +20 -10
- package/commands/changelog.command.d.ts +296 -3
- package/commands/changelog.command.js +127 -43
- package/commands/config.command.d.ts +44 -3
- package/commands/config.command.js +53 -24
- package/commands/diff.command.d.ts +37 -3
- package/commands/diff.command.js +25 -16
- package/commands/exec.command.d.ts +193 -3
- package/commands/exec.command.js +60 -58
- package/commands/github-release.command.d.ts +154 -3
- package/commands/github-release.command.js +67 -37
- package/commands/import.command.d.ts +36 -3
- package/commands/import.command.js +28 -20
- package/commands/info.command.d.ts +35 -7
- package/commands/info.command.js +36 -30
- package/commands/lint.command.d.ts +176 -0
- package/commands/lint.command.js +34 -0
- package/commands/list.command.d.ts +163 -3
- package/commands/list.command.js +109 -71
- package/commands/publish.command.d.ts +231 -0
- package/commands/publish.command.js +304 -0
- package/commands/run.command.d.ts +186 -6
- package/commands/run.command.js +26 -72
- package/commands/test.command.d.ts +173 -3
- package/commands/test.command.js +16 -10
- package/commands/version.command.d.ts +330 -3
- package/commands/version.command.js +292 -78
- package/commands.d.ts +32 -0
- package/commands.js +28 -0
- package/constants.js +1 -1
- package/core/application.d.ts +116 -0
- package/core/application.js +160 -0
- package/core/classes/package.d.ts +219 -0
- package/core/classes/package.js +214 -0
- package/core/classes/registry.d.ts +30 -0
- package/core/classes/registry.js +47 -0
- package/core/{repository.d.ts → classes/repository.d.ts} +69 -20
- package/core/{repository.js → classes/repository.js} +195 -75
- package/core/classes/service.d.ts +49 -0
- package/core/classes/service.js +40 -0
- package/core/{version-scheme.d.ts → classes/version-scheme.d.ts} +23 -1
- package/core/{version-scheme.js → classes/version-scheme.js} +29 -1
- package/core/classes/workspace.d.ts +275 -0
- package/core/classes/workspace.js +537 -0
- package/core/command-builder.d.ts +14 -0
- package/core/command-builder.js +94 -0
- 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 +192 -0
- package/core/config/config-reader.js +727 -0
- package/core/{merge-config.d.ts → config/merge-config.d.ts} +33 -34
- package/core/config/merge-config.js +260 -0
- package/core/{resolve-target.d.ts → config/resolve-config-target.d.ts} +1 -1
- package/core/{resolve-target.js → config/resolve-config-target.js} +1 -1
- package/core/{custom-command.d.ts → interfaces/custom-command.d.ts} +46 -10
- package/core/{custom-command.js → interfaces/custom-command.js} +44 -17
- package/core/{manifest.d.ts → interfaces/manifest.d.ts} +49 -27
- package/core/interfaces/manifest.js +132 -0
- package/core/interfaces/plugin.d.ts +174 -0
- package/core/interfaces/plugin.js +124 -0
- package/core/interfaces/publish-target.d.ts +136 -0
- package/core/interfaces/publish-target.js +43 -0
- package/core/{run-step.d.ts → interfaces/run-step.d.ts} +4 -4
- package/core/interfaces/run-step.js +1 -0
- package/core/plugin-loader.d.ts +25 -0
- package/core/plugin-loader.js +53 -0
- package/index.d.ts +122 -24
- package/index.js +66 -16
- package/interfaces/config-scope.interface.d.ts +223 -0
- package/interfaces/config-scope.interface.js +1 -0
- package/interfaces/rman-config.interface.d.ts +821 -203
- package/interfaces/rman-config.interface.js +78 -1
- package/package.json +3 -1
- package/services/change-hash.service.d.ts +42 -8
- package/services/change-hash.service.js +92 -13
- package/services/changelog.service.d.ts +91 -52
- package/services/changelog.service.js +460 -74
- package/services/config-service.d.ts +8 -0
- package/services/config-service.js +3 -0
- package/services/exec.service.d.ts +23 -12
- package/services/exec.service.js +14 -9
- package/services/github-release.service.d.ts +45 -34
- package/services/github-release.service.js +15 -12
- package/services/import.service.d.ts +25 -14
- package/services/import.service.js +9 -5
- package/services/list.service.d.ts +67 -13
- package/services/list.service.js +62 -15
- package/services/run.service.d.ts +35 -22
- package/services/run.service.js +316 -233
- package/services/system-info.d.ts +1 -1
- package/services/version-plan.service.d.ts +35 -8
- package/services/version-plan.service.js +96 -36
- package/services/version.service.d.ts +34 -14
- package/services/version.service.js +35 -16
- package/services.d.ts +1 -1
- package/services.js +1 -1
- package/utils/bin-path.d.ts +6 -7
- package/utils/bin-path.js +7 -18
- package/utils/branch-guard.d.ts +30 -1
- package/utils/branch-guard.js +31 -0
- package/utils/color-yaml.d.ts +8 -0
- package/utils/color-yaml.js +86 -0
- package/utils/exec.d.ts +10 -0
- package/utils/exec.js +1 -1
- package/utils/git.d.ts +26 -0
- package/utils/git.js +65 -0
- package/utils/logger.d.ts +2 -2
- package/utils/logger.js +1 -1
- package/utils/package-filter.d.ts +135 -8
- package/utils/package-filter.js +204 -16
- package/utils/printable-config.d.ts +9 -1
- package/utils/printable-config.js +46 -1
- 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-bin.d.ts +10 -0
- package/utils/run-bin.js +1 -1
- package/utils/run-options.d.ts +97 -0
- package/utils/run-options.js +81 -0
- package/utils/version-group.d.ts +31 -0
- package/utils/version-group.js +43 -0
- package/utils/version-stamp.d.ts +1 -1
- package/utils/version-stamp.js +1 -1
- package/commands/changed.command.d.ts +0 -3
- package/commands/changed.command.js +0 -29
- package/core/config.d.ts +0 -409
- package/core/config.js +0 -939
- package/core/extends-config.d.ts +0 -27
- package/core/extends-config.js +0 -89
- package/core/manifest.js +0 -150
- package/core/merge-config.js +0 -219
- package/core/package.d.ts +0 -83
- package/core/package.js +0 -106
- package/core/plugin.d.ts +0 -112
- package/core/plugin.js +0 -189
- package/core/workspace.d.ts +0 -68
- package/core/workspace.js +0 -83
- /package/{core/run-step.js → builtins/platforms/node/augmentation/rmanrc.augmentation.js} +0 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import type { ArgsOf } from '../../../../index.js';
|
|
2
|
+
import type { ConfigValue } from '../../../../interfaces/rman-config.interface.js';
|
|
3
|
+
/** Hoisted for `ArgsOf` - see `ci.command.ts` and `RmanConfig.ArgsOf`. */
|
|
4
|
+
declare const COMMAND: "clean";
|
|
5
|
+
declare const config: {
|
|
6
|
+
progress: {
|
|
7
|
+
target: "cli";
|
|
8
|
+
describe: string;
|
|
9
|
+
type: "boolean";
|
|
10
|
+
};
|
|
11
|
+
dryRun: {
|
|
12
|
+
target: "cli";
|
|
13
|
+
cliName: string;
|
|
14
|
+
describe: string;
|
|
15
|
+
type: "boolean";
|
|
16
|
+
};
|
|
17
|
+
/** Config-only: `.rmanrc "clean.skip"` excludes a package from `clean` entirely. Not a flag -
|
|
18
|
+
* a single run narrows with `--scope`/`--ignore`, which every command already has. */
|
|
19
|
+
skip: {
|
|
20
|
+
target: "config";
|
|
21
|
+
describe: string;
|
|
22
|
+
type: "boolean";
|
|
23
|
+
};
|
|
24
|
+
fromRoot: {
|
|
25
|
+
target: "cli";
|
|
26
|
+
cliName: string;
|
|
27
|
+
alias: string;
|
|
28
|
+
describe: string;
|
|
29
|
+
type: "boolean";
|
|
30
|
+
};
|
|
31
|
+
allowBranch: {
|
|
32
|
+
target: "cli";
|
|
33
|
+
cliName: string;
|
|
34
|
+
describe: string;
|
|
35
|
+
type: "string";
|
|
36
|
+
};
|
|
37
|
+
ignoreBranch: {
|
|
38
|
+
target: "cli";
|
|
39
|
+
cliName: string;
|
|
40
|
+
describe: string;
|
|
41
|
+
type: "string";
|
|
42
|
+
};
|
|
43
|
+
scope: {
|
|
44
|
+
target: "cli";
|
|
45
|
+
describe: string;
|
|
46
|
+
type: "string";
|
|
47
|
+
};
|
|
48
|
+
ignore: {
|
|
49
|
+
target: "cli";
|
|
50
|
+
describe: string;
|
|
51
|
+
type: "string";
|
|
52
|
+
};
|
|
53
|
+
platform: {
|
|
54
|
+
target: "cli";
|
|
55
|
+
describe: string;
|
|
56
|
+
type: "string";
|
|
57
|
+
};
|
|
58
|
+
deps: {
|
|
59
|
+
target: "cli";
|
|
60
|
+
describe: string;
|
|
61
|
+
type: "boolean";
|
|
62
|
+
};
|
|
63
|
+
dependents: {
|
|
64
|
+
target: "cli";
|
|
65
|
+
describe: string;
|
|
66
|
+
type: "boolean";
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* The rest of `clean.*` - the two keys an option cannot describe.
|
|
71
|
+
*
|
|
72
|
+
* `include`/`exclude` are each **a glob or a list of them**, and a `CommandOption` says one or the
|
|
73
|
+
* other: `type: 'string'` is a string, `array: true` beside it is a `string[]`. Neither is the
|
|
74
|
+
* union, and the union is what a config author actually writes (`include: 'build'` as often as
|
|
75
|
+
* `include: ['build', '*.tsbuildinfo']`). So they are written out and intersected in, which is what
|
|
76
|
+
* `Extra` is for - `skip` above is an ordinary option and is derived like everything else.
|
|
77
|
+
*/
|
|
78
|
+
export interface CleanExtraKeys {
|
|
79
|
+
/** Extra files and directories to remove, beyond TypeScript's own output - globs relative to
|
|
80
|
+
* each package's own directory. Per-package cascaded; a package declaring its own `clean` block
|
|
81
|
+
* replaces the root's entirely for itself, rather than combining with it. */
|
|
82
|
+
include?: ConfigValue<string | string[]>;
|
|
83
|
+
/** Globs to keep, applied after `include`. */
|
|
84
|
+
exclude?: ConfigValue<string | string[]>;
|
|
85
|
+
}
|
|
86
|
+
type Args = ArgsOf<typeof config, typeof COMMAND>;
|
|
87
|
+
/**
|
|
88
|
+
* `rman clean` - contributed by the `node` built-in rather than always present, because what
|
|
89
|
+
* it deletes is TypeScript's output. See `CleanService.clean`.
|
|
90
|
+
*
|
|
91
|
+
* Declared the same way `ci` is - see that file for why a plugin uses `declareCommand` rather than
|
|
92
|
+
* `registerCommand`.
|
|
93
|
+
*/
|
|
94
|
+
export declare const cleanCommand: (app: import("../../../../index.js").RmanApplication) => {
|
|
95
|
+
command: "clean";
|
|
96
|
+
/** npm's alone: it deletes TypeScript build output, which no other ecosystem has. */
|
|
97
|
+
platforms: string[];
|
|
98
|
+
describe: string;
|
|
99
|
+
/**
|
|
100
|
+
* **No `configKeys`, because `clean` is this command's *own* key now** - derived from the
|
|
101
|
+
* `config` block above and contributed to `RmanConfig` by `CommandContribution`, exactly as a
|
|
102
|
+
* built-in contributes its own. It used to be hand-written in `NodeConfigKeys` *and* named
|
|
103
|
+
* here, which is two statements about one key.
|
|
104
|
+
*
|
|
105
|
+
* **The contribution itself is in `augmentation/rman.augmentation.ts`, not here**, and that is
|
|
106
|
+
* not a stylistic choice: one `declare module 'rman'` block per package is the limit, and a
|
|
107
|
+
* second silently disables the first. Measured again while moving this - a second block left
|
|
108
|
+
* `SystemInfo.PackageManager` unresolved at four call sites, with nothing pointing at the
|
|
109
|
+
* cause. rman's own commands declare theirs beside themselves because they augment a *module
|
|
110
|
+
* path*, which has no such limit.
|
|
111
|
+
*/
|
|
112
|
+
config: {
|
|
113
|
+
progress: {
|
|
114
|
+
target: "cli";
|
|
115
|
+
describe: string;
|
|
116
|
+
type: "boolean";
|
|
117
|
+
};
|
|
118
|
+
dryRun: {
|
|
119
|
+
target: "cli";
|
|
120
|
+
cliName: string;
|
|
121
|
+
describe: string;
|
|
122
|
+
type: "boolean";
|
|
123
|
+
};
|
|
124
|
+
/** Config-only: `.rmanrc "clean.skip"` excludes a package from `clean` entirely. Not a flag -
|
|
125
|
+
* a single run narrows with `--scope`/`--ignore`, which every command already has. */
|
|
126
|
+
skip: {
|
|
127
|
+
target: "config";
|
|
128
|
+
describe: string;
|
|
129
|
+
type: "boolean";
|
|
130
|
+
};
|
|
131
|
+
fromRoot: {
|
|
132
|
+
target: "cli";
|
|
133
|
+
cliName: string;
|
|
134
|
+
alias: string;
|
|
135
|
+
describe: string;
|
|
136
|
+
type: "boolean";
|
|
137
|
+
};
|
|
138
|
+
allowBranch: {
|
|
139
|
+
target: "cli";
|
|
140
|
+
cliName: string;
|
|
141
|
+
describe: string;
|
|
142
|
+
type: "string";
|
|
143
|
+
};
|
|
144
|
+
ignoreBranch: {
|
|
145
|
+
target: "cli";
|
|
146
|
+
cliName: string;
|
|
147
|
+
describe: string;
|
|
148
|
+
type: "string";
|
|
149
|
+
};
|
|
150
|
+
scope: {
|
|
151
|
+
target: "cli";
|
|
152
|
+
describe: string;
|
|
153
|
+
type: "string";
|
|
154
|
+
};
|
|
155
|
+
ignore: {
|
|
156
|
+
target: "cli";
|
|
157
|
+
describe: string;
|
|
158
|
+
type: "string";
|
|
159
|
+
};
|
|
160
|
+
platform: {
|
|
161
|
+
target: "cli";
|
|
162
|
+
describe: string;
|
|
163
|
+
type: "string";
|
|
164
|
+
};
|
|
165
|
+
deps: {
|
|
166
|
+
target: "cli";
|
|
167
|
+
describe: string;
|
|
168
|
+
type: "boolean";
|
|
169
|
+
};
|
|
170
|
+
dependents: {
|
|
171
|
+
target: "cli";
|
|
172
|
+
describe: string;
|
|
173
|
+
type: "boolean";
|
|
174
|
+
};
|
|
175
|
+
};
|
|
176
|
+
examples: ({
|
|
177
|
+
command: string;
|
|
178
|
+
description?: undefined;
|
|
179
|
+
} | {
|
|
180
|
+
command: string;
|
|
181
|
+
description: string;
|
|
182
|
+
})[];
|
|
183
|
+
handler: (args: Args) => Promise<void>;
|
|
184
|
+
};
|
|
185
|
+
export {};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { declareCommand } from '../../../../interfaces/rman-config.interface.js';
|
|
2
|
+
import { assertAllowedBranch, branchGuardOptions, readBranchGuardOptions } from '../../../../utils/branch-guard.js';
|
|
3
|
+
import { fromRootOption, packageFilterOptions, readPackageFilterOptions } from '../../../../utils/package-filter.js';
|
|
4
|
+
import { CleanService } from '../services/clean.service.js';
|
|
5
|
+
/** Hoisted for `ArgsOf` - see `ci.command.ts` and `RmanConfig.ArgsOf`. */
|
|
6
|
+
const COMMAND = 'clean';
|
|
7
|
+
const config = {
|
|
8
|
+
...packageFilterOptions,
|
|
9
|
+
...branchGuardOptions,
|
|
10
|
+
/** A group of one, and a function because its text is this command's own word for what it does. */
|
|
11
|
+
...fromRootOption('Clean'),
|
|
12
|
+
progress: {
|
|
13
|
+
target: 'cli',
|
|
14
|
+
describe: 'Show a live progress panel (default: true; auto-disabled when not a TTY)',
|
|
15
|
+
type: 'boolean',
|
|
16
|
+
},
|
|
17
|
+
dryRun: {
|
|
18
|
+
target: 'cli',
|
|
19
|
+
cliName: 'dry-run',
|
|
20
|
+
describe: 'Report what would be removed without actually removing anything',
|
|
21
|
+
type: 'boolean',
|
|
22
|
+
},
|
|
23
|
+
/** Config-only: `.rmanrc "clean.skip"` excludes a package from `clean` entirely. Not a flag -
|
|
24
|
+
* a single run narrows with `--scope`/`--ignore`, which every command already has. */
|
|
25
|
+
skip: {
|
|
26
|
+
target: 'config',
|
|
27
|
+
describe: 'Excludes this package from clean entirely',
|
|
28
|
+
type: 'boolean',
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* `rman clean` - contributed by the `node` built-in rather than always present, because what
|
|
33
|
+
* it deletes is TypeScript's output. See `CleanService.clean`.
|
|
34
|
+
*
|
|
35
|
+
* Declared the same way `ci` is - see that file for why a plugin uses `declareCommand` rather than
|
|
36
|
+
* `registerCommand`.
|
|
37
|
+
*/
|
|
38
|
+
export const cleanCommand = declareCommand(app => {
|
|
39
|
+
const repository = app.repository;
|
|
40
|
+
return {
|
|
41
|
+
command: COMMAND,
|
|
42
|
+
/** npm's alone: it deletes TypeScript build output, which no other ecosystem has. */
|
|
43
|
+
platforms: ['node'],
|
|
44
|
+
describe: 'Removes compiled TypeScript output and any extra files/dirs configured via .rmanrc "clean"',
|
|
45
|
+
/**
|
|
46
|
+
* **No `configKeys`, because `clean` is this command's *own* key now** - derived from the
|
|
47
|
+
* `config` block above and contributed to `RmanConfig` by `CommandContribution`, exactly as a
|
|
48
|
+
* built-in contributes its own. It used to be hand-written in `NodeConfigKeys` *and* named
|
|
49
|
+
* here, which is two statements about one key.
|
|
50
|
+
*
|
|
51
|
+
* **The contribution itself is in `augmentation/rman.augmentation.ts`, not here**, and that is
|
|
52
|
+
* not a stylistic choice: one `declare module 'rman'` block per package is the limit, and a
|
|
53
|
+
* second silently disables the first. Measured again while moving this - a second block left
|
|
54
|
+
* `SystemInfo.PackageManager` unresolved at four call sites, with nothing pointing at the
|
|
55
|
+
* cause. rman's own commands declare theirs beside themselves because they augment a *module
|
|
56
|
+
* path*, which has no such limit.
|
|
57
|
+
*/
|
|
58
|
+
config,
|
|
59
|
+
examples: [
|
|
60
|
+
{ command: '$0 clean' },
|
|
61
|
+
{ command: '$0 clean --dry-run', description: '# Preview what would be removed' },
|
|
62
|
+
],
|
|
63
|
+
handler: async (args) => {
|
|
64
|
+
await assertAllowedBranch(repository, readBranchGuardOptions(args));
|
|
65
|
+
await CleanService.clean(repository, {
|
|
66
|
+
...readPackageFilterOptions(args),
|
|
67
|
+
progress: args.progress,
|
|
68
|
+
dryRun: args.dryRun,
|
|
69
|
+
fromRoot: args.fromRoot,
|
|
70
|
+
logLevel: args.logLevel,
|
|
71
|
+
});
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './augmentation/rmanrc.augmentation.js';
|
|
2
|
+
export * from './augmentation/system-info.augmentation.js';
|
|
3
|
+
export * from './commands/ci.command.js';
|
|
4
|
+
export * from './commands/clean.command.js';
|
|
5
|
+
export * from './node.platform.js';
|
|
6
|
+
export * from './node-config.interface.js';
|
|
7
|
+
export * from './node-manifest.provider.js';
|
|
8
|
+
export * from './utils/workspace-range.js';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './augmentation/rmanrc.augmentation.js';
|
|
2
|
+
export * from './augmentation/system-info.augmentation.js';
|
|
3
|
+
export * from './commands/ci.command.js';
|
|
4
|
+
export * from './commands/clean.command.js';
|
|
5
|
+
export * from './node.platform.js';
|
|
6
|
+
export * from './node-config.interface.js';
|
|
7
|
+
export * from './node-manifest.provider.js';
|
|
8
|
+
export * from './utils/workspace-range.js';
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { ConfigValue, RmanConfig, ScopedVars } from '../../../interfaces/rman-config.interface.js';
|
|
2
|
+
import type { CiService } from './services/ci.service.js';
|
|
3
|
+
/**
|
|
4
|
+
* The `.rmanrc` keys that only mean something because the repository is a Node one.
|
|
5
|
+
*
|
|
6
|
+
* **One key, and it is here because no single command owns it**: `packageManager` is read by `ci`
|
|
7
|
+
* *and* by the `npm` publish target, so neither can contribute it. Everything else this package
|
|
8
|
+
* adds to `.rmanrc` is declared by whoever reads it - `clean.*` by `clean.command.ts` (through
|
|
9
|
+
* `CommandContribution`), `publish.npm.*` by the target, below.
|
|
10
|
+
*
|
|
11
|
+
* **Two surfaces, and they are not alternatives:**
|
|
12
|
+
*
|
|
13
|
+
* - the `declare module 'rman'` block in [`../augmentation/rman.augmentation.ts`] merges this into
|
|
14
|
+
* `RmanConfigKeys`, so `repository.config.packageManager` stays typed wherever it is read with no
|
|
15
|
+
* cast. It lives there because one such block per package is the limit;
|
|
16
|
+
* - `RmanNodeConfig` is the name a *config author* annotates with, which is what makes the import
|
|
17
|
+
* carrying that augmentation explicit instead of a side effect someone has to remember.
|
|
18
|
+
*/
|
|
19
|
+
export interface NodeConfigKeys {
|
|
20
|
+
/**
|
|
21
|
+
* Which package manager `ci`/`publish` shell out to, and whose version `info` reports under
|
|
22
|
+
* `Binaries`. Root level only. Default `npm`.
|
|
23
|
+
*
|
|
24
|
+
* It used to be a core key, on the grounds that `info` read it - and that stopped being true the
|
|
25
|
+
* moment `SystemInfo`'s npm half moved here: measured, **nothing in rman's core reads it at
|
|
26
|
+
* all**, only the declaration was left behind. The value set was npm's tooling the whole time.
|
|
27
|
+
*/
|
|
28
|
+
packageManager?: CiService.PackageManager;
|
|
29
|
+
}
|
|
30
|
+
export declare namespace RmanNodeConfig {
|
|
31
|
+
/**
|
|
32
|
+
* **`publish.npm.*`** - the `npm` publish target's own block, contributed through the
|
|
33
|
+
* `PublishTargetConfigs` slot rman's `publish` command exports for any target.
|
|
34
|
+
*
|
|
35
|
+
* Named after the target, the way `publish.docker.*` already was. It used to be `publish.directory`
|
|
36
|
+
* - a bare key sitting directly beside `target`, `skip` and `docker`, so the one block that was
|
|
37
|
+
* *not* a target's read as though it belonged to publishing in general. `target` and `skip` are
|
|
38
|
+
* genuinely `publish`'s own; `directory` never was.
|
|
39
|
+
*/
|
|
40
|
+
interface NpmPublishOptions extends NpmPublishOptionsKeys, ScopedVars {
|
|
41
|
+
}
|
|
42
|
+
interface NpmPublishOptionsKeys {
|
|
43
|
+
/** Where this package's publishable output lives, relative to its own directory (e.g.
|
|
44
|
+
* `"build"`). Per-package cascaded, so a root `"[*]"` block can say it once for the whole
|
|
45
|
+
* repository instead of repeating `publishConfig.directory` in every `package.json` - which
|
|
46
|
+
* still wins when a package declares it, being the more specific statement.
|
|
47
|
+
*
|
|
48
|
+
* Publishing from such a directory means the manifest there is **generated by `publish`**,
|
|
49
|
+
* from the package's own - see `PublishService`. There is nothing to configure about it. */
|
|
50
|
+
directory?: ConfigValue<string>;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* `.rmanrc` for a repository using this plugin: rman's own keys plus the ones above.
|
|
55
|
+
*
|
|
56
|
+
* ```js
|
|
57
|
+
* // .rmanrc.mjs
|
|
58
|
+
* import { defineConfig } from 'rman';
|
|
59
|
+
*
|
|
60
|
+
* export default defineConfig({
|
|
61
|
+
* plugins: ['node'],
|
|
62
|
+
* '[*]': { clean: { include: 'build' }, publish: { npm: { directory: 'build' } } },
|
|
63
|
+
* });
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* `.mjs`, not `.ts`: rman loads `.rmanrc.cjs`/`.mjs`/`.js` and no TypeScript form, so the type
|
|
67
|
+
* reaches a config file through the editor rather than through a compiler. The JSON and YAML forms
|
|
68
|
+
* carry no type at all - since the JSON Schema was removed, they are unchecked.
|
|
69
|
+
*/
|
|
70
|
+
export interface RmanNodeConfig extends RmanConfig {
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Identity helper for authoring a `.rmanrc.mjs`/`.cjs`/`.js` config with this plugin's keys checked
|
|
74
|
+
* - rman's own `defineConfig` with a narrower parameter, nothing more. Returns `config` unchanged.
|
|
75
|
+
*/
|
|
76
|
+
export declare function defineConfig(config: RmanNodeConfig): RmanNodeConfig;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity helper for authoring a `.rmanrc.mjs`/`.cjs`/`.js` config with this plugin's keys checked
|
|
3
|
+
* - rman's own `defineConfig` with a narrower parameter, nothing more. Returns `config` unchanged.
|
|
4
|
+
*/
|
|
5
|
+
export function defineConfig(config) {
|
|
6
|
+
return config;
|
|
7
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { Package } from '../../../core/classes/package.js';
|
|
2
|
+
import type { ManifestProvider } from '../../../core/interfaces/manifest.js';
|
|
3
|
+
import { Manifest } from '../../../core/interfaces/manifest.js';
|
|
4
|
+
export declare class NodeManifestProvider implements ManifestProvider {
|
|
5
|
+
name: string;
|
|
6
|
+
fileName: string;
|
|
7
|
+
read(dir: string): Manifest | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* npm's four dependency fields, and only the entries naming a package of this repository -
|
|
10
|
+
* an external dependency is not an edge in rman's graph.
|
|
11
|
+
*
|
|
12
|
+
* Matched by name, which is npm's own identifier and unique by construction; an ecosystem where
|
|
13
|
+
* that does not hold resolves its own way, which is why this is the provider's job.
|
|
14
|
+
*/
|
|
15
|
+
dependencies(manifest: Manifest, candidates: readonly Package[]): Package[];
|
|
16
|
+
/** npm's `@scope/name`. A name with no `/` has no scope and is its own unscoped form; the
|
|
17
|
+
* *last* `/` splits it, so `@scope/a/b` keeps `@scope/a` as the scope the registry would. */
|
|
18
|
+
splitName(name: string): {
|
|
19
|
+
scope?: string;
|
|
20
|
+
unscopedName: string;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Rewrites a sibling's range in all four fields after it was bumped.
|
|
24
|
+
*
|
|
25
|
+
* **A bare `"workspace:*"`/`"^"`/`"~"` selector is left alone**, and that is the load-bearing
|
|
26
|
+
* case: it resolves to the dependency's *current* version at publish time (see
|
|
27
|
+
* `resolveWorkspaceRange`), so rewriting it would replace a live reference with a frozen one.
|
|
28
|
+
* Only an explicit version after `workspace:` needs bumping, like a plain range.
|
|
29
|
+
*/
|
|
30
|
+
updateDependencyVersions(manifest: Manifest, bumped: ReadonlyMap<Package, string>): void;
|
|
31
|
+
/**
|
|
32
|
+
* What the npm registry says this package's current version is - used *only* by
|
|
33
|
+
* `detectChangeHash`, to guess a tag name for a package that has no git tag yet. See
|
|
34
|
+
* `Plugin.publishedVersion` for why that is not a "has this been published" check.
|
|
35
|
+
*
|
|
36
|
+
* No `--registry`/`--userconfig`: a bare `npm view` run in the package's own directory already
|
|
37
|
+
* honours the repository's `.npmrc`, and the flags exist for `publish`'s CLI overrides, which
|
|
38
|
+
* this path has none of.
|
|
39
|
+
*/
|
|
40
|
+
publishedVersion(pkg: Package): Promise<string | undefined>;
|
|
41
|
+
/**
|
|
42
|
+
* npm's source shape: a quoted string assigned to an identifier, which is what a `.ts`/`.js`
|
|
43
|
+
* version constant looks like. `constant` comes from the repository's own `version.stamp` entry,
|
|
44
|
+
* for a file whose identifier is not literally `version`.
|
|
45
|
+
*
|
|
46
|
+
* One line, because `stampVersionConstant` is exported for it - the *pattern* is shared by most
|
|
47
|
+
* languages, while *choosing* it is this ecosystem's call. A provider for a format with no
|
|
48
|
+
* identifier at all (a `pom.xml`) would ignore `constant` and match its own way.
|
|
49
|
+
*/
|
|
50
|
+
stampVersion(file: string, content: string, version: string, options?: {
|
|
51
|
+
constant?: string;
|
|
52
|
+
}): string | undefined;
|
|
53
|
+
write(dir: string, manifest: Manifest): void;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* `package.json` as rman's manifest: where an npm package's name and version are written.
|
|
57
|
+
*
|
|
58
|
+
* This is the deepest npm assumption that used to be in rman's core - `Package.name`,
|
|
59
|
+
* `Package.version`, `Package.json` and `Package.isPrivate` all read this file directly, which
|
|
60
|
+
* meant every command that asked a package what it was called was asking npm.
|
|
61
|
+
*
|
|
62
|
+
* The version scheme is left unset, so packages get the core's semver default: npm versions *are*
|
|
63
|
+
* semver, and saying so again here would only be a second place for the two to disagree.
|
|
64
|
+
*/
|
|
65
|
+
export declare const packageJsonManifest: {};
|
|
66
|
+
/** npm's four dependency fields. Was `rman`'s `DEPENDENCY_KEYS`, which made the core carry npm's
|
|
67
|
+
* field names - `publish` imports it from here now. */
|
|
68
|
+
export declare const DEPENDENCY_KEYS: readonly ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { Manifest } from '../../../core/interfaces/manifest.js';
|
|
4
|
+
import { stampVersionConstant } from '../../../utils/version-stamp.js';
|
|
5
|
+
import { npmViewVersion } from '../../publish-targets/npm/npm-view.js';
|
|
6
|
+
import { parseWorkspaceRange } from './utils/workspace-range.js';
|
|
7
|
+
export class NodeManifestProvider {
|
|
8
|
+
name = 'node';
|
|
9
|
+
fileName = 'package.json';
|
|
10
|
+
read(dir) {
|
|
11
|
+
const file = path.join(dir, 'package.json');
|
|
12
|
+
if (!fs.existsSync(file))
|
|
13
|
+
return undefined;
|
|
14
|
+
const raw = JSON.parse(fs.readFileSync(file, 'utf-8'));
|
|
15
|
+
return {
|
|
16
|
+
/** A `package.json` with no `name` is unusual but legal, and `info` prints such a package
|
|
17
|
+
* rather than refusing it - so the directory name stands in, as it does for a package with
|
|
18
|
+
* no manifest at all. */
|
|
19
|
+
name: typeof raw?.name === 'string' && raw.name ? raw.name : path.basename(dir),
|
|
20
|
+
version: typeof raw?.version === 'string' && raw.version ? raw.version : '0.0.0',
|
|
21
|
+
private: !!raw?.private,
|
|
22
|
+
raw: raw ?? {},
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* npm's four dependency fields, and only the entries naming a package of this repository -
|
|
27
|
+
* an external dependency is not an edge in rman's graph.
|
|
28
|
+
*
|
|
29
|
+
* Matched by name, which is npm's own identifier and unique by construction; an ecosystem where
|
|
30
|
+
* that does not hold resolves its own way, which is why this is the provider's job.
|
|
31
|
+
*/
|
|
32
|
+
dependencies(manifest, candidates) {
|
|
33
|
+
const declared = Object.assign({}, ...DEPENDENCY_KEYS.map(key => manifest.raw[key]));
|
|
34
|
+
const byName = new Map(candidates.map(p => [p.name, p]));
|
|
35
|
+
const result = [];
|
|
36
|
+
for (const name of Object.keys(declared)) {
|
|
37
|
+
const pkg = byName.get(name);
|
|
38
|
+
if (pkg && !result.includes(pkg))
|
|
39
|
+
result.push(pkg);
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
/** npm's `@scope/name`. A name with no `/` has no scope and is its own unscoped form; the
|
|
44
|
+
* *last* `/` splits it, so `@scope/a/b` keeps `@scope/a` as the scope the registry would. */
|
|
45
|
+
splitName(name) {
|
|
46
|
+
const at = name.lastIndexOf('/');
|
|
47
|
+
return at > 0 ? { scope: name.slice(0, at), unscopedName: name.slice(at + 1) } : { unscopedName: name };
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Rewrites a sibling's range in all four fields after it was bumped.
|
|
51
|
+
*
|
|
52
|
+
* **A bare `"workspace:*"`/`"^"`/`"~"` selector is left alone**, and that is the load-bearing
|
|
53
|
+
* case: it resolves to the dependency's *current* version at publish time (see
|
|
54
|
+
* `resolveWorkspaceRange`), so rewriting it would replace a live reference with a frozen one.
|
|
55
|
+
* Only an explicit version after `workspace:` needs bumping, like a plain range.
|
|
56
|
+
*/
|
|
57
|
+
updateDependencyVersions(manifest, bumped) {
|
|
58
|
+
const versionByName = new Map([...bumped].map(([pkg, version]) => [pkg.name, version]));
|
|
59
|
+
for (const depKey of DEPENDENCY_KEYS) {
|
|
60
|
+
const deps = manifest.raw[depKey];
|
|
61
|
+
if (!deps)
|
|
62
|
+
continue;
|
|
63
|
+
for (const depName of Object.keys(deps)) {
|
|
64
|
+
const to = versionByName.get(depName);
|
|
65
|
+
if (!to)
|
|
66
|
+
continue;
|
|
67
|
+
const workspace = parseWorkspaceRange(deps[depName]);
|
|
68
|
+
if (workspace) {
|
|
69
|
+
if (workspace.selector === 'explicit')
|
|
70
|
+
deps[depName] = `workspace:^${to}`;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
deps[depName] = '^' + to;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* What the npm registry says this package's current version is - used *only* by
|
|
79
|
+
* `detectChangeHash`, to guess a tag name for a package that has no git tag yet. See
|
|
80
|
+
* `Plugin.publishedVersion` for why that is not a "has this been published" check.
|
|
81
|
+
*
|
|
82
|
+
* No `--registry`/`--userconfig`: a bare `npm view` run in the package's own directory already
|
|
83
|
+
* honours the repository's `.npmrc`, and the flags exist for `publish`'s CLI overrides, which
|
|
84
|
+
* this path has none of.
|
|
85
|
+
*/
|
|
86
|
+
publishedVersion(pkg) {
|
|
87
|
+
return npmViewVersion(pkg.name, pkg.dirname);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* npm's source shape: a quoted string assigned to an identifier, which is what a `.ts`/`.js`
|
|
91
|
+
* version constant looks like. `constant` comes from the repository's own `version.stamp` entry,
|
|
92
|
+
* for a file whose identifier is not literally `version`.
|
|
93
|
+
*
|
|
94
|
+
* One line, because `stampVersionConstant` is exported for it - the *pattern* is shared by most
|
|
95
|
+
* languages, while *choosing* it is this ecosystem's call. A provider for a format with no
|
|
96
|
+
* identifier at all (a `pom.xml`) would ignore `constant` and match its own way.
|
|
97
|
+
*/
|
|
98
|
+
stampVersion(file, content, version, options) {
|
|
99
|
+
return stampVersionConstant(content, version, options?.constant);
|
|
100
|
+
}
|
|
101
|
+
write(dir, manifest) {
|
|
102
|
+
/**
|
|
103
|
+
* The version is written back into `raw` before serializing, because `raw` is the document and
|
|
104
|
+
* `manifest.version` is rman's view of one field in it. Writing only the view would produce a
|
|
105
|
+
* file whose `version` never changed; writing only `raw` would leave the two disagreeing for
|
|
106
|
+
* anything still holding the manifest.
|
|
107
|
+
*/
|
|
108
|
+
const raw = { ...manifest.raw, version: manifest.version };
|
|
109
|
+
fs.writeFileSync(path.join(dir, 'package.json'), JSON.stringify(raw, undefined, 2) + '\n', 'utf-8');
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* `package.json` as rman's manifest: where an npm package's name and version are written.
|
|
114
|
+
*
|
|
115
|
+
* This is the deepest npm assumption that used to be in rman's core - `Package.name`,
|
|
116
|
+
* `Package.version`, `Package.json` and `Package.isPrivate` all read this file directly, which
|
|
117
|
+
* meant every command that asked a package what it was called was asking npm.
|
|
118
|
+
*
|
|
119
|
+
* The version scheme is left unset, so packages get the core's semver default: npm versions *are*
|
|
120
|
+
* semver, and saying so again here would only be a second place for the two to disagree.
|
|
121
|
+
*/
|
|
122
|
+
export const packageJsonManifest = {};
|
|
123
|
+
/** npm's four dependency fields. Was `rman`'s `DEPENDENCY_KEYS`, which made the core carry npm's
|
|
124
|
+
* field names - `publish` imports it from here now. */
|
|
125
|
+
export const DEPENDENCY_KEYS = ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies'];
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Package } from '../../../core/classes/package.js';
|
|
2
|
+
import type { Platform } from '../../../core/interfaces/plugin.js';
|
|
3
|
+
import type { RunService } from '../../../services/run.service.js';
|
|
4
|
+
import { NodeManifestProvider } from './node-manifest.provider.js';
|
|
5
|
+
import { NodeVersionPlanService } from './services/version-plan.service.js';
|
|
6
|
+
export declare class NodePlatform implements Platform {
|
|
7
|
+
/** The ecosystem, not the file - this is what every package it reads reports as
|
|
8
|
+
* `pkg.provider === 'node'`. `manifestProvider.fileName` already says `package.json`. */
|
|
9
|
+
name: string;
|
|
10
|
+
manifestProvider: NodeManifestProvider;
|
|
11
|
+
versionPlanner: NodeVersionPlanService;
|
|
12
|
+
/**
|
|
13
|
+
* npm's `workspaces` globs, resolved against `dir` - the directories directly below it that hold
|
|
14
|
+
* a `package.json`.
|
|
15
|
+
*
|
|
16
|
+
* **Asked of every directory the walk reaches, not only of the repository root**, which is what
|
|
17
|
+
* the seam changing from a layout to a per-directory question bought: a `package.json` naming
|
|
18
|
+
* `workspaces` is a workspace root wherever it sits, so a Node sub-workspace inside a larger
|
|
19
|
+
* repository is now found by the same code that finds the top one. `deep: 0` already made the
|
|
20
|
+
* globs one level, so nothing here had to change to make that true.
|
|
21
|
+
*/
|
|
22
|
+
getWorkspace(dir: string): string[] | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* Teaches `run` about `package.json#scripts`.
|
|
25
|
+
*
|
|
26
|
+
* rman's core resolves a script from `.rmanrc` alone - `before`/`exec`/`after`. That a script might
|
|
27
|
+
* *also* live in `package.json`, that `prebuild` and `postbuild` run around `build`, and that
|
|
28
|
+
* `a && b` is two steps rather than one, are all facts about npm, so they are here.
|
|
29
|
+
*
|
|
30
|
+
* Registered as a `RunService` step source rather than by wrapping anything: the npm part of `run`
|
|
31
|
+
* is inside step resolution, not at its entry point, so there is nothing a wrapper could reach.
|
|
32
|
+
* The core decides what to do with what this returns - see `getScriptSteps` for the precedence.
|
|
33
|
+
*/
|
|
34
|
+
getRunSteps(pkg: Package, script: string): RunService.ScriptSlots | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* Where npm puts a repository's locally installed executables: `node_modules/.bin`, at **every**
|
|
37
|
+
* level from `cwd` up to the filesystem root - which is how npm itself resolves a binary, so a
|
|
38
|
+
* package's `eslint` is found whether it was installed in that package or hoisted to the workspace
|
|
39
|
+
* root.
|
|
40
|
+
*
|
|
41
|
+
* Adapted from [npm-run-path](https://github.com/sindresorhus/npm-run-path), and it used to sit in
|
|
42
|
+
* rman's core. It is npm's directory layout from end to end: a Cargo or Go repository has no
|
|
43
|
+
* `node_modules` to walk, and nothing here would ever fire for it.
|
|
44
|
+
*
|
|
45
|
+
* **The running `node`'s own directory goes last**, after the walk, and its position is
|
|
46
|
+
* load-bearing. It is there so a script calling `node` gets the interpreter rman itself runs on
|
|
47
|
+
* rather than whatever the shell would pick. It also puts rman's own bin directory ahead of the
|
|
48
|
+
* inherited PATH, which is a measured trap: a nested `rman` invocation inside a `run` script
|
|
49
|
+
* resolves to the globally installed one, not to the repository's. Shim it in
|
|
50
|
+
* `<root>/node_modules/.bin` when that has to be overridden - the walk above reaches there first.
|
|
51
|
+
*/
|
|
52
|
+
getBinPaths(cwd: string): string[];
|
|
53
|
+
}
|