rman 2.11.2 → 2.12.0
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/builtins/platforms/node/services/ci.service.d.ts +1 -1
- package/builtins/platforms/node/services/ci.service.js +2 -2
- package/builtins/platforms/node/services/clean.service.d.ts +1 -1
- package/builtins/platforms/node/services/clean.service.js +2 -2
- package/builtins/platforms/node/services/publish.service.d.ts +11 -4
- package/builtins/platforms/node/services/publish.service.js +48 -10
- package/builtins/publish-targets/npm/npm-publish-target.d.ts +3 -0
- package/builtins/publish-targets/npm/npm-publish-target.js +4 -0
- package/commands/changelog.command.js +1 -1
- package/commands/list.command.js +6 -0
- package/constants.js +1 -1
- package/core/classes/log-sink.d.ts +1 -1
- package/{utils → core/classes}/progress-panel.d.ts +1 -1
- package/core/classes/run-reporters.d.ts +1 -1
- package/core/interfaces/publish-target.d.ts +12 -0
- package/core/interfaces/publish-target.js +8 -0
- package/index.d.ts +2 -2
- package/index.js +2 -2
- package/package.json +1 -1
- package/services/exec.service.js +1 -1
- package/services/list.service.d.ts +5 -0
- package/services/list.service.js +13 -2
- package/services/run.service.d.ts +1 -1
- package/services/run.service.js +1 -1
- package/utils/status-region.js +1 -1
- /package/{utils → core/classes}/live-region.d.ts +0 -0
- /package/{utils → core/classes}/live-region.js +0 -0
- /package/{utils → core/classes}/progress-panel.js +0 -0
|
@@ -33,7 +33,7 @@ export declare namespace CiService {
|
|
|
33
33
|
* `"ci"` script, runs that instead. Once every package is clean, installs once at the root
|
|
34
34
|
* with the configured package manager (`npm`/`yarn`/`pnpm`/`bun`).
|
|
35
35
|
*
|
|
36
|
-
* Uses the same live progress panel as `run`/`build` (see
|
|
36
|
+
* Uses the same live progress panel as `run`/`build` (see `core/classes/progress-panel.ts`) while it
|
|
37
37
|
* runs, falling back to a plain rmdir/clean/run/install log line per step when the panel is off.
|
|
38
38
|
*
|
|
39
39
|
* Unlike `run`/`build`, it does *not* end with a per-package success tally: `ci`'s packages don't
|
|
@@ -2,9 +2,9 @@ import fs from 'node:fs/promises';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import colors from 'ansi-colors';
|
|
4
4
|
import { Logger, resolveRootLogLevel } from '../../../../core/classes/logger.js';
|
|
5
|
+
import { formatDuration, ProgressPanel } from '../../../../core/classes/progress-panel.js';
|
|
5
6
|
import { exec } from '../../../../utils/exec.js';
|
|
6
7
|
import { filterPackages } from '../../../../utils/package-filter.js';
|
|
7
|
-
import { formatDuration, ProgressPanel } from '../../../../utils/progress-panel.js';
|
|
8
8
|
export var CiService;
|
|
9
9
|
(function (CiService) {
|
|
10
10
|
/**
|
|
@@ -53,7 +53,7 @@ export var CiService;
|
|
|
53
53
|
* `"ci"` script, runs that instead. Once every package is clean, installs once at the root
|
|
54
54
|
* with the configured package manager (`npm`/`yarn`/`pnpm`/`bun`).
|
|
55
55
|
*
|
|
56
|
-
* Uses the same live progress panel as `run`/`build` (see
|
|
56
|
+
* Uses the same live progress panel as `run`/`build` (see `core/classes/progress-panel.ts`) while it
|
|
57
57
|
* runs, falling back to a plain rmdir/clean/run/install log line per step when the panel is off.
|
|
58
58
|
*
|
|
59
59
|
* Unlike `run`/`build`, it does *not* end with a per-package success tally: `ci`'s packages don't
|
|
@@ -46,7 +46,7 @@ export declare namespace CleanService {
|
|
|
46
46
|
* Run from inside a single package's own directory, it only cleans that package unless
|
|
47
47
|
* `options.fromRoot` says otherwise (see `Repository.currentPackage`).
|
|
48
48
|
*
|
|
49
|
-
* Uses the same live progress panel as `run`/`build` (see
|
|
49
|
+
* Uses the same live progress panel as `run`/`build` (see `core/classes/progress-panel.ts`) - unlike
|
|
50
50
|
* `ci`, cleaning genuinely is independent per-package work, so the final per-package tally stays.
|
|
51
51
|
*/
|
|
52
52
|
function clean(repository: Repository, options?: Options): Promise<void>;
|
|
@@ -3,8 +3,8 @@ import path from 'node:path';
|
|
|
3
3
|
import colors from 'ansi-colors';
|
|
4
4
|
import fg from 'fast-glob';
|
|
5
5
|
import { Logger, resolveRootLogLevel } from '../../../../core/classes/logger.js';
|
|
6
|
+
import { ProgressPanel } from '../../../../core/classes/progress-panel.js';
|
|
6
7
|
import { filterPackages } from '../../../../utils/package-filter.js';
|
|
7
|
-
import { ProgressPanel } from '../../../../utils/progress-panel.js';
|
|
8
8
|
export var CleanService;
|
|
9
9
|
(function (CleanService) {
|
|
10
10
|
/**
|
|
@@ -38,7 +38,7 @@ export var CleanService;
|
|
|
38
38
|
* Run from inside a single package's own directory, it only cleans that package unless
|
|
39
39
|
* `options.fromRoot` says otherwise (see `Repository.currentPackage`).
|
|
40
40
|
*
|
|
41
|
-
* Uses the same live progress panel as `run`/`build` (see
|
|
41
|
+
* Uses the same live progress panel as `run`/`build` (see `core/classes/progress-panel.ts`) - unlike
|
|
42
42
|
* `ci`, cleaning genuinely is independent per-package work, so the final per-package tally stays.
|
|
43
43
|
*/
|
|
44
44
|
async function clean(repository, options = {}) {
|
|
@@ -128,6 +128,11 @@ export declare namespace PublishService {
|
|
|
128
128
|
* excludes it for a real monorepo (it only doubles as "the" package in a single-package repo,
|
|
129
129
|
* where it's a normal candidate like any other).
|
|
130
130
|
*/
|
|
131
|
+
/**
|
|
132
|
+
* Why the npm target leaves `pkg` alone, from its manifest alone - `'private package'`, or
|
|
133
|
+
* `undefined` when it would be published. `rman list` asks this to grey a package out.
|
|
134
|
+
*/
|
|
135
|
+
function skipReason(pkg: Package, contentsOverride?: string): string | undefined;
|
|
131
136
|
function getPlan(repository: Repository, options?: Options, deps?: Deps): Promise<Entry[]>;
|
|
132
137
|
/**
|
|
133
138
|
* Publishes every `'publish'` entry in `plan`, topological order (already `plan`'s own order -
|
|
@@ -136,10 +141,12 @@ export declare namespace PublishService {
|
|
|
136
141
|
* landed on the registry first, and publishing is rare enough (once per release) that the
|
|
137
142
|
* simplicity is worth more than the parallelism `run` gets from `power-tasks`.
|
|
138
143
|
*
|
|
139
|
-
* If a package fails, every other still-pending entry
|
|
140
|
-
* `'error'` too and never attempted - publishing a package whose own new
|
|
141
|
-
* at a version that never actually reached the registry would hand
|
|
142
|
-
* A package's own failure doesn't stop unrelated packages elsewhere in
|
|
144
|
+
* If a package fails, every other still-pending entry that **a consumer's install needs it for**
|
|
145
|
+
* (transitively) is marked `'error'` too and never attempted - publishing a package whose own new
|
|
146
|
+
* dependency range points at a version that never actually reached the registry would hand
|
|
147
|
+
* consumers a broken install. A package's own failure doesn't stop unrelated packages elsewhere in
|
|
148
|
+
* the plan, though, nor one that lists it only where an install does not need it (see
|
|
149
|
+
* `consumerNeeds`).
|
|
143
150
|
*/
|
|
144
151
|
function applyPlan(repository: Repository, plan: Entry[], options?: ApplyOptions): Promise<Entry[]>;
|
|
145
152
|
}
|
|
@@ -153,6 +153,26 @@ export var PublishService;
|
|
|
153
153
|
* excludes it for a real monorepo (it only doubles as "the" package in a single-package repo,
|
|
154
154
|
* where it's a normal candidate like any other).
|
|
155
155
|
*/
|
|
156
|
+
/**
|
|
157
|
+
* Why the npm target leaves `pkg` alone, from its manifest alone - `'private package'`, or
|
|
158
|
+
* `undefined` when it would be published. `rman list` asks this to grey a package out.
|
|
159
|
+
*/
|
|
160
|
+
/* **The one statement of npm's `private` rule**, called by `getPlan` and by `NpmPublishTarget.
|
|
161
|
+
* skipReason` both, so the plan and the list cannot disagree. Two cases, both private:
|
|
162
|
+
* - **no `publishConfig`** (`privateBySource`) - private in the published manifest too, wherever it
|
|
163
|
+
* is published from;
|
|
164
|
+
* - **published in place** - the source manifest *is* the published one, so its `private` stands
|
|
165
|
+
* whatever else it declares.
|
|
166
|
+
* The second sat after the build-output check in `getPlan` and moved ahead of it unchanged:
|
|
167
|
+
* `hasBuildOutput` is always true in place, so nothing reached it any differently. */
|
|
168
|
+
function skipReason(pkg, contentsOverride) {
|
|
169
|
+
if (!pkg.manifest.raw.private)
|
|
170
|
+
return undefined;
|
|
171
|
+
if (privateBySource(pkg) || publishesInPlace(pkg, contentsOverride))
|
|
172
|
+
return 'private package';
|
|
173
|
+
return undefined;
|
|
174
|
+
}
|
|
175
|
+
PublishService.skipReason = skipReason;
|
|
156
176
|
async function getPlan(repository, options = {}, deps = {}) {
|
|
157
177
|
const git = new GitHelper({ cwd: repository.dirname });
|
|
158
178
|
const packages = filterPackages(repository.getPackages({ toposort: true }), options);
|
|
@@ -173,6 +193,7 @@ export var PublishService;
|
|
|
173
193
|
* finding that out after a round trip per package would be a slower way to the same
|
|
174
194
|
* refusal. */
|
|
175
195
|
const distTag = distTagFor(pkg, options.tag);
|
|
196
|
+
const privateReason = skipReason(pkg, options.contents);
|
|
176
197
|
if (retiredDirectoryKey(pkg)) {
|
|
177
198
|
entries.set(pkg.name, {
|
|
178
199
|
package: pkg,
|
|
@@ -189,8 +210,8 @@ export var PublishService;
|
|
|
189
210
|
reason: 'excluded via .rmanrc "publish.skip"',
|
|
190
211
|
});
|
|
191
212
|
}
|
|
192
|
-
else if (
|
|
193
|
-
entries.set(pkg.name, { package: pkg, version: pkg.version, status: 'skip', reason:
|
|
213
|
+
else if (privateReason) {
|
|
214
|
+
entries.set(pkg.name, { package: pkg, version: pkg.version, status: 'skip', reason: privateReason });
|
|
194
215
|
}
|
|
195
216
|
else if (!hasBuildOutput(pkg, options.contents)) {
|
|
196
217
|
const dir = path.relative(pkg.dirname, resolvePublishDir(pkg, options.contents)) || '.';
|
|
@@ -201,9 +222,6 @@ export var PublishService;
|
|
|
201
222
|
reason: `nothing to publish in "${dir}" - it is missing or empty; build the package first`,
|
|
202
223
|
});
|
|
203
224
|
}
|
|
204
|
-
else if (publishesInPlace(pkg, options.contents) && pkg.manifest.raw.private) {
|
|
205
|
-
entries.set(pkg.name, { package: pkg, version: pkg.version, status: 'skip', reason: 'private package' });
|
|
206
|
-
}
|
|
207
225
|
else if (distTag.error) {
|
|
208
226
|
entries.set(pkg.name, { package: pkg, version: pkg.version, status: 'error', reason: distTag.error });
|
|
209
227
|
}
|
|
@@ -259,10 +277,12 @@ export var PublishService;
|
|
|
259
277
|
* landed on the registry first, and publishing is rare enough (once per release) that the
|
|
260
278
|
* simplicity is worth more than the parallelism `run` gets from `power-tasks`.
|
|
261
279
|
*
|
|
262
|
-
* If a package fails, every other still-pending entry
|
|
263
|
-
* `'error'` too and never attempted - publishing a package whose own new
|
|
264
|
-
* at a version that never actually reached the registry would hand
|
|
265
|
-
* A package's own failure doesn't stop unrelated packages elsewhere in
|
|
280
|
+
* If a package fails, every other still-pending entry that **a consumer's install needs it for**
|
|
281
|
+
* (transitively) is marked `'error'` too and never attempted - publishing a package whose own new
|
|
282
|
+
* dependency range points at a version that never actually reached the registry would hand
|
|
283
|
+
* consumers a broken install. A package's own failure doesn't stop unrelated packages elsewhere in
|
|
284
|
+
* the plan, though, nor one that lists it only where an install does not need it (see
|
|
285
|
+
* `consumerNeeds`).
|
|
266
286
|
*/
|
|
267
287
|
async function applyPlan(repository, plan, options = {}) {
|
|
268
288
|
const packageManager = CiService.resolvePackageManager(repository, options.packageManager);
|
|
@@ -279,7 +299,7 @@ export var PublishService;
|
|
|
279
299
|
continue;
|
|
280
300
|
}
|
|
281
301
|
const pkg = entry.package;
|
|
282
|
-
const blocker = pkg.dependencies.find(d => failed.has(d.name));
|
|
302
|
+
const blocker = pkg.dependencies.find(d => failed.has(d.name) && consumerNeeds(pkg, d.name));
|
|
283
303
|
if (blocker) {
|
|
284
304
|
failed.add(pkg.name);
|
|
285
305
|
result.push({ ...entry, status: 'error', reason: `dependency "${blocker.name}" failed to publish` });
|
|
@@ -343,6 +363,24 @@ function resolvePublishDir(pkg, contentsOverride) {
|
|
|
343
363
|
function privateBySource(pkg) {
|
|
344
364
|
return !!pkg.manifest.raw.private && !pkg.manifest.raw.publishConfig;
|
|
345
365
|
}
|
|
366
|
+
/** Whether a consumer installing `pkg` needs `name` to resolve: a `dependencies` entry, or a peer
|
|
367
|
+
* not marked optional. */
|
|
368
|
+
/* **Not every edge blocks a publish**, and blocking on all of them cost a release. A failed publish
|
|
369
|
+
* stops its dependents because their published range would point at a version that is not there -
|
|
370
|
+
* which is only true of what reaches the consumer:
|
|
371
|
+
* - `devDependencies` are removed from the published manifest (`derivePublishManifest`);
|
|
372
|
+
* - an optional peer that cannot be satisfied does not fail an install;
|
|
373
|
+
* - `optionalDependencies` are the ones npm proceeds without "if it cannot be found or fails to
|
|
374
|
+
* install" (npm's own documentation; not measured here).
|
|
375
|
+
* Measured on opra's 1.31.0 release: `@opra/api-ui` failed its first publish, and `@opra/http` -
|
|
376
|
+
* which lists it as an optional peer and a devDependency only - was blocked, taking elastic, mongodb
|
|
377
|
+
* and sqb with it, though none of their installs would have needed api-ui. */
|
|
378
|
+
function consumerNeeds(pkg, name) {
|
|
379
|
+
const raw = pkg.manifest.raw;
|
|
380
|
+
if (raw.dependencies?.[name] !== undefined)
|
|
381
|
+
return true;
|
|
382
|
+
return raw.peerDependencies?.[name] !== undefined && !raw.peerDependenciesMeta?.[name]?.optional;
|
|
383
|
+
}
|
|
346
384
|
/** Whether `pkg` is published from its own directory, whose `package.json` is then the manifest. */
|
|
347
385
|
/* In place, `private` is the source's whatever `publishConfig` says - npm refuses to publish it. */
|
|
348
386
|
function publishesInPlace(pkg, contentsOverride) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Package } from '../../../core/classes/package.js';
|
|
1
2
|
import type { PublishTarget } from '../../../core/interfaces/publish-target.js';
|
|
2
3
|
import { PublishService } from '../../platforms/node/services/publish.service.js';
|
|
3
4
|
/** The name this target answers to in `publish.target` and `--target`. */
|
|
@@ -70,6 +71,8 @@ export declare class NpmPublishTarget implements PublishTarget {
|
|
|
70
71
|
type: "string";
|
|
71
72
|
};
|
|
72
73
|
};
|
|
74
|
+
/** npm's `private` rule, the same function `getPlan` asks. */
|
|
75
|
+
skipReason(pkg: Package): string | undefined;
|
|
73
76
|
getPlan(ctx: PublishTarget.Context): Promise<PublishService.Entry[]>;
|
|
74
77
|
applyPlan(ctx: PublishTarget.Context, plan: PublishTarget.Entry[]): Promise<PublishService.Entry[]>;
|
|
75
78
|
/** The shared filters plus the two flags both halves need - read here rather than in the
|
|
@@ -75,6 +75,10 @@ export class NpmPublishTarget {
|
|
|
75
75
|
type: 'string',
|
|
76
76
|
},
|
|
77
77
|
};
|
|
78
|
+
/** npm's `private` rule, the same function `getPlan` asks. */
|
|
79
|
+
skipReason(pkg) {
|
|
80
|
+
return PublishService.skipReason(pkg);
|
|
81
|
+
}
|
|
78
82
|
getPlan(ctx) {
|
|
79
83
|
return PublishService.getPlan(ctx.repository, this.planOptions(ctx));
|
|
80
84
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import colors from 'ansi-colors';
|
|
3
3
|
import { Logger, resolveRootLogLevel } from '../core/classes/logger.js';
|
|
4
|
+
import { ProgressPanel } from '../core/classes/progress-panel.js';
|
|
4
5
|
import { registerCommand } from '../interfaces/rman-config.interface.js';
|
|
5
6
|
import { ChangeHashService } from '../services/change-hash.service.js';
|
|
6
7
|
import { fromRootOption, packageFilterOptions, readPackageFilterOptions } from '../utils/package-filter.js';
|
|
7
|
-
import { ProgressPanel } from '../utils/progress-panel.js';
|
|
8
8
|
const COMMAND = 'changelog';
|
|
9
9
|
const config = {
|
|
10
10
|
...packageFilterOptions,
|
package/commands/list.command.js
CHANGED
|
@@ -100,6 +100,11 @@ function statusLabel(status) {
|
|
|
100
100
|
return '';
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
|
+
/** Where a package ships, one target name each - grey for a target `publish` would skip it for
|
|
104
|
+
* (`Item.skippedTargets`), so the column never reads as a promise the release will not keep. */
|
|
105
|
+
function publishLabel(it) {
|
|
106
|
+
return it.publishTargets.map(name => (it.skippedTargets[name] ? colors.gray(name) : colors.green(name))).join(', ');
|
|
107
|
+
}
|
|
103
108
|
/**
|
|
104
109
|
* **The tree, as a table**: the root first, then each package indented by how far below it sits.
|
|
105
110
|
*
|
|
@@ -126,6 +131,7 @@ function printTable(items, withRoot) {
|
|
|
126
131
|
table.cell('Version', colors.yellow(it.version));
|
|
127
132
|
table.cell('Platform', it.platform ? colors.cyan(it.platform) : '');
|
|
128
133
|
table.cell('Private', it.private ? colors.magentaBright('yes') : '');
|
|
134
|
+
table.cell('Publish', publishLabel(it));
|
|
129
135
|
table.cell('Changed', statusLabel(it.status));
|
|
130
136
|
table.cell('Path', it.location);
|
|
131
137
|
table.newRow();
|
package/constants.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '2.
|
|
1
|
+
export const version = '2.12.0';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ProgressItem } from '../../utils/progress-panel.js';
|
|
2
1
|
import type { LogLevel } from './logger.js';
|
|
2
|
+
import type { ProgressItem } from './progress-panel.js';
|
|
3
3
|
/**
|
|
4
4
|
* One thing that happened during a run, in the order it happened. The JSON form is exactly this
|
|
5
5
|
* object with a `time` added; the text form is one line per event.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { StatusRegion, TerminalRegion } from '../../utils/status-region.js';
|
|
1
2
|
import { LiveRegion } from './live-region.js';
|
|
2
|
-
import type { StatusRegion, TerminalRegion } from './status-region.js';
|
|
3
3
|
export type ProgressStatus = 'pending' | 'running' | 'success' | 'failed' | 'skipped';
|
|
4
4
|
export interface ProgressItem {
|
|
5
5
|
readonly name: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { ProgressPanel } from '../../utils/progress-panel.js';
|
|
2
1
|
import type { LogEvent, Reporter, ReportOrigin } from './log-sink.js';
|
|
3
2
|
import { type LogLevel } from './logger.js';
|
|
3
|
+
import type { ProgressPanel } from './progress-panel.js';
|
|
4
4
|
/**
|
|
5
5
|
* The screen with no live panel: each line a step prints, led by its package, and one line per step
|
|
6
6
|
* when it ends - the output `--no-progress`, a pipe or CI gets.
|
|
@@ -61,6 +61,14 @@ export interface PublishTarget {
|
|
|
61
61
|
* let through.
|
|
62
62
|
*/
|
|
63
63
|
claims?(pkg: Package): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Why this target would leave a package it ships to alone, or `undefined` when it would not -
|
|
66
|
+
* answered from the config and the manifest alone, with no registry and no build.
|
|
67
|
+
*
|
|
68
|
+
* `publish.skip` is the core's and is asked before this (see `skipReasonFor`); a target answers
|
|
69
|
+
* only what is its own, such as npm's `private`.
|
|
70
|
+
*/
|
|
71
|
+
skipReason?(pkg: Package): string | undefined;
|
|
64
72
|
/** What this target *would* do - never publishes. Called even under `--dry-run`, which is the
|
|
65
73
|
* whole point of the split. */
|
|
66
74
|
getPlan(ctx: PublishTarget.Context): Promise<PublishTarget.Entry[]>;
|
|
@@ -131,6 +139,10 @@ export declare function shipsTo(pkg: Package, target: PublishTarget): boolean;
|
|
|
131
139
|
/** Every registered target `pkg` ships to, in registration order. The single answer to "where does
|
|
132
140
|
* this package go", so `publish` and `list --json` cannot disagree about it. */
|
|
133
141
|
export declare function targetsOf(app: RmanApplication, pkg: Package): PublishTarget[];
|
|
142
|
+
/** Why `target` would leave `pkg` alone, or `undefined` when it would publish it: `.rmanrc
|
|
143
|
+
* "publish.skip"`, which excludes a package from every target, and then the target's own
|
|
144
|
+
* `skipReason`. */
|
|
145
|
+
export declare function skipReasonFor(pkg: Package, target: PublishTarget): string | undefined;
|
|
134
146
|
/** Names in a package's `publish.target` that no registered target answers to - a misconfiguration
|
|
135
147
|
* that used to be caught by a `choices: ['npm', 'docker']` the core can no longer write down. */
|
|
136
148
|
export declare function unknownTargets(app: RmanApplication, pkg: Package): string[];
|
|
@@ -32,6 +32,14 @@ export function shipsTo(pkg, target) {
|
|
|
32
32
|
export function targetsOf(app, pkg) {
|
|
33
33
|
return app.publishTargets.all.filter(target => shipsTo(pkg, target));
|
|
34
34
|
}
|
|
35
|
+
/** Why `target` would leave `pkg` alone, or `undefined` when it would publish it: `.rmanrc
|
|
36
|
+
* "publish.skip"`, which excludes a package from every target, and then the target's own
|
|
37
|
+
* `skipReason`. */
|
|
38
|
+
export function skipReasonFor(pkg, target) {
|
|
39
|
+
if (pkg.config.publish?.skip)
|
|
40
|
+
return 'excluded via .rmanrc "publish.skip"';
|
|
41
|
+
return target.skipReason?.(pkg);
|
|
42
|
+
}
|
|
35
43
|
/** Names in a package's `publish.target` that no registered target answers to - a misconfiguration
|
|
36
44
|
* that used to be caught by a `choices: ['npm', 'docker']` the core can no longer write down. */
|
|
37
45
|
export function unknownTargets(app, pkg) {
|
package/index.d.ts
CHANGED
|
@@ -65,7 +65,7 @@ export { Manifest } from './core/interfaces/manifest.js';
|
|
|
65
65
|
export { Registry } from './core/classes/registry.js';
|
|
66
66
|
export { Repository } from './core/classes/repository.js';
|
|
67
67
|
export { Service, type ServiceFactory, type ServiceMap } from './core/classes/service.js';
|
|
68
|
-
export { declaredTargets, type PublishTarget, shipsTo, targetsOf, unknownTargets, } from './core/interfaces/publish-target.js';
|
|
68
|
+
export { declaredTargets, type PublishTarget, shipsTo, skipReasonFor, targetsOf, unknownTargets, } from './core/interfaces/publish-target.js';
|
|
69
69
|
export type { RunConditionFn, RunStepContext, RunStepFn, RunStepObject, RunStepValue, } from './core/interfaces/run-step.js';
|
|
70
70
|
/**
|
|
71
71
|
* **`Platform` is one technology, whole**; **`Plugin` is whatever a package contributes**, platforms
|
|
@@ -145,7 +145,7 @@ export { GitHelper } from './utils/git.js';
|
|
|
145
145
|
export { applyFromRootOption, applyPackageFilterOptions, filterPackages, fromRootOption, type PackageFilterOptions, packageFilterOptions, readFromRootOption, readPackageFilterOptions, ROOT_SELECTOR, } from './utils/package-filter.js';
|
|
146
146
|
/** The live panel `run`/`build`/`clean` print - a plugin's per-package command looks like the rest
|
|
147
147
|
* of rman instead of like a script someone bolted on. */
|
|
148
|
-
export { formatDuration, type ProgressItem, ProgressPanel, type ProgressStatus, type ProgressSummary, } from './
|
|
148
|
+
export { formatDuration, type ProgressItem, ProgressPanel, type ProgressStatus, type ProgressSummary, } from './core/classes/progress-panel.js';
|
|
149
149
|
/** Version stamping helpers a `Plugin.stampVersion` can delegate to - the quoted-constant
|
|
150
150
|
* pattern most languages share, and the OCI Dockerfile label (which `version` stamps itself, since
|
|
151
151
|
* the label's value is by specification the package's version). */
|
package/index.js
CHANGED
|
@@ -71,7 +71,7 @@ export { Manifest } from './core/interfaces/manifest.js';
|
|
|
71
71
|
export { Registry } from './core/classes/registry.js';
|
|
72
72
|
export { Repository } from './core/classes/repository.js';
|
|
73
73
|
export { Service } from './core/classes/service.js';
|
|
74
|
-
export { declaredTargets, shipsTo, targetsOf, unknownTargets, } from './core/interfaces/publish-target.js';
|
|
74
|
+
export { declaredTargets, shipsTo, skipReasonFor, targetsOf, unknownTargets, } from './core/interfaces/publish-target.js';
|
|
75
75
|
export { basePlatform, definePlatform, definePlugin, isPlatform, } from './core/interfaces/plugin.js';
|
|
76
76
|
/** The numbering seam. `VersionScheme` is abstract - `highestVersion`/`highestBump`/`smallestBump`
|
|
77
77
|
* are implemented from the members around them, so a scheme states only what it must and still
|
|
@@ -128,7 +128,7 @@ export { GitHelper } from './utils/git.js';
|
|
|
128
128
|
export { applyFromRootOption, applyPackageFilterOptions, filterPackages, fromRootOption, packageFilterOptions, readFromRootOption, readPackageFilterOptions, ROOT_SELECTOR, } from './utils/package-filter.js';
|
|
129
129
|
/** The live panel `run`/`build`/`clean` print - a plugin's per-package command looks like the rest
|
|
130
130
|
* of rman instead of like a script someone bolted on. */
|
|
131
|
-
export { formatDuration, ProgressPanel, } from './
|
|
131
|
+
export { formatDuration, ProgressPanel, } from './core/classes/progress-panel.js';
|
|
132
132
|
export { CiService } from './builtins/platforms/node/services/ci.service.js';
|
|
133
133
|
export { CleanService } from './builtins/platforms/node/services/clean.service.js';
|
|
134
134
|
export { PublishService } from './builtins/platforms/node/services/publish.service.js';
|
package/package.json
CHANGED
package/services/exec.service.js
CHANGED
|
@@ -2,10 +2,10 @@ import os from 'node:os';
|
|
|
2
2
|
import colors from 'ansi-colors';
|
|
3
3
|
import { Task } from 'power-tasks';
|
|
4
4
|
import { Logger, resolveRootLogLevel } from '../core/classes/logger.js';
|
|
5
|
+
import { ProgressPanel } from '../core/classes/progress-panel.js';
|
|
5
6
|
import { Service } from '../core/classes/service.js';
|
|
6
7
|
import { exec as execCommand } from '../utils/exec.js';
|
|
7
8
|
import { filterPackages } from '../utils/package-filter.js';
|
|
8
|
-
import { ProgressPanel } from '../utils/progress-panel.js';
|
|
9
9
|
/**
|
|
10
10
|
* A service class - see `ListService` for the shape and `Service` for the three measured
|
|
11
11
|
* consequences a namespace had. `repository` left the signature because the application carries it.
|
|
@@ -76,6 +76,11 @@ export declare namespace ListService {
|
|
|
76
76
|
* declares one, otherwise every registered target that claims it, which is the same question
|
|
77
77
|
* `publish` asks. Empty in a repository whose plugins contribute no target the package fits. */
|
|
78
78
|
publishTargets: PublishTargetName[];
|
|
79
|
+
/** The entries of `publishTargets` that `publish` would leave this package alone for, each with
|
|
80
|
+
* why - `.rmanrc "publish.skip"`, or the target's own rule (npm's `private`). Decided without the
|
|
81
|
+
* registry, so `{}` means "a candidate", not "will publish": whether the version is already out
|
|
82
|
+
* there is `publish --dry-run`'s answer. */
|
|
83
|
+
skippedTargets: Record<PublishTargetName, string>;
|
|
79
84
|
/** Present only when `"docker"` is one of `publishTargets` and `publish.docker` is configured -
|
|
80
85
|
* the raw `.rmanrc` config, unresolved (no namespace prefixing - see `DockerPublishService`). */
|
|
81
86
|
docker?: DockerPublishOptions;
|
package/services/list.service.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import { Service } from '../core/classes/service.js';
|
|
3
|
-
import { targetsOf } from '../core/interfaces/publish-target.js';
|
|
3
|
+
import { skipReasonFor, targetsOf } from '../core/interfaces/publish-target.js';
|
|
4
4
|
import { filterPackages } from '../utils/package-filter.js';
|
|
5
5
|
/**
|
|
6
6
|
* **A class, and the shape every service follows now.**
|
|
@@ -33,7 +33,17 @@ export class ListService extends Service {
|
|
|
33
33
|
/** **Asked, not assumed.** This read the config key directly and defaulted to `['npm']`, so a
|
|
34
34
|
* Cargo package in a polyglot repository was reported as shipping to npm - which is what
|
|
35
35
|
* `PublishTarget.claims` exists to answer, per target, from the ecosystem that knows. */
|
|
36
|
-
|
|
36
|
+
/** **A monorepo's root ships nowhere**: `publish` never makes it a candidate
|
|
37
|
+
* (`repository.getPackages()` leaves it out), so listing the target a root *would* claim
|
|
38
|
+
* says something no command does. */
|
|
39
|
+
const targets = p === repository.rootPackage && repository.monorepo ? [] : targetsOf(this.app, p);
|
|
40
|
+
const publishTargets = targets.map(t => t.name);
|
|
41
|
+
const skippedTargets = {};
|
|
42
|
+
for (const target of targets) {
|
|
43
|
+
const reason = skipReasonFor(p, target);
|
|
44
|
+
if (reason)
|
|
45
|
+
skippedTargets[target.name] = reason;
|
|
46
|
+
}
|
|
37
47
|
return {
|
|
38
48
|
name: p.name,
|
|
39
49
|
selector: p.selector,
|
|
@@ -46,6 +56,7 @@ export class ListService extends Service {
|
|
|
46
56
|
status: status[p.selector],
|
|
47
57
|
dependencies: p.dependencies.map(d => d.name),
|
|
48
58
|
publishTargets: [...publishTargets],
|
|
59
|
+
skippedTargets,
|
|
49
60
|
docker: publishTargets.includes('docker') ? p.config.publish?.docker : undefined,
|
|
50
61
|
};
|
|
51
62
|
};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { Reporter } from '../core/classes/log-sink.js';
|
|
2
2
|
import { type LogLevel } from '../core/classes/logger.js';
|
|
3
3
|
import type { Package } from '../core/classes/package.js';
|
|
4
|
+
import { ProgressPanel } from '../core/classes/progress-panel.js';
|
|
4
5
|
import type { Repository } from '../core/classes/repository.js';
|
|
5
6
|
import { Service } from '../core/classes/service.js';
|
|
6
7
|
import type { RunStepContext, RunStepFn, RunStepValue } from '../core/interfaces/run-step.js';
|
|
7
8
|
import { type PackageFilterOptions } from '../utils/package-filter.js';
|
|
8
|
-
import { ProgressPanel } from '../utils/progress-panel.js';
|
|
9
9
|
/**
|
|
10
10
|
* A service class - see `ListService` for the shape and `Service` for the three measured
|
|
11
11
|
* consequences a namespace had.
|
package/services/run.service.js
CHANGED
|
@@ -5,11 +5,11 @@ import colors from 'ansi-colors';
|
|
|
5
5
|
import { tokenize } from 'fast-tokenizer';
|
|
6
6
|
import { Task } from 'power-tasks';
|
|
7
7
|
import { LOG_LEVELS, Logger, resolveRootLogLevel } from '../core/classes/logger.js';
|
|
8
|
+
import { ProgressPanel } from '../core/classes/progress-panel.js';
|
|
8
9
|
import { PanelReporter, PlainReporter } from '../core/classes/run-reporters.js';
|
|
9
10
|
import { Service } from '../core/classes/service.js';
|
|
10
11
|
import { exec } from '../utils/exec.js';
|
|
11
12
|
import { filterPackages } from '../utils/package-filter.js';
|
|
12
|
-
import { ProgressPanel } from '../utils/progress-panel.js';
|
|
13
13
|
import { runBin } from '../utils/run-bin.js';
|
|
14
14
|
/**
|
|
15
15
|
* A service class - see `ListService` for the shape and `Service` for the three measured
|
package/utils/status-region.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|