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
|
@@ -1,6 +1,22 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Service } from '../core/classes/service.js';
|
|
2
2
|
import { type LogLevel } from '../utils/logger.js';
|
|
3
3
|
import { type PackageFilterOptions } from '../utils/package-filter.js';
|
|
4
|
+
/**
|
|
5
|
+
* A service class - see `ListService` for the shape and `Service` for the three measured
|
|
6
|
+
* consequences a namespace had. `repository` left the signature because the application carries it.
|
|
7
|
+
*/
|
|
8
|
+
export declare class ExecService extends Service {
|
|
9
|
+
/**
|
|
10
|
+
* `exec`: runs `command` (an arbitrary shell command, not an npm script) directly in every
|
|
11
|
+
* matching package's own directory - unlike `run`, there's no `package.json` script to resolve
|
|
12
|
+
* and no `pre<script>`/`post<script>` npm lifecycle convention to honor, since the command isn't
|
|
13
|
+
* tied to any script name at all. Everything else about how packages are selected and scheduled
|
|
14
|
+
* matches `run`: topological order and per-package bail by default, the same live progress panel
|
|
15
|
+
* (falling back to a classic one-line-per-package log when it's off), and the same
|
|
16
|
+
* `--scope`/`--ignore`/`--deps`/`--dependents`/`--changed` package filtering.
|
|
17
|
+
*/
|
|
18
|
+
exec(command: string, options?: ExecService.Options): Promise<void>;
|
|
19
|
+
}
|
|
4
20
|
export declare namespace ExecService {
|
|
5
21
|
interface Options extends PackageFilterOptions {
|
|
6
22
|
/** Max packages at once: `true`/omitted = CPU count, a number = that many, `false` = serial (1). */
|
|
@@ -20,16 +36,11 @@ export declare namespace ExecService {
|
|
|
20
36
|
/** Run across the whole repository even when the current directory is inside a single package
|
|
21
37
|
* (which otherwise scopes the run to just that package). Has no effect when already at the
|
|
22
38
|
* repository root, or outside any known package. */
|
|
23
|
-
|
|
39
|
+
fromRoot?: boolean;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
declare module '../core/classes/service.js' {
|
|
43
|
+
interface ServiceMap {
|
|
44
|
+
exec: ExecService;
|
|
24
45
|
}
|
|
25
|
-
/**
|
|
26
|
-
* `exec`: runs `command` (an arbitrary shell command, not an npm script) directly in every
|
|
27
|
-
* matching package's own directory - unlike `run`, there's no `package.json` script to resolve
|
|
28
|
-
* and no `pre<script>`/`post<script>` npm lifecycle convention to honor, since the command isn't
|
|
29
|
-
* tied to any script name at all. Everything else about how packages are selected and scheduled
|
|
30
|
-
* matches `run`: topological order and per-package bail by default, the same live progress panel
|
|
31
|
-
* (falling back to a classic one-line-per-package log when it's off), and the same
|
|
32
|
-
* `--scope`/`--ignore`/`--deps`/`--dependents`/`--changed` package filtering.
|
|
33
|
-
*/
|
|
34
|
-
function exec(repository: Repository, command: string, options?: Options): Promise<void>;
|
|
35
46
|
}
|
package/services/exec.service.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import os from 'node:os';
|
|
2
2
|
import colors from 'ansi-colors';
|
|
3
3
|
import { Task } from 'power-tasks';
|
|
4
|
+
import { Service } from '../core/classes/service.js';
|
|
4
5
|
import { exec as execCommand } from '../utils/exec.js';
|
|
5
6
|
import { Logger, resolveRootLogLevel } from '../utils/logger.js';
|
|
6
7
|
import { filterPackages } from '../utils/package-filter.js';
|
|
7
8
|
import { ProgressPanel } from '../utils/progress-panel.js';
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
/**
|
|
10
|
+
* A service class - see `ListService` for the shape and `Service` for the three measured
|
|
11
|
+
* consequences a namespace had. `repository` left the signature because the application carries it.
|
|
12
|
+
*/
|
|
13
|
+
export class ExecService extends Service {
|
|
10
14
|
/**
|
|
11
15
|
* `exec`: runs `command` (an arbitrary shell command, not an npm script) directly in every
|
|
12
16
|
* matching package's own directory - unlike `run`, there's no `package.json` script to resolve
|
|
@@ -16,10 +20,11 @@ export var ExecService;
|
|
|
16
20
|
* (falling back to a classic one-line-per-package log when it's off), and the same
|
|
17
21
|
* `--scope`/`--ignore`/`--deps`/`--dependents`/`--changed` package filtering.
|
|
18
22
|
*/
|
|
19
|
-
async
|
|
23
|
+
async exec(command, options = {}) {
|
|
24
|
+
const repository = this.repository;
|
|
20
25
|
const logLevelDefault = resolveRootLogLevel(repository);
|
|
21
26
|
const logger = new Logger(options.logLevel ?? logLevelDefault);
|
|
22
|
-
const cwdScope = options.
|
|
27
|
+
const cwdScope = options.fromRoot ? undefined : repository.currentPackage;
|
|
23
28
|
const topo = options.topo ?? true;
|
|
24
29
|
let packages = repository.getPackages({ toposort: topo, scope: cwdScope?.name });
|
|
25
30
|
if (!topo)
|
|
@@ -48,7 +53,7 @@ export var ExecService;
|
|
|
48
53
|
const children = packages.map(pkg => {
|
|
49
54
|
const ctx = panel.addItem(pkg.name);
|
|
50
55
|
const dependencies = topo ? pkg.dependencies.filter(d => names.has(d.name)).map(d => d.name) : [];
|
|
51
|
-
return new Task(() => execForPackage(ctx, panel.enabled, pkg.dirname, command, logger, bail ? () => rootTask?.abort() : () => { }), { name: pkg.name, dependencies });
|
|
56
|
+
return new Task(() => execForPackage(this.app, ctx, panel.enabled, pkg.dirname, command, logger, bail ? () => rootTask?.abort() : () => { }), { name: pkg.name, dependencies });
|
|
52
57
|
});
|
|
53
58
|
panel.start();
|
|
54
59
|
let failed = false;
|
|
@@ -73,15 +78,15 @@ export var ExecService;
|
|
|
73
78
|
throw err;
|
|
74
79
|
}
|
|
75
80
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
async function execForPackage(ctx, panelEnabled, cwd, command, logger, abort) {
|
|
81
|
+
}
|
|
82
|
+
async function execForPackage(app, ctx, panelEnabled, cwd, command, logger, abort) {
|
|
79
83
|
ctx.status = 'running';
|
|
80
84
|
ctx.startedAt = Date.now();
|
|
81
85
|
try {
|
|
82
86
|
if (panelEnabled) {
|
|
83
87
|
await execCommand(command, {
|
|
84
88
|
cwd,
|
|
89
|
+
app,
|
|
85
90
|
stdio: 'pipe',
|
|
86
91
|
onLine: line => {
|
|
87
92
|
ctx.log.push(line);
|
|
@@ -93,7 +98,7 @@ async function execForPackage(ctx, panelEnabled, cwd, command, logger, abort) {
|
|
|
93
98
|
logger.info(colors.cyan('exec'), colors.cyan(ctx.name), command);
|
|
94
99
|
const t = Date.now();
|
|
95
100
|
try {
|
|
96
|
-
await execCommand(command, { cwd, stdio: 'inherit' });
|
|
101
|
+
await execCommand(command, { cwd, app, stdio: 'inherit' });
|
|
97
102
|
logger.info(colors.green('success'), colors.cyan(ctx.name), colors.yellow(`(${Date.now() - t} ms)`));
|
|
98
103
|
}
|
|
99
104
|
catch (e) {
|
|
@@ -1,35 +1,10 @@
|
|
|
1
|
-
import { Package } from '../core/package.js';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
releaseExists?: (repository: string, tag: string) => Promise<boolean>;
|
|
9
|
-
}
|
|
10
|
-
interface Options {
|
|
11
|
-
/** Uncommitted local changes anywhere in the repository make the release `'skip'` instead of
|
|
12
|
-
* `'error'` - same as `version`/`publish`'s other targets. */
|
|
13
|
-
ignoreDirty?: boolean;
|
|
14
|
-
/** `owner/repo` override - otherwise the root's own `githubRelease.repository`, falling back
|
|
15
|
-
* to the `origin` remote's URL. */
|
|
16
|
-
repository?: string;
|
|
17
|
-
}
|
|
18
|
-
/** The repository's release outcome - see `getPlan`. At most one of these: a GitHub Release
|
|
19
|
-
* belongs to the repository, not to a package. */
|
|
20
|
-
interface Entry {
|
|
21
|
-
/** Always the repository root - a release covers the whole source tree, not one package. */
|
|
22
|
-
package: Package;
|
|
23
|
-
/** The repository's own release version (see `buildRootEntry`). */
|
|
24
|
-
version: string;
|
|
25
|
-
status: 'publish' | 'skip' | 'up-to-date' | 'error';
|
|
26
|
-
/** The tag this release belongs to - the repository release tag on a calendar version, the
|
|
27
|
-
* single shared version's tag otherwise. */
|
|
28
|
-
tag?: string;
|
|
29
|
-
/** `owner/repo` this release lands in - unset only when it couldn't be resolved (an `'error'`). */
|
|
30
|
-
repository?: string;
|
|
31
|
-
reason?: string;
|
|
32
|
-
}
|
|
1
|
+
import { Package } from '../core/classes/package.js';
|
|
2
|
+
import { Service } from '../core/classes/service.js';
|
|
3
|
+
/**
|
|
4
|
+
* A service class - see `ListService` for the shape and `Service` for the three measured
|
|
5
|
+
* consequences a namespace had. `repository` left the signature because the application carries it.
|
|
6
|
+
*/
|
|
7
|
+
export declare class GithubReleaseService extends Service {
|
|
33
8
|
/**
|
|
34
9
|
* Computes what `github-release` *would* do - **one** release per run.
|
|
35
10
|
*
|
|
@@ -51,7 +26,7 @@ export declare namespace GithubReleaseService {
|
|
|
51
26
|
* such release", is `'error'` too - a blocking misconfiguration rather than a silent "not
|
|
52
27
|
* released yet" that only fails later.
|
|
53
28
|
*/
|
|
54
|
-
|
|
29
|
+
getPlan(options?: GithubReleaseService.Options, deps?: GithubReleaseService.Deps): Promise<GithubReleaseService.Entry[]>;
|
|
55
30
|
/**
|
|
56
31
|
* Creates the repository's GitHub Release, then uploads whatever `githubRelease.assets` globs
|
|
57
32
|
* match, across every package. The body covers **every** package that shipped under this
|
|
@@ -65,5 +40,41 @@ export declare namespace GithubReleaseService {
|
|
|
65
40
|
* An existing release for the tag is updated rather than treated as a failure, so a re-run after
|
|
66
41
|
* a partial failure converges.
|
|
67
42
|
*/
|
|
68
|
-
|
|
43
|
+
applyPlan(plan: GithubReleaseService.Entry[]): Promise<GithubReleaseService.Entry[]>;
|
|
44
|
+
}
|
|
45
|
+
export declare namespace GithubReleaseService {
|
|
46
|
+
/** Injectable "does this release already exist" check - mainly for tests, so they don't depend
|
|
47
|
+
* on network access or a real GitHub token. Same shape as `DockerPublishService.Deps`' own
|
|
48
|
+
* `imageExists`. */
|
|
49
|
+
interface Deps {
|
|
50
|
+
releaseExists?: (repository: string, tag: string) => Promise<boolean>;
|
|
51
|
+
}
|
|
52
|
+
interface Options {
|
|
53
|
+
/** Uncommitted local changes anywhere in the repository make the release `'skip'` instead of
|
|
54
|
+
* `'error'` - same as `version`/`publish`'s other targets. */
|
|
55
|
+
ignoreDirty?: boolean;
|
|
56
|
+
/** `owner/repo` override - otherwise the root's own `githubRelease.repository`, falling back
|
|
57
|
+
* to the `origin` remote's URL. */
|
|
58
|
+
repository?: string;
|
|
59
|
+
}
|
|
60
|
+
/** The repository's release outcome - see `getPlan`. At most one of these: a GitHub Release
|
|
61
|
+
* belongs to the repository, not to a package. */
|
|
62
|
+
interface Entry {
|
|
63
|
+
/** Always the repository root - a release covers the whole source tree, not one package. */
|
|
64
|
+
package: Package;
|
|
65
|
+
/** The repository's own release version (see `buildRootEntry`). */
|
|
66
|
+
version: string;
|
|
67
|
+
status: 'publish' | 'skip' | 'up-to-date' | 'error';
|
|
68
|
+
/** The tag this release belongs to - the repository release tag on a calendar version, the
|
|
69
|
+
* single shared version's tag otherwise. */
|
|
70
|
+
tag?: string;
|
|
71
|
+
/** `owner/repo` this release lands in - unset only when it couldn't be resolved (an `'error'`). */
|
|
72
|
+
repository?: string;
|
|
73
|
+
reason?: string;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
declare module '../core/classes/service.js' {
|
|
77
|
+
interface ServiceMap {
|
|
78
|
+
githubRelease: GithubReleaseService;
|
|
79
|
+
}
|
|
69
80
|
}
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import fastGlob from 'fast-glob';
|
|
4
|
-
import { Package } from '../core/package.js';
|
|
5
|
-
import { Repository } from '../core/repository.js';
|
|
4
|
+
import { Package } from '../core/classes/package.js';
|
|
5
|
+
import { Repository } from '../core/classes/repository.js';
|
|
6
|
+
import { Service } from '../core/classes/service.js';
|
|
6
7
|
import { GitHelper } from '../utils/git.js';
|
|
7
8
|
import { expandReleaseTag, isCalendarVersion, releaseTagPattern } from '../utils/release-version.js';
|
|
8
9
|
import { ChangeHashService } from './change-hash.service.js';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
/**
|
|
11
|
+
* A service class - see `ListService` for the shape and `Service` for the three measured
|
|
12
|
+
* consequences a namespace had. `repository` left the signature because the application carries it.
|
|
13
|
+
*/
|
|
14
|
+
export class GithubReleaseService extends Service {
|
|
12
15
|
/**
|
|
13
16
|
* Computes what `github-release` *would* do - **one** release per run.
|
|
14
17
|
*
|
|
@@ -30,7 +33,8 @@ export var GithubReleaseService;
|
|
|
30
33
|
* such release", is `'error'` too - a blocking misconfiguration rather than a silent "not
|
|
31
34
|
* released yet" that only fails later.
|
|
32
35
|
*/
|
|
33
|
-
async
|
|
36
|
+
async getPlan(options = {}, deps = {}) {
|
|
37
|
+
const repository = this.repository;
|
|
34
38
|
const root = repository.rootPackage;
|
|
35
39
|
const git = new GitHelper({ cwd: repository.dirname });
|
|
36
40
|
const base = { package: root, version: root.version };
|
|
@@ -88,7 +92,6 @@ export var GithubReleaseService;
|
|
|
88
92
|
return [{ ...base, tag, repository: repo, status: 'error', reason: e.message }];
|
|
89
93
|
}
|
|
90
94
|
}
|
|
91
|
-
GithubReleaseService.getPlan = getPlan;
|
|
92
95
|
/**
|
|
93
96
|
* Creates the repository's GitHub Release, then uploads whatever `githubRelease.assets` globs
|
|
94
97
|
* match, across every package. The body covers **every** package that shipped under this
|
|
@@ -102,7 +105,8 @@ export var GithubReleaseService;
|
|
|
102
105
|
* An existing release for the tag is updated rather than treated as a failure, so a re-run after
|
|
103
106
|
* a partial failure converges.
|
|
104
107
|
*/
|
|
105
|
-
async
|
|
108
|
+
async applyPlan(plan) {
|
|
109
|
+
const repository = this.repository;
|
|
106
110
|
const entry = plan.find(e => e.status === 'publish');
|
|
107
111
|
if (!entry)
|
|
108
112
|
return plan;
|
|
@@ -122,8 +126,7 @@ export var GithubReleaseService;
|
|
|
122
126
|
return plan.map(e2 => (e2 === entry ? { ...e2, status: 'error', reason: e.message } : e2));
|
|
123
127
|
}
|
|
124
128
|
}
|
|
125
|
-
|
|
126
|
-
})(GithubReleaseService || (GithubReleaseService = {}));
|
|
129
|
+
}
|
|
127
130
|
const GITHUB_API = 'https://api.github.com';
|
|
128
131
|
const GITHUB_UPLOADS = 'https://uploads.github.com';
|
|
129
132
|
/** The tag naming this repository's release. A calendar root version means several version lines,
|
|
@@ -198,9 +201,9 @@ async function buildReleaseNotes(repository, git, releaseTag) {
|
|
|
198
201
|
return '';
|
|
199
202
|
const sections = [];
|
|
200
203
|
for (const pkg of [...repository.getPackages(), root]) {
|
|
201
|
-
const entries = await
|
|
204
|
+
const entries = await repository.app.getService('changelog').getEntries({
|
|
202
205
|
from: previous,
|
|
203
|
-
|
|
206
|
+
fromRoot: true,
|
|
204
207
|
includeSkipped: true,
|
|
205
208
|
scope: pkg.name,
|
|
206
209
|
version: pkg.version,
|
|
@@ -1,16 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
interface Result {
|
|
8
|
-
/** The imported package's name (from its own `package.json`, or its directory basename). */
|
|
9
|
-
name: string;
|
|
10
|
-
/** Where it was placed, absolute. */
|
|
11
|
-
targetDir: string;
|
|
12
|
-
commitCount: number;
|
|
13
|
-
}
|
|
1
|
+
import { Service } from '../core/classes/service.js';
|
|
2
|
+
/**
|
|
3
|
+
* A service class - see `ListService` for the shape and `Service` for the three measured
|
|
4
|
+
* consequences a namespace had. `repository` left the signature because the application carries it.
|
|
5
|
+
*/
|
|
6
|
+
export declare class ImportService extends Service {
|
|
14
7
|
/**
|
|
15
8
|
* Imports `sourcePath` (a local clone of some other git repository) as a new package under this
|
|
16
9
|
* repository, preserving its **entire commit history** - every original commit, author, date and
|
|
@@ -26,5 +19,23 @@ export declare namespace ImportService {
|
|
|
26
19
|
* merge (which real `git subtree` would give, at the cost of far less predictable behavior
|
|
27
20
|
* across git versions - the reason this - and lerna - avoid it).
|
|
28
21
|
*/
|
|
29
|
-
|
|
22
|
+
importRepo(sourcePath: string, options?: ImportService.Options): Promise<ImportService.Result>;
|
|
23
|
+
}
|
|
24
|
+
export declare namespace ImportService {
|
|
25
|
+
interface Options {
|
|
26
|
+
/** Subdirectory (relative to the repository root) the new package is placed under - default `'packages'`. */
|
|
27
|
+
dest?: string;
|
|
28
|
+
}
|
|
29
|
+
interface Result {
|
|
30
|
+
/** The imported package's name (from its own `package.json`, or its directory basename). */
|
|
31
|
+
name: string;
|
|
32
|
+
/** Where it was placed, absolute. */
|
|
33
|
+
targetDir: string;
|
|
34
|
+
commitCount: number;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
declare module '../core/classes/service.js' {
|
|
38
|
+
interface ServiceMap {
|
|
39
|
+
import: ImportService;
|
|
40
|
+
}
|
|
30
41
|
}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import os from 'node:os';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
+
import { Service } from '../core/classes/service.js';
|
|
4
5
|
import { GitHelper } from '../utils/git.js';
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* A service class - see `ListService` for the shape and `Service` for the three measured
|
|
8
|
+
* consequences a namespace had. `repository` left the signature because the application carries it.
|
|
9
|
+
*/
|
|
10
|
+
export class ImportService extends Service {
|
|
7
11
|
/**
|
|
8
12
|
* Imports `sourcePath` (a local clone of some other git repository) as a new package under this
|
|
9
13
|
* repository, preserving its **entire commit history** - every original commit, author, date and
|
|
@@ -19,7 +23,8 @@ export var ImportService;
|
|
|
19
23
|
* merge (which real `git subtree` would give, at the cost of far less predictable behavior
|
|
20
24
|
* across git versions - the reason this - and lerna - avoid it).
|
|
21
25
|
*/
|
|
22
|
-
async
|
|
26
|
+
async importRepo(sourcePath, options = {}) {
|
|
27
|
+
const repository = this.repository;
|
|
23
28
|
const absSource = path.resolve(sourcePath);
|
|
24
29
|
if (!fs.existsSync(path.join(absSource, '.git'))) {
|
|
25
30
|
throw new Error(`"${sourcePath}" is not a git repository (no .git found) - clone it locally first`);
|
|
@@ -48,8 +53,7 @@ export var ImportService;
|
|
|
48
53
|
fs.rmSync(patchDir, { recursive: true, force: true });
|
|
49
54
|
}
|
|
50
55
|
}
|
|
51
|
-
|
|
52
|
-
})(ImportService || (ImportService = {}));
|
|
56
|
+
}
|
|
53
57
|
/** The source repo's own `package.json` name, or its directory's basename when it has none (or
|
|
54
58
|
* isn't even a package yet - a plain library repo being folded in). */
|
|
55
59
|
function resolveSourceName(absSource) {
|
|
@@ -1,34 +1,88 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { DockerPublishOptions } from '../builtins/publish-targets/docker/docker.target.js';
|
|
2
|
+
import type { Repository } from '../core/classes/repository.js';
|
|
3
|
+
import { Service } from '../core/classes/service.js';
|
|
4
|
+
import { type PublishTargetName } from '../core/interfaces/publish-target.js';
|
|
3
5
|
import { type PackageFilterOptions } from '../utils/package-filter.js';
|
|
6
|
+
/**
|
|
7
|
+
* **A class, and the shape every service follows now.**
|
|
8
|
+
*
|
|
9
|
+
* `repository` is gone from the signature - it comes from the application, which is what always
|
|
10
|
+
* made the parameter redundant: every caller had one and passed it, and no caller ever had two.
|
|
11
|
+
* What a namespace could not do is hold state without holding it *globally*, be subclassed, or be
|
|
12
|
+
* stubbed without mutating the module; `Service` records the three measured consequences.
|
|
13
|
+
*
|
|
14
|
+
* **Declared before the namespace below, which is not style.** A namespace merges *into* a class
|
|
15
|
+
* only when the class comes first - the other order is
|
|
16
|
+
* `Cannot use namespace 'ListService' as a type`. Merged, `ListService.Options` and
|
|
17
|
+
* `ListService.Item` still read exactly as they did, so nothing importing a type had to change.
|
|
18
|
+
*/
|
|
19
|
+
export declare class ListService extends Service {
|
|
20
|
+
/**
|
|
21
|
+
* `list`: every package in the repository (or, with `changed`/`changedSince`, only the ones that
|
|
22
|
+
* have actually changed), each with its version, location, private flag, and change status
|
|
23
|
+
* relative to upstream. Pure data - no console output; `rman list`'s own command decides how to
|
|
24
|
+
* present it (table, JSON, parseable, names only, or a dependency graph).
|
|
25
|
+
*/
|
|
26
|
+
getPackages(options?: ListService.Options): Promise<ListService.Item[]>;
|
|
27
|
+
}
|
|
4
28
|
export declare namespace ListService {
|
|
5
29
|
interface Options extends PackageFilterOptions {
|
|
6
30
|
/** Topological order (dependencies before dependents) instead of lexical by directory. */
|
|
7
31
|
toposort?: boolean;
|
|
8
|
-
/**
|
|
9
|
-
*
|
|
32
|
+
/**
|
|
33
|
+
* Also report the **root package**, first, as the row the members' `depth` is measured from.
|
|
34
|
+
*
|
|
35
|
+
* Opt-in rather than always, because it changes what the answer *is*: `repository.packages` is
|
|
36
|
+
* the workspace members, so every other reader of this list - and the count `rman list` prints -
|
|
37
|
+
* is about them. `rman list`'s table asks for it because a tree needs a root to hang from; its
|
|
38
|
+
* `--json`, `--parseable` and `--short` forms do not, and a consumer parsing them sees exactly
|
|
39
|
+
* what it saw before.
|
|
40
|
+
*/
|
|
41
|
+
includeRoot?: boolean;
|
|
42
|
+
/** Only include packages the developer has touched but not pushed (dirty, or committed and not
|
|
43
|
+
* yet on the upstream branch) - or, with `changedSince`, since that specific commit/hash.
|
|
44
|
+
* **Question C, never a release question**: after a push `git cherry` is empty and everything
|
|
45
|
+
* reads `clean`, which does not mean there is nothing left to release. */
|
|
10
46
|
changed?: boolean;
|
|
11
47
|
changedSince?: string;
|
|
12
48
|
}
|
|
13
49
|
interface Item {
|
|
14
50
|
name: string;
|
|
51
|
+
/** What addresses this package - `"[glob]"` and `--scope` match it. The same as `name` wherever
|
|
52
|
+
* the technology names its packages, which is every Node repository; see `Package.selector`. */
|
|
53
|
+
selector: string;
|
|
15
54
|
version: string;
|
|
55
|
+
/** The technology that claimed this package's directory - `Package.provider`. Empty when none
|
|
56
|
+
* did, which is a repository naming no plugin. */
|
|
57
|
+
platform: string;
|
|
58
|
+
/**
|
|
59
|
+
* How far below the **root package** this one sits: `0` for the root itself, `1` for an ordinary
|
|
60
|
+
* member, more for a package nested inside another.
|
|
61
|
+
*
|
|
62
|
+
* A fact about the package rather than about this list's order, so it is still right under
|
|
63
|
+
* `--toposort` - which reorders the rows and leaves the nesting where it is.
|
|
64
|
+
*/
|
|
65
|
+
depth: number;
|
|
66
|
+
/** Whether this row *is* the root package - present only when `includeRoot` asked for it, or in
|
|
67
|
+
* a single-package repository where the root is the one member. */
|
|
68
|
+
isRoot: boolean;
|
|
16
69
|
location: string;
|
|
17
70
|
private: boolean;
|
|
18
71
|
status: Repository.PackageStatus;
|
|
19
72
|
/** In-repo package names this one depends on - enough to build a dependency graph without a
|
|
20
73
|
* second call, e.g. `Object.fromEntries(items.map(i => [i.name, i.dependencies]))`. */
|
|
21
74
|
dependencies: string[];
|
|
22
|
-
/**
|
|
23
|
-
*
|
|
24
|
-
|
|
75
|
+
/** Where this package actually ships - its own (cascaded) `.rmanrc "publish.target"` when it
|
|
76
|
+
* declares one, otherwise every registered target that claims it, which is the same question
|
|
77
|
+
* `publish` asks. Empty in a repository whose plugins contribute no target the package fits. */
|
|
78
|
+
publishTargets: PublishTargetName[];
|
|
25
79
|
/** Present only when `"docker"` is one of `publishTargets` and `publish.docker` is configured -
|
|
26
80
|
* the raw `.rmanrc` config, unresolved (no namespace prefixing - see `DockerPublishService`). */
|
|
27
|
-
docker?:
|
|
81
|
+
docker?: DockerPublishOptions;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
declare module '../core/classes/service.js' {
|
|
85
|
+
interface ServiceMap {
|
|
86
|
+
list: ListService;
|
|
28
87
|
}
|
|
29
|
-
/** `list`: every package in the repository (or, with `changed`/`changedSince`, only the ones
|
|
30
|
-
* that have actually changed), each with its version, location, private flag, and change
|
|
31
|
-
* status relative to upstream. Pure data - no console output; `rman list`'s own command
|
|
32
|
-
* decides how to present it (table, JSON, parseable, names only, or a dependency graph). */
|
|
33
|
-
function getPackages(repository: Repository, options?: Options): Promise<Item[]>;
|
|
34
88
|
}
|
package/services/list.service.js
CHANGED
|
@@ -1,34 +1,81 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
+
import { Service } from '../core/classes/service.js';
|
|
3
|
+
import { targetsOf } from '../core/interfaces/publish-target.js';
|
|
2
4
|
import { filterPackages } from '../utils/package-filter.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
/**
|
|
6
|
+
* **A class, and the shape every service follows now.**
|
|
7
|
+
*
|
|
8
|
+
* `repository` is gone from the signature - it comes from the application, which is what always
|
|
9
|
+
* made the parameter redundant: every caller had one and passed it, and no caller ever had two.
|
|
10
|
+
* What a namespace could not do is hold state without holding it *globally*, be subclassed, or be
|
|
11
|
+
* stubbed without mutating the module; `Service` records the three measured consequences.
|
|
12
|
+
*
|
|
13
|
+
* **Declared before the namespace below, which is not style.** A namespace merges *into* a class
|
|
14
|
+
* only when the class comes first - the other order is
|
|
15
|
+
* `Cannot use namespace 'ListService' as a type`. Merged, `ListService.Options` and
|
|
16
|
+
* `ListService.Item` still read exactly as they did, so nothing importing a type had to change.
|
|
17
|
+
*/
|
|
18
|
+
export class ListService extends Service {
|
|
19
|
+
/**
|
|
20
|
+
* `list`: every package in the repository (or, with `changed`/`changedSince`, only the ones that
|
|
21
|
+
* have actually changed), each with its version, location, private flag, and change status
|
|
22
|
+
* relative to upstream. Pure data - no console output; `rman list`'s own command decides how to
|
|
23
|
+
* present it (table, JSON, parseable, names only, or a dependency graph).
|
|
24
|
+
*/
|
|
25
|
+
async getPackages(options = {}) {
|
|
26
|
+
const repository = this.repository;
|
|
10
27
|
/** `false`: `list` is the inventory, so a package its own `.rmanrc "skip"` excludes is still
|
|
11
28
|
* *in* the repository and still listed - hiding it would answer a different question. Every
|
|
12
29
|
* other caller honours it, being a command that acts rather than reports. */
|
|
13
30
|
const packages = filterPackages(repository.getPackages({ toposort: options.toposort }), options, false);
|
|
14
|
-
const status = await repository.listStatus({ hash: options.changedSince });
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
31
|
+
const status = await repository.listStatus({ hash: options.changedSince, includeRoot: options.includeRoot });
|
|
32
|
+
const item = (p) => {
|
|
33
|
+
/** **Asked, not assumed.** This read the config key directly and defaulted to `['npm']`, so a
|
|
34
|
+
* Cargo package in a polyglot repository was reported as shipping to npm - which is what
|
|
35
|
+
* `PublishTarget.claims` exists to answer, per target, from the ecosystem that knows. */
|
|
36
|
+
const publishTargets = targetsOf(this.app, p).map(t => t.name);
|
|
18
37
|
return {
|
|
19
38
|
name: p.name,
|
|
39
|
+
selector: p.selector,
|
|
20
40
|
version: p.version,
|
|
41
|
+
platform: p.provider,
|
|
42
|
+
depth: depthOf(p),
|
|
43
|
+
isRoot: p === repository.rootPackage,
|
|
21
44
|
location: path.relative(repository.dirname, p.dirname) || '.',
|
|
22
45
|
private: p.isPrivate,
|
|
23
|
-
status: status[p.
|
|
46
|
+
status: status[p.selector],
|
|
24
47
|
dependencies: p.dependencies.map(d => d.name),
|
|
25
48
|
publishTargets: [...publishTargets],
|
|
26
49
|
docker: publishTargets.includes('docker') ? p.config.publish?.docker : undefined,
|
|
27
50
|
};
|
|
28
|
-
}
|
|
51
|
+
};
|
|
52
|
+
let items = packages.map(item);
|
|
29
53
|
if (options.changed || options.changedSince)
|
|
30
54
|
items = items.filter(it => it.status !== 'clean');
|
|
55
|
+
/**
|
|
56
|
+
* **The root goes on the front, after filtering, and is never filtered out.** It is the tree's
|
|
57
|
+
* own row - what the members' indentation hangs from - so a `--scope` that narrows the members
|
|
58
|
+
* still leaves it standing rather than removing the thing they are nested under. A glob never
|
|
59
|
+
* matches the root anyway (`ROOT_SELECTOR`), so there is no filter here to respect.
|
|
60
|
+
*
|
|
61
|
+
* Not in a single-package repository, where `repository.packages` already *is* `[rootPackage]`
|
|
62
|
+
* and it would appear twice.
|
|
63
|
+
*/
|
|
64
|
+
if (options.includeRoot && repository.monorepo)
|
|
65
|
+
items.unshift(item(repository.rootPackage));
|
|
31
66
|
return items;
|
|
32
67
|
}
|
|
33
|
-
|
|
34
|
-
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* How far below the root `pkg` sits, by walking `parent` - `0` for the root itself.
|
|
71
|
+
*
|
|
72
|
+
* From the tree edge rather than by counting path segments, which would be a different number: a
|
|
73
|
+
* package in `packages/a` is two directories down and one *package* down, and it is the second that
|
|
74
|
+
* the indentation is about.
|
|
75
|
+
*/
|
|
76
|
+
function depthOf(pkg) {
|
|
77
|
+
let depth = 0;
|
|
78
|
+
for (let at = pkg.parent; at; at = at.parent)
|
|
79
|
+
depth++;
|
|
80
|
+
return depth;
|
|
81
|
+
}
|