rman 1.3.0 → 2.0.0-beta.2
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 +63 -19
- package/cli.d.ts +5 -0
- package/cli.js +214 -88
- package/commands/build.command.d.ts +177 -3
- package/commands/build.command.js +20 -10
- package/commands/changed.command.d.ts +80 -3
- package/commands/changed.command.js +19 -12
- package/commands/changelog.command.d.ts +192 -3
- package/commands/changelog.command.js +87 -43
- package/commands/config.command.d.ts +44 -3
- package/commands/config.command.js +30 -19
- 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/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 +317 -3
- package/commands/version.command.js +149 -69
- 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 +143 -0
- package/core/command-builder.d.ts +14 -0
- package/core/command-builder.js +78 -0
- package/core/config.d.ts +140 -19
- package/core/config.js +258 -74
- package/core/core-services.d.ts +14 -0
- package/core/core-services.js +30 -0
- package/core/core-targets.d.ts +14 -0
- package/core/core-targets.js +16 -0
- package/core/custom-command.d.ts +42 -6
- package/core/custom-command.js +44 -17
- package/core/extends-config.d.ts +13 -5
- package/core/extends-config.js +52 -12
- package/core/load-config-module.d.ts +28 -0
- package/core/load-config-module.js +42 -0
- package/core/manifest.d.ts +47 -25
- package/core/manifest.js +51 -69
- package/core/merge-config.d.ts +33 -34
- package/core/merge-config.js +137 -92
- package/core/package.d.ts +145 -17
- package/core/package.js +128 -36
- package/core/plugin-loader.d.ts +65 -0
- package/core/plugin-loader.js +234 -0
- package/core/plugin.d.ts +135 -90
- package/core/plugin.js +70 -173
- package/core/publish-target.d.ts +124 -0
- package/core/publish-target.js +30 -0
- package/core/registry.d.ts +30 -0
- package/core/registry.js +47 -0
- package/core/repository.d.ts +72 -9
- package/core/repository.js +293 -44
- package/core/resolve-target.d.ts +1 -1
- package/core/resolve-target.js +1 -1
- package/core/service.d.ts +49 -0
- package/core/service.js +40 -0
- package/core/version-scheme.d.ts +23 -1
- package/core/version-scheme.js +29 -1
- package/core/workspace.d.ts +84 -33
- package/core/workspace.js +63 -22
- package/index.d.ts +111 -14
- package/index.js +85 -9
- package/interfaces/rman-config.interface.d.ts +725 -202
- package/interfaces/rman-config.interface.js +61 -1
- package/package.json +2 -1
- package/plugins/builtins.d.ts +44 -0
- package/plugins/builtins.js +33 -0
- package/plugins/detect.d.ts +78 -0
- package/plugins/detect.js +70 -0
- package/plugins/node/augmentation/rman.augmentation.d.ts +84 -0
- package/plugins/node/augmentation/rman.augmentation.js +1 -0
- package/plugins/node/augmentation/system-info.augmentation.d.ts +26 -0
- package/plugins/node/augmentation/system-info.augmentation.js +79 -0
- package/plugins/node/commands/ci.command.d.ts +131 -0
- package/plugins/node/commands/ci.command.js +59 -0
- package/plugins/node/commands/clean.command.d.ts +183 -0
- package/plugins/node/commands/clean.command.js +73 -0
- package/plugins/node/index.d.ts +29 -0
- package/plugins/node/index.js +40 -0
- package/plugins/node/node-config.interface.d.ts +77 -0
- package/plugins/node/node-config.interface.js +7 -0
- package/plugins/node/node-manifest.provider.d.ts +68 -0
- package/plugins/node/node-manifest.provider.js +125 -0
- package/plugins/node/node.platform.d.ts +53 -0
- package/plugins/node/node.platform.js +134 -0
- package/plugins/node/npm-publish-target.d.ts +73 -0
- package/plugins/node/npm-publish-target.js +96 -0
- package/plugins/node/services/ci.service.d.ts +47 -0
- package/plugins/node/services/ci.service.js +213 -0
- package/plugins/node/services/clean.service.d.ts +53 -0
- package/plugins/node/services/clean.service.js +237 -0
- package/plugins/node/services/publish.service.d.ts +114 -0
- package/plugins/node/services/publish.service.js +371 -0
- package/plugins/node/services/version-plan.service.d.ts +44 -0
- package/plugins/node/services/version-plan.service.js +58 -0
- package/plugins/node/utils/npm-view.d.ts +48 -0
- package/plugins/node/utils/npm-view.js +71 -0
- package/plugins/node/utils/workspace-range.d.ts +26 -0
- package/plugins/node/utils/workspace-range.js +28 -0
- package/services/change-hash.service.d.ts +2 -2
- package/services/change-hash.service.js +2 -2
- package/services/changelog.service.d.ts +62 -51
- package/services/changelog.service.js +14 -11
- package/services/docker-publish.service.d.ts +50 -29
- package/services/docker-publish.service.js +43 -20
- package/services/exec.service.d.ts +23 -12
- package/services/exec.service.js +14 -9
- package/services/github-release.service.d.ts +44 -33
- package/services/github-release.service.js +13 -10
- package/services/import.service.d.ts +25 -14
- package/services/import.service.js +9 -5
- package/services/list.service.d.ts +62 -10
- package/services/list.service.js +62 -15
- package/services/run.service.d.ts +22 -13
- package/services/run.service.js +262 -223
- package/services/version-plan.service.d.ts +27 -4
- package/services/version-plan.service.js +42 -15
- package/services/version.service.d.ts +31 -11
- package/services/version.service.js +29 -13
- package/targets/docker.target.d.ts +53 -0
- package/targets/docker.target.js +40 -0
- package/utils/bin-path.d.ts +6 -7
- package/utils/bin-path.js +7 -18
- package/utils/branch-guard.d.ts +29 -0
- package/utils/branch-guard.js +31 -0
- package/utils/exec.d.ts +10 -0
- package/utils/exec.js +1 -1
- package/utils/logger.d.ts +1 -1
- package/utils/logger.js +1 -1
- package/utils/package-filter.d.ts +127 -7
- package/utils/package-filter.js +197 -16
- package/utils/printable-config.d.ts +1 -1
- package/utils/printable-config.js +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-stamp.d.ts +1 -1
- package/utils/version-stamp.js +1 -1
|
@@ -1,35 +1,10 @@
|
|
|
1
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
|
-
}
|
|
2
|
+
import { Service } from '../core/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/service.js' {
|
|
77
|
+
interface ServiceMap {
|
|
78
|
+
githubRelease: GithubReleaseService;
|
|
79
|
+
}
|
|
69
80
|
}
|
|
@@ -3,12 +3,15 @@ import path from 'node:path';
|
|
|
3
3
|
import fastGlob from 'fast-glob';
|
|
4
4
|
import { Package } from '../core/package.js';
|
|
5
5
|
import { Repository } from '../core/repository.js';
|
|
6
|
+
import { Service } from '../core/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/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/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/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,10 +1,44 @@
|
|
|
1
|
+
import { type PublishTargetName } from '../core/publish-target.js';
|
|
1
2
|
import type { Repository } from '../core/repository.js';
|
|
2
|
-
import
|
|
3
|
+
import { Service } from '../core/service.js';
|
|
4
|
+
import type { DockerPublishOptions } from '../targets/docker.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;
|
|
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;
|
|
8
42
|
/** Only include packages that have changed since the last publish (dirty or committed but
|
|
9
43
|
* not yet published) - or, with `changedSince`, since that specific commit/hash. */
|
|
10
44
|
changed?: boolean;
|
|
@@ -12,23 +46,41 @@ export declare namespace ListService {
|
|
|
12
46
|
}
|
|
13
47
|
interface Item {
|
|
14
48
|
name: string;
|
|
49
|
+
/** What addresses this package - `"[glob]"` and `--scope` match it. The same as `name` wherever
|
|
50
|
+
* the technology names its packages, which is every Node repository; see `Package.selector`. */
|
|
51
|
+
selector: string;
|
|
15
52
|
version: string;
|
|
53
|
+
/** The technology that claimed this package's directory - `Package.provider`. Empty when none
|
|
54
|
+
* did, which is a repository naming no plugin. */
|
|
55
|
+
platform: string;
|
|
56
|
+
/**
|
|
57
|
+
* How far below the **root package** this one sits: `0` for the root itself, `1` for an ordinary
|
|
58
|
+
* member, more for a package nested inside another.
|
|
59
|
+
*
|
|
60
|
+
* A fact about the package rather than about this list's order, so it is still right under
|
|
61
|
+
* `--toposort` - which reorders the rows and leaves the nesting where it is.
|
|
62
|
+
*/
|
|
63
|
+
depth: number;
|
|
64
|
+
/** Whether this row *is* the root package - present only when `includeRoot` asked for it, or in
|
|
65
|
+
* a single-package repository where the root is the one member. */
|
|
66
|
+
isRoot: boolean;
|
|
16
67
|
location: string;
|
|
17
68
|
private: boolean;
|
|
18
69
|
status: Repository.PackageStatus;
|
|
19
70
|
/** In-repo package names this one depends on - enough to build a dependency graph without a
|
|
20
71
|
* second call, e.g. `Object.fromEntries(items.map(i => [i.name, i.dependencies]))`. */
|
|
21
72
|
dependencies: string[];
|
|
22
|
-
/**
|
|
23
|
-
*
|
|
24
|
-
|
|
73
|
+
/** Where this package actually ships - its own (cascaded) `.rmanrc "publish.target"` when it
|
|
74
|
+
* declares one, otherwise every registered target that claims it, which is the same question
|
|
75
|
+
* `publish` asks. Empty in a repository whose plugins contribute no target the package fits. */
|
|
76
|
+
publishTargets: PublishTargetName[];
|
|
25
77
|
/** Present only when `"docker"` is one of `publishTargets` and `publish.docker` is configured -
|
|
26
78
|
* the raw `.rmanrc` config, unresolved (no namespace prefixing - see `DockerPublishService`). */
|
|
27
|
-
docker?:
|
|
79
|
+
docker?: DockerPublishOptions;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
declare module '../core/service.js' {
|
|
83
|
+
interface ServiceMap {
|
|
84
|
+
list: ListService;
|
|
28
85
|
}
|
|
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
86
|
}
|
package/services/list.service.js
CHANGED
|
@@ -1,34 +1,81 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
+
import { targetsOf } from '../core/publish-target.js';
|
|
3
|
+
import { Service } from '../core/service.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
|
+
}
|
|
@@ -1,8 +1,23 @@
|
|
|
1
1
|
import type { Package } from '../core/package.js';
|
|
2
2
|
import type { Repository } from '../core/repository.js';
|
|
3
3
|
import type { RunStepContext, RunStepFn, RunStepValue } from '../core/run-step.js';
|
|
4
|
+
import { Service } from '../core/service.js';
|
|
4
5
|
import { type LogLevel } from '../utils/logger.js';
|
|
5
6
|
import { type PackageFilterOptions } from '../utils/package-filter.js';
|
|
7
|
+
/**
|
|
8
|
+
* A service class - see `ListService` for the shape and `Service` for the three measured
|
|
9
|
+
* consequences a namespace had.
|
|
10
|
+
*
|
|
11
|
+
* **Only `runScript` became a method**, because only it takes a repository. `getConfig`,
|
|
12
|
+
* `parseIfExpr`, `normalizeScriptValue` and the rest take a `Package` or a raw value and stay
|
|
13
|
+
* functions on the namespace below - the same rule that leaves `ChangeHashService` a namespace
|
|
14
|
+
* entirely. Declared before the namespace, which TypeScript requires for the merge.
|
|
15
|
+
*/
|
|
16
|
+
export declare class RunService extends Service {
|
|
17
|
+
runScript(script: string, options?: RunService.Options & {
|
|
18
|
+
commandName?: string;
|
|
19
|
+
}): Promise<void>;
|
|
20
|
+
}
|
|
6
21
|
export declare namespace RunService {
|
|
7
22
|
export interface Options extends PackageFilterOptions {
|
|
8
23
|
/** Max packages built at once: `true`/omitted = CPU count, a number = that many, `false` = serial (1). */
|
|
@@ -24,7 +39,7 @@ export declare namespace RunService {
|
|
|
24
39
|
* (which otherwise scopes the run to just that package, and skips the root's own pre/post
|
|
25
40
|
* bookend - see `Repository.currentPackage`). Has no effect when already at the repository
|
|
26
41
|
* root, or outside any known package. */
|
|
27
|
-
|
|
42
|
+
fromRoot?: boolean;
|
|
28
43
|
}
|
|
29
44
|
/**
|
|
30
45
|
* A package's `.rmanrc` (cascaded) can configure `run.<script>.*` - e.g.
|
|
@@ -89,21 +104,13 @@ export declare namespace RunService {
|
|
|
89
104
|
*
|
|
90
105
|
* The core knows one source: the config. **`package.json#scripts` is not a source the core has**,
|
|
91
106
|
* because "a script lives in package.json" is true of a Node repository and of nothing else -
|
|
92
|
-
* `
|
|
107
|
+
* the `node` built-in contributes that one (with npm's `pre<script>`/`post<script>` convention and its
|
|
93
108
|
* `&&` splitting), and a plugin for another ecosystem would contribute its own.
|
|
94
109
|
*
|
|
95
110
|
* Returns `undefined` for "this package declares nothing", not empty slots - the difference
|
|
96
111
|
* decides whether the config's value applies.
|
|
97
112
|
*/
|
|
98
113
|
export type StepSource = (pkg: Package, script: string) => ScriptSlots | undefined;
|
|
99
|
-
/**
|
|
100
|
-
* Registers a source. Called by `loadPlugins` for each plugin's `runSteps`, in `plugins`
|
|
101
|
-
* declaration order - never as an import side effect, so what is registered is exactly what the
|
|
102
|
-
* repository's `.rmanrc` asked for.
|
|
103
|
-
*/
|
|
104
|
-
export function addStepSource(source: StepSource): void;
|
|
105
|
-
/** For tests, which would otherwise leak a source into every later case in the process. */
|
|
106
|
-
export function clearStepSources(): void;
|
|
107
114
|
/**
|
|
108
115
|
* What the *package itself* declares for the lifecycle `script`, from the contributed sources
|
|
109
116
|
* alone - no `.rmanrc` involved. `undefined` when it declares nothing.
|
|
@@ -193,9 +200,6 @@ export declare namespace RunService {
|
|
|
193
200
|
/** Evaluates a parsed `if` expression for one package. `statusCache` avoids repeat `git` calls
|
|
194
201
|
* for the same reference hash across packages/scripts in a single run. */
|
|
195
202
|
export function evaluateIf(repository: Repository, pkg: Package, node: IfNode, statusCache: Map<string, Record<string, Repository.PackageStatus>>): Promise<boolean>;
|
|
196
|
-
export function runScript(repository: Repository, script: string, options?: Options & {
|
|
197
|
-
commandName?: string;
|
|
198
|
-
}): Promise<void>;
|
|
199
203
|
export {};
|
|
200
204
|
}
|
|
201
205
|
/** Resolution order: explicit CLI flag > the package's resolved `.rmanrc` > `fallback`. */
|
|
@@ -208,3 +212,8 @@ export declare function resolveBool(cliValue: boolean | undefined, pkg: Package,
|
|
|
208
212
|
export declare function resolveBail(cliValue: boolean | undefined, pkg: Package, script: string, fallback: boolean): boolean;
|
|
209
213
|
export declare function resolveNumber(cliValue: number | undefined, pkg: Package, script: string, key: string, fallback: number): number;
|
|
210
214
|
export declare function resolveLogLevel(cliValue: LogLevel | undefined, pkg: Package, script: string, fallback: LogLevel): LogLevel;
|
|
215
|
+
declare module '../core/service.js' {
|
|
216
|
+
interface ServiceMap {
|
|
217
|
+
run: RunService;
|
|
218
|
+
}
|
|
219
|
+
}
|