rman 2.0.0-beta.2 → 2.0.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -12
- package/{plugins/node/augmentation/rman.augmentation.d.ts → builtins/platforms/node/augmentation/rmanrc.augmentation.d.ts} +4 -5
- package/{plugins → builtins/platforms}/node/augmentation/system-info.augmentation.js +1 -1
- package/{plugins → builtins/platforms}/node/commands/ci.command.d.ts +5 -3
- package/{plugins → builtins/platforms}/node/commands/ci.command.js +6 -5
- package/{plugins → builtins/platforms}/node/commands/clean.command.d.ts +6 -4
- package/{plugins → builtins/platforms}/node/commands/clean.command.js +6 -5
- package/builtins/platforms/node/index.d.ts +8 -0
- package/builtins/platforms/node/index.js +8 -0
- package/{plugins → builtins/platforms}/node/node-config.interface.d.ts +1 -2
- package/{plugins → builtins/platforms}/node/node-manifest.provider.d.ts +3 -3
- package/{plugins → builtins/platforms}/node/node-manifest.provider.js +3 -3
- package/{plugins → builtins/platforms}/node/node.platform.d.ts +3 -3
- package/{plugins → builtins/platforms}/node/services/ci.service.d.ts +3 -3
- package/{plugins → builtins/platforms}/node/services/ci.service.js +4 -4
- package/{plugins → builtins/platforms}/node/services/clean.service.d.ts +3 -3
- package/{plugins → builtins/platforms}/node/services/clean.service.js +3 -3
- package/{plugins → builtins/platforms}/node/services/publish.service.d.ts +4 -4
- package/{plugins → builtins/platforms}/node/services/publish.service.js +13 -7
- package/{plugins → builtins/platforms}/node/services/version-plan.service.d.ts +3 -3
- package/{plugins → builtins/platforms}/node/services/version-plan.service.js +2 -2
- package/builtins/presets/index.d.ts +15 -0
- package/builtins/presets/index.js +57 -0
- package/builtins/presets/node.d.ts +16 -0
- package/builtins/presets/node.js +57 -0
- package/{services → builtins/publish-targets/docker}/docker-publish.service.d.ts +6 -6
- package/{services → builtins/publish-targets/docker}/docker-publish.service.js +9 -9
- package/{targets → builtins/publish-targets/docker}/docker.target.d.ts +6 -5
- package/{targets → builtins/publish-targets/docker}/docker.target.js +1 -1
- package/builtins/publish-targets/docker/index.d.ts +2 -0
- package/builtins/publish-targets/docker/index.js +2 -0
- package/builtins/publish-targets/npm/index.d.ts +2 -0
- package/builtins/publish-targets/npm/index.js +2 -0
- package/{plugins/node → builtins/publish-targets/npm}/npm-publish-target.d.ts +4 -4
- package/{plugins/node → builtins/publish-targets/npm}/npm-publish-target.js +4 -5
- package/cli.d.ts +3 -0
- package/cli.js +16 -7
- package/commands/changelog.command.d.ts +106 -2
- package/commands/changelog.command.js +40 -0
- package/commands/config.command.js +23 -5
- package/commands/list.command.js +1 -1
- package/commands/publish.command.d.ts +1 -1
- package/commands/publish.command.js +1 -1
- package/commands/run.command.js +1 -1
- package/commands/version.command.d.ts +16 -3
- package/commands/version.command.js +143 -9
- package/commands.d.ts +0 -1
- package/commands.js +0 -1
- package/constants.js +1 -1
- package/core/application.d.ts +10 -10
- package/core/application.js +28 -11
- package/core/{package.d.ts → classes/package.d.ts} +12 -4
- package/core/{package.js → classes/package.js} +17 -1
- package/core/{repository.d.ts → classes/repository.d.ts} +22 -36
- package/core/{repository.js → classes/repository.js} +112 -241
- package/core/{service.d.ts → classes/service.d.ts} +2 -2
- package/core/classes/workspace.d.ts +277 -0
- package/core/classes/workspace.js +585 -0
- package/core/command-builder.js +17 -1
- package/core/config/config-file-scope.d.ts +107 -0
- package/core/config/config-file-scope.js +226 -0
- package/core/config/config-interpolator.d.ts +164 -0
- package/core/config/config-interpolator.js +577 -0
- package/core/config/config-paths.d.ts +65 -0
- package/core/config/config-paths.js +78 -0
- package/core/config/config-reader.d.ts +215 -0
- package/core/config/config-reader.js +851 -0
- package/core/{merge-config.js → config/merge-config.js} +4 -8
- package/core/{custom-command.d.ts → interfaces/custom-command.d.ts} +5 -5
- package/core/{manifest.d.ts → interfaces/manifest.d.ts} +3 -3
- package/core/{manifest.js → interfaces/manifest.js} +2 -2
- package/core/{plugin.d.ts → interfaces/plugin.d.ts} +44 -27
- package/core/{plugin.js → interfaces/plugin.js} +48 -10
- package/core/{publish-target.d.ts → interfaces/publish-target.d.ts} +24 -12
- package/core/{publish-target.js → interfaces/publish-target.js} +16 -3
- package/core/{run-step.d.ts → interfaces/run-step.d.ts} +4 -4
- package/core/plugin-loader.d.ts +11 -51
- package/core/plugin-loader.js +21 -202
- package/index.d.ts +29 -28
- package/index.js +20 -46
- package/interfaces/config-scope.interface.d.ts +223 -0
- package/interfaces/config-scope.interface.js +1 -0
- package/interfaces/rman-config.interface.d.ts +100 -5
- package/interfaces/rman-config.interface.js +17 -0
- package/package.json +3 -2
- package/services/change-hash.service.d.ts +40 -6
- package/services/change-hash.service.js +90 -11
- package/services/changelog.service.d.ts +31 -3
- package/services/changelog.service.js +448 -65
- package/services/config-service.d.ts +8 -0
- package/services/config-service.js +3 -0
- package/services/exec.service.d.ts +2 -2
- package/services/exec.service.js +1 -1
- package/services/github-release.service.d.ts +3 -3
- package/services/github-release.service.js +3 -3
- package/services/import.service.d.ts +2 -2
- package/services/import.service.js +1 -1
- package/services/list.service.d.ts +9 -7
- package/services/list.service.js +2 -2
- package/services/run.service.d.ts +15 -11
- package/services/run.service.js +62 -18
- package/services/system-info.d.ts +1 -1
- package/services/version-plan.service.d.ts +8 -4
- package/services/version-plan.service.js +54 -21
- package/services/version.service.d.ts +5 -5
- package/services/version.service.js +7 -4
- package/services.d.ts +1 -1
- package/services.js +1 -1
- package/utils/branch-guard.d.ts +1 -1
- package/utils/color-yaml.d.ts +8 -0
- package/utils/color-yaml.js +86 -0
- package/utils/git.d.ts +26 -0
- package/utils/git.js +65 -0
- package/utils/logger.d.ts +1 -1
- package/utils/package-filter.d.ts +8 -1
- package/utils/package-filter.js +7 -0
- package/utils/printable-config.d.ts +8 -0
- package/utils/printable-config.js +45 -0
- package/utils/progress-panel.d.ts +9 -0
- package/utils/progress-panel.js +23 -1
- package/utils/release-version.d.ts +1 -1
- package/utils/run-options.js +1 -1
- package/utils/version-group.d.ts +31 -0
- package/utils/version-group.js +43 -0
- package/commands/changed.command.d.ts +0 -80
- package/commands/changed.command.js +0 -36
- package/core/config.d.ts +0 -530
- package/core/config.js +0 -1123
- package/core/core-services.d.ts +0 -14
- package/core/core-services.js +0 -30
- package/core/core-targets.d.ts +0 -14
- package/core/core-targets.js +0 -16
- package/core/extends-config.d.ts +0 -35
- package/core/extends-config.js +0 -129
- package/core/load-config-module.d.ts +0 -28
- package/core/load-config-module.js +0 -42
- package/core/workspace.d.ts +0 -119
- package/core/workspace.js +0 -124
- package/plugins/builtins.d.ts +0 -44
- package/plugins/builtins.js +0 -33
- package/plugins/detect.d.ts +0 -78
- package/plugins/detect.js +0 -70
- package/plugins/node/index.d.ts +0 -29
- package/plugins/node/index.js +0 -40
- /package/{core/run-step.js → builtins/platforms/node/augmentation/rmanrc.augmentation.js} +0 -0
- /package/{plugins → builtins/platforms}/node/augmentation/system-info.augmentation.d.ts +0 -0
- /package/{plugins → builtins/platforms}/node/node-config.interface.js +0 -0
- /package/{plugins → builtins/platforms}/node/node.platform.js +0 -0
- /package/{plugins → builtins/platforms}/node/utils/workspace-range.d.ts +0 -0
- /package/{plugins → builtins/platforms}/node/utils/workspace-range.js +0 -0
- /package/{plugins/node/utils → builtins/publish-targets/npm}/npm-view.d.ts +0 -0
- /package/{plugins/node/utils → builtins/publish-targets/npm}/npm-view.js +0 -0
- /package/core/{registry.d.ts → classes/registry.d.ts} +0 -0
- /package/core/{registry.js → classes/registry.js} +0 -0
- /package/core/{service.js → classes/service.js} +0 -0
- /package/core/{version-scheme.d.ts → classes/version-scheme.d.ts} +0 -0
- /package/core/{version-scheme.js → classes/version-scheme.js} +0 -0
- /package/core/{merge-config.d.ts → config/merge-config.d.ts} +0 -0
- /package/core/{resolve-target.d.ts → config/resolve-config-target.d.ts} +0 -0
- /package/core/{resolve-target.js → config/resolve-config-target.js} +0 -0
- /package/core/{custom-command.js → interfaces/custom-command.js} +0 -0
- /package/{plugins/node/augmentation/rman.augmentation.js → core/interfaces/run-step.js} +0 -0
package/core/core-services.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { RmanApplication } from './application.js';
|
|
2
|
-
/**
|
|
3
|
-
* Every service the core brings, registered as an application is built.
|
|
4
|
-
*
|
|
5
|
-
* **Factories rather than instances**, so nothing is constructed until something asks: `rman info`
|
|
6
|
-
* has no business building the changelog or release services, and services reach each other through
|
|
7
|
-
* the application, so resolving at call time is also what keeps that from being a construction
|
|
8
|
-
* cycle.
|
|
9
|
-
*
|
|
10
|
-
* Here rather than inside `RmanApplication` so the composition list is one readable file, and so
|
|
11
|
-
* the application itself imports no service - only this does. A plugin adds its own the same way,
|
|
12
|
-
* from its own package, with `app.setService`.
|
|
13
|
-
*/
|
|
14
|
-
export declare function registerCoreServices(app: RmanApplication): void;
|
package/core/core-services.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { ChangelogService } from '../services/changelog.service.js';
|
|
2
|
-
import { DockerPublishService } from '../services/docker-publish.service.js';
|
|
3
|
-
import { ExecService } from '../services/exec.service.js';
|
|
4
|
-
import { GithubReleaseService } from '../services/github-release.service.js';
|
|
5
|
-
import { ImportService } from '../services/import.service.js';
|
|
6
|
-
import { ListService } from '../services/list.service.js';
|
|
7
|
-
import { RunService } from '../services/run.service.js';
|
|
8
|
-
import { VersionService } from '../services/version.service.js';
|
|
9
|
-
/**
|
|
10
|
-
* Every service the core brings, registered as an application is built.
|
|
11
|
-
*
|
|
12
|
-
* **Factories rather than instances**, so nothing is constructed until something asks: `rman info`
|
|
13
|
-
* has no business building the changelog or release services, and services reach each other through
|
|
14
|
-
* the application, so resolving at call time is also what keeps that from being a construction
|
|
15
|
-
* cycle.
|
|
16
|
-
*
|
|
17
|
-
* Here rather than inside `RmanApplication` so the composition list is one readable file, and so
|
|
18
|
-
* the application itself imports no service - only this does. A plugin adds its own the same way,
|
|
19
|
-
* from its own package, with `app.setService`.
|
|
20
|
-
*/
|
|
21
|
-
export function registerCoreServices(app) {
|
|
22
|
-
app.setService('changelog', a => new ChangelogService(a));
|
|
23
|
-
app.setService('dockerPublish', a => new DockerPublishService(a));
|
|
24
|
-
app.setService('githubRelease', a => new GithubReleaseService(a));
|
|
25
|
-
app.setService('exec', a => new ExecService(a));
|
|
26
|
-
app.setService('import', a => new ImportService(a));
|
|
27
|
-
app.setService('list', a => new ListService(a));
|
|
28
|
-
app.setService('run', a => new RunService(a));
|
|
29
|
-
app.setService('version', a => new VersionService(a));
|
|
30
|
-
}
|
package/core/core-targets.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { RmanApplication } from './application.js';
|
|
2
|
-
/**
|
|
3
|
-
* Every publish target the core brings, registered as an application is built - `registerCoreServices`
|
|
4
|
-
* for the other half of what a fresh application starts with.
|
|
5
|
-
*
|
|
6
|
-
* Exactly one today, and that is the point: `docker` is the target that belongs to no ecosystem, so
|
|
7
|
-
* it is the only one the core can honestly ship. `npm` arrives with the `node` built-in, and a Cargo or
|
|
8
|
-
* Maven target would arrive from its own plugin the same way.
|
|
9
|
-
*
|
|
10
|
-
* A separate file from `core-services.ts` rather than a second call inside it: a target is not a
|
|
11
|
-
* service (it is a contribution summed with others, not one replaceable answer), and a function
|
|
12
|
-
* called `registerCoreServices` that also registered targets would have to be read to be believed.
|
|
13
|
-
*/
|
|
14
|
-
export declare function registerCoreTargets(app: RmanApplication): void;
|
package/core/core-targets.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { dockerPublishTarget } from '../targets/docker.target.js';
|
|
2
|
-
/**
|
|
3
|
-
* Every publish target the core brings, registered as an application is built - `registerCoreServices`
|
|
4
|
-
* for the other half of what a fresh application starts with.
|
|
5
|
-
*
|
|
6
|
-
* Exactly one today, and that is the point: `docker` is the target that belongs to no ecosystem, so
|
|
7
|
-
* it is the only one the core can honestly ship. `npm` arrives with the `node` built-in, and a Cargo or
|
|
8
|
-
* Maven target would arrive from its own plugin the same way.
|
|
9
|
-
*
|
|
10
|
-
* A separate file from `core-services.ts` rather than a second call inside it: a target is not a
|
|
11
|
-
* service (it is a contribution summed with others, not one replaceable answer), and a function
|
|
12
|
-
* called `registerCoreServices` that also registered targets would have to be read to be believed.
|
|
13
|
-
*/
|
|
14
|
-
export function registerCoreTargets(app) {
|
|
15
|
-
app.publishTargets.add(dockerPublishTarget);
|
|
16
|
-
}
|
package/core/extends-config.d.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import type { RmanConfig } from '../interfaces/rman-config.interface.js';
|
|
2
|
-
/** The key naming configs to inherit from, the way eslint and tsconfig spell it. */
|
|
3
|
-
export declare const EXTENDS_KEY = "extends";
|
|
4
|
-
/**
|
|
5
|
-
* Resolves `config`'s own `extends` into it: every named config is loaded, merged in declaration
|
|
6
|
-
* order, and `config`'s own keys land on top. Returns a new object with no `extends` left in it.
|
|
7
|
-
*
|
|
8
|
-
* The point is a shared package - `extends: "@panates/rman-monorepo"` - so a repository declares
|
|
9
|
-
* its house rules once instead of restating them. `+key` is what makes that liveable (see
|
|
10
|
-
* `mergeConfig`): without it, adding one step to a base's list means copying the list.
|
|
11
|
-
*
|
|
12
|
-
* `from` is the file the `extends` was written in, and everything resolves relative to **it**: a
|
|
13
|
-
* bare specifier through that file's own `node_modules`, a relative path against its directory.
|
|
14
|
-
* Resolving from rman's own location instead would look in rman's dependencies, where a
|
|
15
|
-
* repository's shared config has no reason to be.
|
|
16
|
-
*
|
|
17
|
-
* `seen` carries the chain being resolved, so a config that extends its way back to itself is
|
|
18
|
-
* reported rather than recursed into forever.
|
|
19
|
-
*/
|
|
20
|
-
export declare function resolveExtends(config: RmanConfig, from: string, seen?: string[]): Promise<RmanConfig>;
|
|
21
|
-
/**
|
|
22
|
-
* **Refuses the keys a `"[selector]"` block cannot carry** - each for its own reason, and the
|
|
23
|
-
* reason is the same shape every time: a selector block is typed as a whole `RmanConfig`, so any
|
|
24
|
-
* key looks valid there, and one that can never be read is a config that quietly does nothing.
|
|
25
|
-
* That is worse than one that will not load.
|
|
26
|
-
*
|
|
27
|
-
* - **`extends`** is a statement about the *file*, not about the packages a selector happens to
|
|
28
|
-
* name, and it belongs at the top level where it would actually be resolved.
|
|
29
|
-
* - **`platform` and `name`** are what the selector is derived *from*, so a glob block setting
|
|
30
|
-
* either would need its own answer in order to be matched. See below; `"[/]"` is exempt.
|
|
31
|
-
*
|
|
32
|
-
* Called on every config form a directory can hold and on every `extends` base, so the file in the
|
|
33
|
-
* message is the one the line was written in.
|
|
34
|
-
*/
|
|
35
|
-
export declare function assertSelectorBlocks(config: RmanConfig, file: string): void;
|
package/core/extends-config.js
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import * as yaml from 'js-yaml';
|
|
4
|
-
import { isSelectorKey, parseSelector } from './config.js';
|
|
5
|
-
import { loadConfigModule } from './load-config-module.js';
|
|
6
|
-
import { mergeConfig } from './merge-config.js';
|
|
7
|
-
import { resolveConfigTarget } from './resolve-target.js';
|
|
8
|
-
/** The key naming configs to inherit from, the way eslint and tsconfig spell it. */
|
|
9
|
-
export const EXTENDS_KEY = 'extends';
|
|
10
|
-
/**
|
|
11
|
-
* Resolves `config`'s own `extends` into it: every named config is loaded, merged in declaration
|
|
12
|
-
* order, and `config`'s own keys land on top. Returns a new object with no `extends` left in it.
|
|
13
|
-
*
|
|
14
|
-
* The point is a shared package - `extends: "@panates/rman-monorepo"` - so a repository declares
|
|
15
|
-
* its house rules once instead of restating them. `+key` is what makes that liveable (see
|
|
16
|
-
* `mergeConfig`): without it, adding one step to a base's list means copying the list.
|
|
17
|
-
*
|
|
18
|
-
* `from` is the file the `extends` was written in, and everything resolves relative to **it**: a
|
|
19
|
-
* bare specifier through that file's own `node_modules`, a relative path against its directory.
|
|
20
|
-
* Resolving from rman's own location instead would look in rman's dependencies, where a
|
|
21
|
-
* repository's shared config has no reason to be.
|
|
22
|
-
*
|
|
23
|
-
* `seen` carries the chain being resolved, so a config that extends its way back to itself is
|
|
24
|
-
* reported rather than recursed into forever.
|
|
25
|
-
*/
|
|
26
|
-
export async function resolveExtends(config, from, seen = []) {
|
|
27
|
-
const declared = config[EXTENDS_KEY];
|
|
28
|
-
if (declared === undefined)
|
|
29
|
-
return config;
|
|
30
|
-
const targets = Array.isArray(declared) ? declared : [declared];
|
|
31
|
-
for (const target of targets) {
|
|
32
|
-
if (typeof target !== 'string' || !target.trim()) {
|
|
33
|
-
throw new Error(`"extends" in "${from}" must be a config name or path, or an array of them`);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
const base = {};
|
|
37
|
-
for (const target of targets) {
|
|
38
|
-
const file = resolveConfigTarget(target, from, EXTENDS_KEY);
|
|
39
|
-
if (seen.includes(file)) {
|
|
40
|
-
throw new Error(`"extends" forms a cycle: ${[...seen, file].map(f => path.basename(f)).join(' -> ')}`);
|
|
41
|
-
}
|
|
42
|
-
const loaded = await loadConfigFile(file);
|
|
43
|
-
assertSelectorBlocks(loaded, file);
|
|
44
|
-
// Recursive: a shared config may itself be built on another.
|
|
45
|
-
mergeConfig(base, await resolveExtends(loaded, file, [...seen, file]), file);
|
|
46
|
-
}
|
|
47
|
-
const own = { ...config };
|
|
48
|
-
delete own[EXTENDS_KEY];
|
|
49
|
-
return mergeConfig(base, own);
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* **Refuses the keys a `"[selector]"` block cannot carry** - each for its own reason, and the
|
|
53
|
-
* reason is the same shape every time: a selector block is typed as a whole `RmanConfig`, so any
|
|
54
|
-
* key looks valid there, and one that can never be read is a config that quietly does nothing.
|
|
55
|
-
* That is worse than one that will not load.
|
|
56
|
-
*
|
|
57
|
-
* - **`extends`** is a statement about the *file*, not about the packages a selector happens to
|
|
58
|
-
* name, and it belongs at the top level where it would actually be resolved.
|
|
59
|
-
* - **`platform` and `name`** are what the selector is derived *from*, so a glob block setting
|
|
60
|
-
* either would need its own answer in order to be matched. See below; `"[/]"` is exempt.
|
|
61
|
-
*
|
|
62
|
-
* Called on every config form a directory can hold and on every `extends` base, so the file in the
|
|
63
|
-
* message is the one the line was written in.
|
|
64
|
-
*/
|
|
65
|
-
export function assertSelectorBlocks(config, file) {
|
|
66
|
-
for (const [key, value] of Object.entries(config)) {
|
|
67
|
-
if (!isSelectorKey(key) || !value || typeof value !== 'object')
|
|
68
|
-
continue;
|
|
69
|
-
if (EXTENDS_KEY in value) {
|
|
70
|
-
throw new Error(`"${key}" in "${file}" cannot use "extends" - it belongs at the top level, where it is a ` +
|
|
71
|
-
`statement about this config rather than about the packages the selector names.`);
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* **The two keys a selector cannot carry, because the selector is downstream of them.**
|
|
75
|
-
*
|
|
76
|
-
* A `"[glob]"` matches `Package.selector`, which comes from `name` - and which package a
|
|
77
|
-
* directory even holds comes from `platform`. Both are read from the *unmarked* cascade, while
|
|
78
|
-
* the packages are still being found, so a glob block setting either would need its own answer
|
|
79
|
-
* in order to be matched at all. Typed as a whole `RmanConfig`, both look valid there and both
|
|
80
|
-
* would simply never be read.
|
|
81
|
-
*
|
|
82
|
-
* `"[/]"` is exempt and keeps working: the root is addressed structurally - its directory *is*
|
|
83
|
-
* the repository root - so a root block needs no selector and is applied during the walk.
|
|
84
|
-
*/
|
|
85
|
-
if (parseSelector(key).scope === 'root')
|
|
86
|
-
continue;
|
|
87
|
-
for (const identity of IDENTITY_KEYS) {
|
|
88
|
-
if (identity in value) {
|
|
89
|
-
throw new Error(`"${key}" in "${file}" cannot set "${identity}" - a glob matches a package's selector, ` +
|
|
90
|
-
`and "${identity}" is what the selector is derived from, so the block could never be ` +
|
|
91
|
-
`matched in order to apply it. Write it unmarked, in the package's own ".rmanrc", or ` +
|
|
92
|
-
`under "[/]" for the root package.`);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Loads one resolved target. YAML and JSON are read directly; anything else goes through
|
|
99
|
-
* `loadConfigModule`, so a shared config can be a `defineConfig` module with real logic in it.
|
|
100
|
-
*
|
|
101
|
-
* **Through that function rather than a bare `await import()`, which is what this used to do.**
|
|
102
|
-
* The two are not equivalent under an ESM loader hook: a `.cjs` base came back as an empty object,
|
|
103
|
-
* and an empty object is a valid config, so it contributed nothing and said nothing. See there for
|
|
104
|
-
* the measurement - the same file loaded correctly when it was a *directory's* own `.rmanrc.cjs`,
|
|
105
|
-
* because that path always used the careful loader.
|
|
106
|
-
*/
|
|
107
|
-
async function loadConfigFile(file) {
|
|
108
|
-
const ext = path.extname(file);
|
|
109
|
-
if (ext === '.yml' || ext === '.yaml') {
|
|
110
|
-
const obj = yaml.load(fs.readFileSync(file, 'utf-8'));
|
|
111
|
-
return asConfig(obj, file);
|
|
112
|
-
}
|
|
113
|
-
if (ext === '.json')
|
|
114
|
-
return asConfig(JSON.parse(fs.readFileSync(file, 'utf-8')), file);
|
|
115
|
-
return asConfig(await loadConfigModule(file), file);
|
|
116
|
-
}
|
|
117
|
-
function asConfig(value, file) {
|
|
118
|
-
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
119
|
-
throw new Error(`"${file}" does not export an rman config object`);
|
|
120
|
-
}
|
|
121
|
-
const config = { ...value };
|
|
122
|
-
// Editor tooling only - meaningless once merged, and `additionalProperties` would reject it
|
|
123
|
-
// wherever it ended up.
|
|
124
|
-
delete config.$schema;
|
|
125
|
-
return config;
|
|
126
|
-
}
|
|
127
|
-
/** The keys that decide *what a package is* and *what addresses it*, read from the unmarked
|
|
128
|
-
* cascade before any package exists - see `assertSelectorBlocks`. */
|
|
129
|
-
const IDENTITY_KEYS = ['platform', 'name'];
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Loads a config module - a `.rmanrc.cjs`/`.mjs`/`.js`, or an `extends` target that is one.
|
|
3
|
-
*
|
|
4
|
-
* **`require()` first, and that is not an optimization.** A CommonJS module's `module.exports` is
|
|
5
|
-
* more reliably observed this way than through dynamic `import()`'s CJS-interop synthesis, which
|
|
6
|
-
* some ESM loader hooks - ts-node/swc-node-style transpilers registered via `--import` - can
|
|
7
|
-
* short-circuit into an **empty object**. `require()` throws `ERR_REQUIRE_ESM` for a genuinely-ESM
|
|
8
|
-
* file (`.mjs`, or `.js` under `"type": "module"`), and only then does this fall back to
|
|
9
|
-
* `import()`, the one case that actually needs it.
|
|
10
|
-
*
|
|
11
|
-
* Either path can hand back an ES module namespace rather than a plain object - Node's
|
|
12
|
-
* `require(esm)` support does this too, not just `import()` - so `.default` is preferred whenever
|
|
13
|
-
* present.
|
|
14
|
-
*
|
|
15
|
-
* **It lives here because `extends` needs it too, and did not have it.** A directory's own
|
|
16
|
-
* `.rmanrc.cjs` went through this while `extends-config.ts` used a bare `await import()`, so the
|
|
17
|
-
* *same file* loaded correctly as a directory's config and came back empty when another config
|
|
18
|
-
* named it - and an empty object is a valid config, so nothing was reported. Measured under mocha:
|
|
19
|
-
* a base declaring `"[*]": { version: { stamp: ['build'] } }`, reached by
|
|
20
|
-
* `extends: './base.cjs'`, contributed nothing; the identical fixture with `base.json` contributed
|
|
21
|
-
* normally, and the same `.cjs` worked from the CLI, where no loader hook is registered.
|
|
22
|
-
*
|
|
23
|
-
* `createRequire` is based on this module's own URL rather than on the config file. That is right
|
|
24
|
-
* here and *not* right for resolving a bare specifier - see `resolveConfigTarget`, which is based
|
|
25
|
-
* on the config file so a package name resolves through the repository's `node_modules` rather than
|
|
26
|
-
* rman's own. By the time a file reaches this function it is already an absolute path.
|
|
27
|
-
*/
|
|
28
|
-
export declare function loadConfigModule(file: string): Promise<any>;
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { createRequire } from 'node:module';
|
|
2
|
-
import { pathToFileURL } from 'node:url';
|
|
3
|
-
/**
|
|
4
|
-
* Loads a config module - a `.rmanrc.cjs`/`.mjs`/`.js`, or an `extends` target that is one.
|
|
5
|
-
*
|
|
6
|
-
* **`require()` first, and that is not an optimization.** A CommonJS module's `module.exports` is
|
|
7
|
-
* more reliably observed this way than through dynamic `import()`'s CJS-interop synthesis, which
|
|
8
|
-
* some ESM loader hooks - ts-node/swc-node-style transpilers registered via `--import` - can
|
|
9
|
-
* short-circuit into an **empty object**. `require()` throws `ERR_REQUIRE_ESM` for a genuinely-ESM
|
|
10
|
-
* file (`.mjs`, or `.js` under `"type": "module"`), and only then does this fall back to
|
|
11
|
-
* `import()`, the one case that actually needs it.
|
|
12
|
-
*
|
|
13
|
-
* Either path can hand back an ES module namespace rather than a plain object - Node's
|
|
14
|
-
* `require(esm)` support does this too, not just `import()` - so `.default` is preferred whenever
|
|
15
|
-
* present.
|
|
16
|
-
*
|
|
17
|
-
* **It lives here because `extends` needs it too, and did not have it.** A directory's own
|
|
18
|
-
* `.rmanrc.cjs` went through this while `extends-config.ts` used a bare `await import()`, so the
|
|
19
|
-
* *same file* loaded correctly as a directory's config and came back empty when another config
|
|
20
|
-
* named it - and an empty object is a valid config, so nothing was reported. Measured under mocha:
|
|
21
|
-
* a base declaring `"[*]": { version: { stamp: ['build'] } }`, reached by
|
|
22
|
-
* `extends: './base.cjs'`, contributed nothing; the identical fixture with `base.json` contributed
|
|
23
|
-
* normally, and the same `.cjs` worked from the CLI, where no loader hook is registered.
|
|
24
|
-
*
|
|
25
|
-
* `createRequire` is based on this module's own URL rather than on the config file. That is right
|
|
26
|
-
* here and *not* right for resolving a bare specifier - see `resolveConfigTarget`, which is based
|
|
27
|
-
* on the config file so a package name resolves through the repository's `node_modules` rather than
|
|
28
|
-
* rman's own. By the time a file reaches this function it is already an absolute path.
|
|
29
|
-
*/
|
|
30
|
-
export async function loadConfigModule(file) {
|
|
31
|
-
let mod;
|
|
32
|
-
try {
|
|
33
|
-
mod = requireConfigModule(file);
|
|
34
|
-
}
|
|
35
|
-
catch (e) {
|
|
36
|
-
if (e?.code !== 'ERR_REQUIRE_ESM')
|
|
37
|
-
throw e;
|
|
38
|
-
mod = await import(pathToFileURL(file).href);
|
|
39
|
-
}
|
|
40
|
-
return mod?.default ?? mod;
|
|
41
|
-
}
|
|
42
|
-
const requireConfigModule = createRequire(import.meta.url);
|
package/core/workspace.d.ts
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import type { RmanApplication } from './application.js';
|
|
2
|
-
import type { Platform } from './plugin.js';
|
|
3
|
-
/**
|
|
4
|
-
* How a repository is laid out, and who decides.
|
|
5
|
-
*
|
|
6
|
-
* A namespace for the same reason `Manifest` is one: it is what a plugin can *augment*
|
|
7
|
-
* (`declare module 'rman' { namespace Workspace { ... } }`), so whatever this seam grows later
|
|
8
|
-
* arrives as a member here rather than as another top-level export.
|
|
9
|
-
*/
|
|
10
|
-
export declare namespace Workspace {
|
|
11
|
-
/**
|
|
12
|
-
* **Where one directory's own child packages are** - the directories immediately below it that
|
|
13
|
-
* hold a package, as absolute paths. `undefined` for "this is not a directory I recognize".
|
|
14
|
-
*
|
|
15
|
-
* **A provider answers for one directory, not for the repository**, and that is the whole
|
|
16
|
-
* correction. It used to be `(root) => { root, packageDirs }`: asked once, at the top, by the
|
|
17
|
-
* first platform that recognized it - so in a polyglot repository the technology listed first in
|
|
18
|
-
* `plugins` decided which directories were packages *at all*. Measured, and documented as a known
|
|
19
|
-
* limitation for a year: a `Cargo.toml`-only package was simply not found until a provider that
|
|
20
|
-
* looks for both was listed first.
|
|
21
|
-
*
|
|
22
|
-
* Asked per directory, each platform only ever answers about its own packages - which is all a
|
|
23
|
-
* platform knows - and the recursion is the core's (see `walk`). A Cargo workspace nested inside
|
|
24
|
-
* a Node monorepo is then just a node in the tree whose children came from a different platform.
|
|
25
|
-
*
|
|
26
|
-
* **Children, not descendants.** A provider returning the whole subtree would have to know what
|
|
27
|
-
* the platforms below it consider a package; returning one level means it never has to. npm's
|
|
28
|
-
* `workspaces` globs are already one level by construction (`deep: 0`).
|
|
29
|
-
*
|
|
30
|
-
* Still directories rather than `Package` objects, for the reason it always was: discovery runs
|
|
31
|
-
* before any package exists, so a provider returning packages would make discovery the owner of
|
|
32
|
-
* identity too. A path is also unique by construction, where a name is only unique if the
|
|
33
|
-
* ecosystem says so.
|
|
34
|
-
*/
|
|
35
|
-
type Provider = (dir: string) => string[] | undefined;
|
|
36
|
-
/**
|
|
37
|
-
* One directory in the walk's result: which technology claimed it, and what sits below it.
|
|
38
|
-
*
|
|
39
|
-
* A plain tree rather than `Package`s, keeping the line `Provider` draws: `Repository.create`
|
|
40
|
-
* turns this into packages, so identity stays with the manifest provider and discovery stays
|
|
41
|
-
* with this one.
|
|
42
|
-
*/
|
|
43
|
-
interface Node {
|
|
44
|
-
/** Absolute path to the directory. */
|
|
45
|
-
dirname: string;
|
|
46
|
-
/** The technology that claimed it - `basePlatform` when none did, so a reader needs no guard. */
|
|
47
|
-
platform: Platform;
|
|
48
|
-
/** The nodes for the package directories directly below it, in the order the platform gave
|
|
49
|
-
* them. Empty for a leaf. */
|
|
50
|
-
children: Node[];
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* What a directory's `.rmanrc "platform"` resolves to, when it declares one - `undefined` when
|
|
54
|
-
* it says nothing, so the walk falls back to the guess.
|
|
55
|
-
*
|
|
56
|
-
* **A callback rather than config knowledge in here**, which keeps this namespace answering one
|
|
57
|
-
* question. Reading a directory's cascaded config, deciding that a declared name has to be
|
|
58
|
-
* loaded, and refusing one that cannot be, are all the repository's business; where the packages
|
|
59
|
-
* are is this one's. `Repository.create` supplies it - and it is also the seam a spec uses to
|
|
60
|
-
* drive the declaration path without writing a config file.
|
|
61
|
-
*/
|
|
62
|
-
type DeclaredPlatform = (dir: string) => Promise<Platform | undefined>;
|
|
63
|
-
/**
|
|
64
|
-
* **The walk**: descend from `rootDir`, asking each directory's own technology where its children
|
|
65
|
-
* are, and repeating for each answer.
|
|
66
|
-
*
|
|
67
|
-
* One step, applied recursively:
|
|
68
|
-
*
|
|
69
|
-
* 1. take the directory's **declared** platform if it has one, and otherwise the first registered
|
|
70
|
-
* platform whose manifest provider recognizes it (`app.platformFor`, `basePlatform` if none);
|
|
71
|
-
* 2. ask **that** platform's `getWorkspace` for the directories below it holding packages;
|
|
72
|
-
* 3. do the same for each of them.
|
|
73
|
-
*
|
|
74
|
-
* **A declaration wins, and is then held to it.** A platform named for a directory it does not
|
|
75
|
-
* recognize is a statement that is simply untrue, and the failure it would otherwise become is
|
|
76
|
-
* invisible: the manifest reads as nothing, so the package is named after its directory at
|
|
77
|
-
* `0.0.0` and the repository looks like it works. The error names the directory, the platform and
|
|
78
|
-
* the file that platform looked for.
|
|
79
|
-
*
|
|
80
|
-
* The root node always exists - a repository is a package whatever its technology - so this never
|
|
81
|
-
* returns `undefined`. A repository nobody recognizes is a root with no children, which is the
|
|
82
|
-
* single-package answer arrived at rather than guessed.
|
|
83
|
-
*
|
|
84
|
-
* **A directory is visited once.** A provider may legitimately name a directory another one
|
|
85
|
-
* already claimed (two globs overlapping, a symlinked package), and a provider naming an ancestor
|
|
86
|
-
* would otherwise recurse forever. First visit wins, so a package sits where it was first found.
|
|
87
|
-
*
|
|
88
|
-
* `deep` bounds the descent for the same reason `findRoot` bounds its climb: a provider computing
|
|
89
|
-
* paths rather than reading them can produce a chain that never ends, and a guessed depth is
|
|
90
|
-
* better than a hang with nothing printed.
|
|
91
|
-
*/
|
|
92
|
-
function walk(app: RmanApplication, rootDir: string, options?: {
|
|
93
|
-
deep?: number;
|
|
94
|
-
declared?: DeclaredPlatform;
|
|
95
|
-
}): Promise<Node>;
|
|
96
|
-
/** Every node below `node`, depth-first, excluding `node` itself - the flat list `Repository`
|
|
97
|
-
* reports as its packages, since the root is not one of its own members. */
|
|
98
|
-
function flatten(node: Node): Node[];
|
|
99
|
-
/**
|
|
100
|
-
* Where the repository starts, decided **without knowing anything about any ecosystem** - it has
|
|
101
|
-
* to be, because the plugins that do know are named in the config file this walk is looking for.
|
|
102
|
-
*
|
|
103
|
-
* Walking up from `from`, stopping after a directory holding `.git`, the root is:
|
|
104
|
-
*
|
|
105
|
-
* 1. the **outermost** directory in that chain holding an `.rmanrc*` - outermost, because a
|
|
106
|
-
* *package* may have its own `.rmanrc` (that is a supported thing), and from inside such a
|
|
107
|
-
* package the nearest one is the package's, not the repository's;
|
|
108
|
-
* 2. otherwise the `.git` directory itself, the ordinary meaning of "repository root";
|
|
109
|
-
* 3. otherwise `from`, which is all that is left to go on.
|
|
110
|
-
*
|
|
111
|
-
* **What "outermost" costs**, since the two cases genuinely conflict and only one can win: a
|
|
112
|
-
* self-contained project nested inside a larger git repository *and sharing its `.git`* resolves
|
|
113
|
-
* to the outer root, not to itself (measured). That is the same repository by any definition git
|
|
114
|
-
* recognizes, so it is the defensible answer - and a nested project with a `.git` of its own is
|
|
115
|
-
* found correctly, because the walk stops there before the outer `.rmanrc` is ever seen (also
|
|
116
|
-
* measured). A per-package `.rmanrc` is the common case and it is the one served.
|
|
117
|
-
*/
|
|
118
|
-
function findRoot(from: string, deep?: number): string;
|
|
119
|
-
}
|
package/core/workspace.js
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
/**
|
|
4
|
-
* How a repository is laid out, and who decides.
|
|
5
|
-
*
|
|
6
|
-
* A namespace for the same reason `Manifest` is one: it is what a plugin can *augment*
|
|
7
|
-
* (`declare module 'rman' { namespace Workspace { ... } }`), so whatever this seam grows later
|
|
8
|
-
* arrives as a member here rather than as another top-level export.
|
|
9
|
-
*/
|
|
10
|
-
export var Workspace;
|
|
11
|
-
(function (Workspace) {
|
|
12
|
-
/**
|
|
13
|
-
* **The walk**: descend from `rootDir`, asking each directory's own technology where its children
|
|
14
|
-
* are, and repeating for each answer.
|
|
15
|
-
*
|
|
16
|
-
* One step, applied recursively:
|
|
17
|
-
*
|
|
18
|
-
* 1. take the directory's **declared** platform if it has one, and otherwise the first registered
|
|
19
|
-
* platform whose manifest provider recognizes it (`app.platformFor`, `basePlatform` if none);
|
|
20
|
-
* 2. ask **that** platform's `getWorkspace` for the directories below it holding packages;
|
|
21
|
-
* 3. do the same for each of them.
|
|
22
|
-
*
|
|
23
|
-
* **A declaration wins, and is then held to it.** A platform named for a directory it does not
|
|
24
|
-
* recognize is a statement that is simply untrue, and the failure it would otherwise become is
|
|
25
|
-
* invisible: the manifest reads as nothing, so the package is named after its directory at
|
|
26
|
-
* `0.0.0` and the repository looks like it works. The error names the directory, the platform and
|
|
27
|
-
* the file that platform looked for.
|
|
28
|
-
*
|
|
29
|
-
* The root node always exists - a repository is a package whatever its technology - so this never
|
|
30
|
-
* returns `undefined`. A repository nobody recognizes is a root with no children, which is the
|
|
31
|
-
* single-package answer arrived at rather than guessed.
|
|
32
|
-
*
|
|
33
|
-
* **A directory is visited once.** A provider may legitimately name a directory another one
|
|
34
|
-
* already claimed (two globs overlapping, a symlinked package), and a provider naming an ancestor
|
|
35
|
-
* would otherwise recurse forever. First visit wins, so a package sits where it was first found.
|
|
36
|
-
*
|
|
37
|
-
* `deep` bounds the descent for the same reason `findRoot` bounds its climb: a provider computing
|
|
38
|
-
* paths rather than reading them can produce a chain that never ends, and a guessed depth is
|
|
39
|
-
* better than a hang with nothing printed.
|
|
40
|
-
*/
|
|
41
|
-
async function walk(app, rootDir, options) {
|
|
42
|
-
const visited = new Set();
|
|
43
|
-
const descend = async (dir, remaining) => {
|
|
44
|
-
const resolved = path.resolve(dir);
|
|
45
|
-
visited.add(resolved);
|
|
46
|
-
const declared = await options?.declared?.(resolved);
|
|
47
|
-
if (declared && !declared.manifestProvider.read(resolved)) {
|
|
48
|
-
throw new Error(`"${resolved}" declares \`platform: '${declared.name}'\`, and that platform does not ` +
|
|
49
|
-
`recognize it - it looks for "${declared.manifestProvider.fileName}". Either the ` +
|
|
50
|
-
`directory is not a ${declared.name} package, or the declaration belongs one level down.`);
|
|
51
|
-
}
|
|
52
|
-
const platform = declared ?? app.platformFor(resolved);
|
|
53
|
-
const node = { dirname: resolved, platform, children: [] };
|
|
54
|
-
if (remaining <= 0)
|
|
55
|
-
return node;
|
|
56
|
-
/**
|
|
57
|
-
* **Its own platform is asked, and nobody else.** A platform that did not claim the directory
|
|
58
|
-
* has no standing to say what is under it - that was the old first-wins rule, one level up.
|
|
59
|
-
* `basePlatform` has no `getWorkspace`, so a directory no technology claimed has no children,
|
|
60
|
-
* which is the documented behaviour of a repository naming no plugin.
|
|
61
|
-
*/
|
|
62
|
-
for (const child of platform.getWorkspace?.(resolved) ?? []) {
|
|
63
|
-
const childDir = path.resolve(child);
|
|
64
|
-
if (visited.has(childDir))
|
|
65
|
-
continue;
|
|
66
|
-
node.children.push(await descend(childDir, remaining - 1));
|
|
67
|
-
}
|
|
68
|
-
return node;
|
|
69
|
-
};
|
|
70
|
-
return descend(rootDir, options?.deep ?? 10);
|
|
71
|
-
}
|
|
72
|
-
Workspace.walk = walk;
|
|
73
|
-
/** Every node below `node`, depth-first, excluding `node` itself - the flat list `Repository`
|
|
74
|
-
* reports as its packages, since the root is not one of its own members. */
|
|
75
|
-
function flatten(node) {
|
|
76
|
-
return node.children.flatMap(child => [child, ...flatten(child)]);
|
|
77
|
-
}
|
|
78
|
-
Workspace.flatten = flatten;
|
|
79
|
-
/**
|
|
80
|
-
* Where the repository starts, decided **without knowing anything about any ecosystem** - it has
|
|
81
|
-
* to be, because the plugins that do know are named in the config file this walk is looking for.
|
|
82
|
-
*
|
|
83
|
-
* Walking up from `from`, stopping after a directory holding `.git`, the root is:
|
|
84
|
-
*
|
|
85
|
-
* 1. the **outermost** directory in that chain holding an `.rmanrc*` - outermost, because a
|
|
86
|
-
* *package* may have its own `.rmanrc` (that is a supported thing), and from inside such a
|
|
87
|
-
* package the nearest one is the package's, not the repository's;
|
|
88
|
-
* 2. otherwise the `.git` directory itself, the ordinary meaning of "repository root";
|
|
89
|
-
* 3. otherwise `from`, which is all that is left to go on.
|
|
90
|
-
*
|
|
91
|
-
* **What "outermost" costs**, since the two cases genuinely conflict and only one can win: a
|
|
92
|
-
* self-contained project nested inside a larger git repository *and sharing its `.git`* resolves
|
|
93
|
-
* to the outer root, not to itself (measured). That is the same repository by any definition git
|
|
94
|
-
* recognizes, so it is the defensible answer - and a nested project with a `.git` of its own is
|
|
95
|
-
* found correctly, because the walk stops there before the outer `.rmanrc` is ever seen (also
|
|
96
|
-
* measured). A per-package `.rmanrc` is the common case and it is the one served.
|
|
97
|
-
*/
|
|
98
|
-
function findRoot(from, deep = 10) {
|
|
99
|
-
const chain = [];
|
|
100
|
-
let dir = path.resolve(from);
|
|
101
|
-
let remaining = deep;
|
|
102
|
-
while (remaining-- >= 0 && fs.existsSync(dir)) {
|
|
103
|
-
chain.push(dir);
|
|
104
|
-
if (fs.existsSync(path.join(dir, '.git')))
|
|
105
|
-
break;
|
|
106
|
-
const parent = path.resolve(dir, '..');
|
|
107
|
-
if (parent === dir)
|
|
108
|
-
break;
|
|
109
|
-
dir = parent;
|
|
110
|
-
}
|
|
111
|
-
const withConfig = chain.filter(hasRmanConfig);
|
|
112
|
-
if (withConfig.length)
|
|
113
|
-
return withConfig[withConfig.length - 1];
|
|
114
|
-
const gitRoot = chain.find(d => fs.existsSync(path.join(d, '.git')));
|
|
115
|
-
return gitRoot ?? path.resolve(from);
|
|
116
|
-
}
|
|
117
|
-
Workspace.findRoot = findRoot;
|
|
118
|
-
/** Every file form a `.rmanrc` comes in - `package.json#rman` is deliberately *not* one of them
|
|
119
|
-
* here: it would make the root question npm-shaped again. */
|
|
120
|
-
const CONFIG_FILES = ['.rmanrc', '.rmanrc.yml', '.rmanrc.cjs', '.rmanrc.mjs', '.rmanrc.js'];
|
|
121
|
-
function hasRmanConfig(dir) {
|
|
122
|
-
return CONFIG_FILES.some(name => fs.existsSync(path.join(dir, name)));
|
|
123
|
-
}
|
|
124
|
-
})(Workspace || (Workspace = {}));
|
package/plugins/builtins.d.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import type { Platform } from '../core/plugin.js';
|
|
2
|
-
import type { RmanConfig } from '../interfaces/rman-config.interface.js';
|
|
3
|
-
/**
|
|
4
|
-
* **The plugins rman ships in the box, by the name a config calls them.**
|
|
5
|
-
*
|
|
6
|
-
* `plugins: ['node']` is the whole of it - no new key, because there is no new concept. A
|
|
7
|
-
* repository was always able to say which technologies it holds; this is that same statement with
|
|
8
|
-
* a name instead of an instance, which is the form a YAML config and a zero-config repository both
|
|
9
|
-
* need.
|
|
10
|
-
*
|
|
11
|
-
* **Bundled is not the same as always on, and keeping those apart is the point.** Nothing an entry
|
|
12
|
-
* contributes exists until a repository names it or detection finds it, so the core still assumes
|
|
13
|
-
* no ecosystem and `rman clean` is still `Unknown argument` in a repository that is not a Node one.
|
|
14
|
-
* What changed is only where the code is shipped from - one install instead of two, which is what
|
|
15
|
-
* `extends: 'rman-node'` was costing every Node repository for a benefit that belonged to polyglot
|
|
16
|
-
* ones.
|
|
17
|
-
*
|
|
18
|
-
* The key is `Plugin.name`, so what a config writes is what `${{ pkg.provider }}` reads back.
|
|
19
|
-
*
|
|
20
|
-
* **A published package is still not one of these.** `plugins: ['rman-node']` names a package, whose
|
|
21
|
-
* config reaches a repository through `extends`; it is refused, saying so. The two are different
|
|
22
|
-
* statements and a built-in name is neither of them - it is the plugin itself, called by name.
|
|
23
|
-
*/
|
|
24
|
-
export declare const BUILTIN_PLUGINS: Record<string, Builtin>;
|
|
25
|
-
/**
|
|
26
|
-
* One built-in, in the two halves that must not be the same call.
|
|
27
|
-
*
|
|
28
|
-
* **`plugin` answers questions; `contribute` changes the run.** Detection asks a platform whether a
|
|
29
|
-
* directory is its own, which has to be possible without registering anything - and registering is
|
|
30
|
-
* what `contribute` does: it hands over commands, publish targets and (for `node`) an augmentation
|
|
31
|
-
* that rewrites the core's `SystemInfo` in place. One call for both would have "is this a Node
|
|
32
|
-
* repository?" print npm's tooling in a Cargo one, which is exactly the line between *bundled* and
|
|
33
|
-
* *on*.
|
|
34
|
-
*/
|
|
35
|
-
export interface Builtin {
|
|
36
|
-
/** The platform itself, for asking - constructed, registered nowhere, with no side effect. */
|
|
37
|
-
platform: () => Platform;
|
|
38
|
-
/** Everything this built-in adds to a repository that asked for it. */
|
|
39
|
-
contribute: () => RmanConfig;
|
|
40
|
-
}
|
|
41
|
-
/** Whether `name` is one rman ships - the check `plugins` makes before treating a string as a glob. */
|
|
42
|
-
export declare function isBuiltinPlugin(name: string): boolean;
|
|
43
|
-
/** The built-in names, for an error message that has to list what a repository could have meant. */
|
|
44
|
-
export declare function builtinPluginNames(): string[];
|
package/plugins/builtins.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { nodeBuiltin, nodePlatform } from './node/index.js';
|
|
2
|
-
/**
|
|
3
|
-
* **The plugins rman ships in the box, by the name a config calls them.**
|
|
4
|
-
*
|
|
5
|
-
* `plugins: ['node']` is the whole of it - no new key, because there is no new concept. A
|
|
6
|
-
* repository was always able to say which technologies it holds; this is that same statement with
|
|
7
|
-
* a name instead of an instance, which is the form a YAML config and a zero-config repository both
|
|
8
|
-
* need.
|
|
9
|
-
*
|
|
10
|
-
* **Bundled is not the same as always on, and keeping those apart is the point.** Nothing an entry
|
|
11
|
-
* contributes exists until a repository names it or detection finds it, so the core still assumes
|
|
12
|
-
* no ecosystem and `rman clean` is still `Unknown argument` in a repository that is not a Node one.
|
|
13
|
-
* What changed is only where the code is shipped from - one install instead of two, which is what
|
|
14
|
-
* `extends: 'rman-node'` was costing every Node repository for a benefit that belonged to polyglot
|
|
15
|
-
* ones.
|
|
16
|
-
*
|
|
17
|
-
* The key is `Plugin.name`, so what a config writes is what `${{ pkg.provider }}` reads back.
|
|
18
|
-
*
|
|
19
|
-
* **A published package is still not one of these.** `plugins: ['rman-node']` names a package, whose
|
|
20
|
-
* config reaches a repository through `extends`; it is refused, saying so. The two are different
|
|
21
|
-
* statements and a built-in name is neither of them - it is the plugin itself, called by name.
|
|
22
|
-
*/
|
|
23
|
-
export const BUILTIN_PLUGINS = {
|
|
24
|
-
node: { platform: () => nodePlatform, contribute: nodeBuiltin },
|
|
25
|
-
};
|
|
26
|
-
/** Whether `name` is one rman ships - the check `plugins` makes before treating a string as a glob. */
|
|
27
|
-
export function isBuiltinPlugin(name) {
|
|
28
|
-
return Object.hasOwn(BUILTIN_PLUGINS, name);
|
|
29
|
-
}
|
|
30
|
-
/** The built-in names, for an error message that has to list what a repository could have meant. */
|
|
31
|
-
export function builtinPluginNames() {
|
|
32
|
-
return Object.keys(BUILTIN_PLUGINS).sort();
|
|
33
|
-
}
|