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
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import fastGlob from 'fast-glob';
|
|
4
|
-
import { Package } from '../core/package.js';
|
|
5
|
-
import { Repository } from '../core/repository.js';
|
|
6
|
-
import { Service } from '../core/service.js';
|
|
4
|
+
import { Package } from '../core/classes/package.js';
|
|
5
|
+
import { Repository } from '../core/classes/repository.js';
|
|
6
|
+
import { Service } from '../core/classes/service.js';
|
|
7
7
|
import { GitHelper } from '../utils/git.js';
|
|
8
8
|
import { expandReleaseTag, isCalendarVersion, releaseTagPattern } from '../utils/release-version.js';
|
|
9
9
|
import { ChangeHashService } from './change-hash.service.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Service } from '../core/service.js';
|
|
1
|
+
import { Service } from '../core/classes/service.js';
|
|
2
2
|
/**
|
|
3
3
|
* A service class - see `ListService` for the shape and `Service` for the three measured
|
|
4
4
|
* consequences a namespace had. `repository` left the signature because the application carries it.
|
|
@@ -34,7 +34,7 @@ export declare namespace ImportService {
|
|
|
34
34
|
commitCount: number;
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
-
declare module '../core/service.js' {
|
|
37
|
+
declare module '../core/classes/service.js' {
|
|
38
38
|
interface ServiceMap {
|
|
39
39
|
import: ImportService;
|
|
40
40
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
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
|
+
import { Service } from '../core/classes/service.js';
|
|
5
5
|
import { GitHelper } from '../utils/git.js';
|
|
6
6
|
/**
|
|
7
7
|
* A service class - see `ListService` for the shape and `Service` for the three measured
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { Repository } from '../core/repository.js';
|
|
3
|
-
import { Service } from '../core/service.js';
|
|
4
|
-
import type
|
|
1
|
+
import type { DockerPublishOptions } from '../builtins/publish-targets/docker/docker.target.js';
|
|
2
|
+
import type { Repository } from '../core/classes/repository.js';
|
|
3
|
+
import { Service } from '../core/classes/service.js';
|
|
4
|
+
import { type PublishTargetName } from '../core/interfaces/publish-target.js';
|
|
5
5
|
import { type PackageFilterOptions } from '../utils/package-filter.js';
|
|
6
6
|
/**
|
|
7
7
|
* **A class, and the shape every service follows now.**
|
|
@@ -39,8 +39,10 @@ export declare namespace ListService {
|
|
|
39
39
|
* what it saw before.
|
|
40
40
|
*/
|
|
41
41
|
includeRoot?: boolean;
|
|
42
|
-
/** Only include packages
|
|
43
|
-
*
|
|
42
|
+
/** Only include packages the developer has touched but not pushed (dirty, or committed and not
|
|
43
|
+
* yet on the upstream branch) - or, with `changedSince`, since that specific commit/hash.
|
|
44
|
+
* **Question C, never a release question**: after a push `git cherry` is empty and everything
|
|
45
|
+
* reads `clean`, which does not mean there is nothing left to release. */
|
|
44
46
|
changed?: boolean;
|
|
45
47
|
changedSince?: string;
|
|
46
48
|
}
|
|
@@ -79,7 +81,7 @@ export declare namespace ListService {
|
|
|
79
81
|
docker?: DockerPublishOptions;
|
|
80
82
|
}
|
|
81
83
|
}
|
|
82
|
-
declare module '../core/service.js' {
|
|
84
|
+
declare module '../core/classes/service.js' {
|
|
83
85
|
interface ServiceMap {
|
|
84
86
|
list: ListService;
|
|
85
87
|
}
|
package/services/list.service.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { Service } from '../core/classes/service.js';
|
|
3
|
+
import { 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.**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { Package } from '../core/package.js';
|
|
2
|
-
import type { Repository } from '../core/repository.js';
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
1
|
+
import type { Package } from '../core/classes/package.js';
|
|
2
|
+
import type { Repository } from '../core/classes/repository.js';
|
|
3
|
+
import { Service } from '../core/classes/service.js';
|
|
4
|
+
import type { RunStepContext, RunStepFn, RunStepValue } from '../core/interfaces/run-step.js';
|
|
5
5
|
import { type LogLevel } from '../utils/logger.js';
|
|
6
6
|
import { type PackageFilterOptions } from '../utils/package-filter.js';
|
|
7
7
|
/**
|
|
@@ -127,11 +127,15 @@ export declare namespace RunService {
|
|
|
127
127
|
* Runs one slot of a lifecycle belonging to some operation other than `run` itself - `version`'s
|
|
128
128
|
* hooks around the version write are the only one so far.
|
|
129
129
|
*
|
|
130
|
-
* **Here rather than in `VersionService`, because the rule it applies is this service's**:
|
|
131
|
-
* package's own declaration for `script`
|
|
132
|
-
*
|
|
133
|
-
* the copies would sit in the file that writes versions
|
|
134
|
-
* all.
|
|
130
|
+
* **Here rather than in `VersionService`, because the rule it applies is this service's**: how a
|
|
131
|
+
* package's own declaration for `script` and the caller's `fallback` combine, slot by slot -
|
|
132
|
+
* `slotValues`, the same function `getScriptSteps` decides it with. Kept in two places that rule
|
|
133
|
+
* would drift, and one of the copies would sit in the file that writes versions, which now runs
|
|
134
|
+
* no command of its own at all.
|
|
135
|
+
*
|
|
136
|
+
* So npm's `preversion` does **not** replace a repository's `.rmanrc version.before` any more;
|
|
137
|
+
* both run, the config's first. Only `version.exec` is a single answer, and there the package's
|
|
138
|
+
* own still wins.
|
|
135
139
|
*
|
|
136
140
|
* `fallback` is the caller's own configured step(s), **already evaluated**: `version`'s three
|
|
137
141
|
* paths are in `DEFERRED_PATHS` precisely because only the caller can bind
|
|
@@ -172,7 +176,7 @@ export declare namespace RunService {
|
|
|
172
176
|
*
|
|
173
177
|
* run:
|
|
174
178
|
* build:
|
|
175
|
-
* if: changed #
|
|
179
|
+
* if: changed # touched but not pushed
|
|
176
180
|
* test:
|
|
177
181
|
* if: changed = a1b2c3d # changed since a specific commit
|
|
178
182
|
* if: changed = {CHANGE_HASH} # {NAME} -> process.env.NAME first
|
|
@@ -212,7 +216,7 @@ export declare function resolveBool(cliValue: boolean | undefined, pkg: Package,
|
|
|
212
216
|
export declare function resolveBail(cliValue: boolean | undefined, pkg: Package, script: string, fallback: boolean): boolean;
|
|
213
217
|
export declare function resolveNumber(cliValue: number | undefined, pkg: Package, script: string, key: string, fallback: number): number;
|
|
214
218
|
export declare function resolveLogLevel(cliValue: LogLevel | undefined, pkg: Package, script: string, fallback: LogLevel): LogLevel;
|
|
215
|
-
declare module '../core/service.js' {
|
|
219
|
+
declare module '../core/classes/service.js' {
|
|
216
220
|
interface ServiceMap {
|
|
217
221
|
run: RunService;
|
|
218
222
|
}
|
package/services/run.service.js
CHANGED
|
@@ -3,7 +3,7 @@ import { inspect } from 'node:util';
|
|
|
3
3
|
import colors from 'ansi-colors';
|
|
4
4
|
import { tokenize } from 'fast-tokenizer';
|
|
5
5
|
import { Task } from 'power-tasks';
|
|
6
|
-
import { Service } from '../core/service.js';
|
|
6
|
+
import { Service } from '../core/classes/service.js';
|
|
7
7
|
import { exec } from '../utils/exec.js';
|
|
8
8
|
import { LOG_LEVELS, Logger, resolveRootLogLevel } from '../utils/logger.js';
|
|
9
9
|
import { filterPackages } from '../utils/package-filter.js';
|
|
@@ -61,6 +61,12 @@ export class RunService extends Service {
|
|
|
61
61
|
for (let i = 0; i < steps.length; i++) {
|
|
62
62
|
const step = steps[i];
|
|
63
63
|
ctx.currentStep = step.name;
|
|
64
|
+
/** The command for a shell step, the function's own name for a JS one - and a bare
|
|
65
|
+
* marker for an anonymous function, which is still worth saying: the slot label alone
|
|
66
|
+
* does not distinguish a JS step from a shell one. `step.label` is not used directly
|
|
67
|
+
* because for a function it already folds the slot in (`before (js)`), which the row
|
|
68
|
+
* prints two characters to its left. */
|
|
69
|
+
ctx.currentCommand = step.command ?? (step.run?.name ? `${step.run.name}()` : '(js function)');
|
|
64
70
|
ctx.stepIndex = i;
|
|
65
71
|
if (panel.enabled) {
|
|
66
72
|
const onLine = (line) => {
|
|
@@ -275,11 +281,15 @@ export class RunService extends Service {
|
|
|
275
281
|
* Runs one slot of a lifecycle belonging to some operation other than `run` itself - `version`'s
|
|
276
282
|
* hooks around the version write are the only one so far.
|
|
277
283
|
*
|
|
278
|
-
* **Here rather than in `VersionService`, because the rule it applies is this service's**:
|
|
279
|
-
* package's own declaration for `script`
|
|
280
|
-
*
|
|
281
|
-
* the copies would sit in the file that writes versions
|
|
282
|
-
* all.
|
|
284
|
+
* **Here rather than in `VersionService`, because the rule it applies is this service's**: how a
|
|
285
|
+
* package's own declaration for `script` and the caller's `fallback` combine, slot by slot -
|
|
286
|
+
* `slotValues`, the same function `getScriptSteps` decides it with. Kept in two places that rule
|
|
287
|
+
* would drift, and one of the copies would sit in the file that writes versions, which now runs
|
|
288
|
+
* no command of its own at all.
|
|
289
|
+
*
|
|
290
|
+
* So npm's `preversion` does **not** replace a repository's `.rmanrc version.before` any more;
|
|
291
|
+
* both run, the config's first. Only `version.exec` is a single answer, and there the package's
|
|
292
|
+
* own still wins.
|
|
283
293
|
*
|
|
284
294
|
* `fallback` is the caller's own configured step(s), **already evaluated**: `version`'s three
|
|
285
295
|
* paths are in `DEFERRED_PATHS` precisely because only the caller can bind
|
|
@@ -291,8 +301,7 @@ export class RunService extends Service {
|
|
|
291
301
|
* semantics of the shell case too, since `cd x && y` in one process is not the same as two.
|
|
292
302
|
*/
|
|
293
303
|
async function runLifecycleSlot(pkg, script, slot, fallback) {
|
|
294
|
-
const
|
|
295
|
-
const values = own.length ? own : (fallback ?? []);
|
|
304
|
+
const values = slotValues(slot, contributedSlots(pkg, script)?.[slot] ?? [], fallback ?? [], false);
|
|
296
305
|
for (const value of values) {
|
|
297
306
|
if (typeof value === 'function') {
|
|
298
307
|
await value(createStepContext(pkg, pkg.dirname));
|
|
@@ -575,12 +584,14 @@ async function passesIf(repository, pkg, raw, cwd, statusCache) {
|
|
|
575
584
|
*
|
|
576
585
|
* 1. `run.<script>.override: true` -> the config, always. The escape hatch for "ignore what the
|
|
577
586
|
* package says it does".
|
|
578
|
-
* 2. a **contributed** source - `package.json#scripts` via `rman-node
|
|
579
|
-
* because
|
|
580
|
-
*
|
|
581
|
-
*
|
|
582
|
-
*
|
|
583
|
-
* 4.
|
|
587
|
+
* 2. for `exec`, a **contributed** source - `package.json#scripts` via `rman-node` - wins over the
|
|
588
|
+
* config, because the two are one answer to one question and the more specific statement wins.
|
|
589
|
+
* 3. for `before`/`after`, the two **compose**: they are hooks at a point rather than answers, so
|
|
590
|
+
* the config's bracket the package's own (`config.before -> prebuild -> build -> postbuild ->
|
|
591
|
+
* config.after`). See `slotValues` for the measurement behind that.
|
|
592
|
+
* 4. the config's own `before`/`exec`/`after` alone, letting a package run a script it never
|
|
593
|
+
* declared.
|
|
594
|
+
* 5. nothing - and an empty result is what tells `runScript` this package defines no such script.
|
|
584
595
|
*/
|
|
585
596
|
function getScriptSteps(pkg, script) {
|
|
586
597
|
const cfg = RunService.getConfig(pkg, script);
|
|
@@ -593,14 +604,47 @@ function getScriptSteps(pkg, script) {
|
|
|
593
604
|
};
|
|
594
605
|
const steps = [];
|
|
595
606
|
for (const slot of SCRIPT_SLOTS) {
|
|
596
|
-
const
|
|
597
|
-
const configured = fromConfig[slot] ?? [];
|
|
598
|
-
const values = override ? (configured.length ? configured : own) : own.length ? own : configured;
|
|
599
|
-
for (const value of values)
|
|
607
|
+
for (const value of slotValues(slot, contributed?.[slot] ?? [], fromConfig[slot] ?? [], override)) {
|
|
600
608
|
steps.push(toStep(slot, value));
|
|
609
|
+
}
|
|
601
610
|
}
|
|
602
611
|
return steps;
|
|
603
612
|
}
|
|
613
|
+
/**
|
|
614
|
+
* The steps for one slot, from the package's own declaration and the config's, in the order they
|
|
615
|
+
* run.
|
|
616
|
+
*
|
|
617
|
+
* **`exec` replaces; `before` and `after` compose.** They are not the same kind of key, and
|
|
618
|
+
* treating them alike is what this function exists to stop:
|
|
619
|
+
*
|
|
620
|
+
* - `exec` is *one answer to one question* - what this script does. A package declaring
|
|
621
|
+
* `"build": "tsc -b"` and a config declaring `exec: 'tsc -b'` are the same build stated twice,
|
|
622
|
+
* so the more specific statement wins and the other is dropped.
|
|
623
|
+
* - `before`/`after` are *hooks at a point*, and two of them at one point both belong. npm's
|
|
624
|
+
* `prebuild` means "immediately before my own build"; `run.build.before` means "before this
|
|
625
|
+
* script, for every package". Neither answers the other.
|
|
626
|
+
*
|
|
627
|
+
* **Measured, on a two-line repository**: a root declaring
|
|
628
|
+
* `"[*]": { run: { build: { before: 'echo CONFIG-BEFORE', after: 'echo CONFIG-AFTER' } } }` and a
|
|
629
|
+
* package declaring `prebuild`/`build`/`postbuild` ran the package's three and **neither of the
|
|
630
|
+
* root's** - while the identical repository with `prebuild` deleted ran both. So adding an
|
|
631
|
+
* unrelated codegen hook to one package silently cancelled a repo-wide `rman clean`, with a stale
|
|
632
|
+
* build directory as the only symptom.
|
|
633
|
+
*
|
|
634
|
+
* **The config brackets the package's own**, which is what the wider statement means and the shape
|
|
635
|
+
* a bookend already has here: `config.before -> prebuild -> build -> postbuild -> config.after`.
|
|
636
|
+
*
|
|
637
|
+
* `override: true` is unchanged - it is the escape hatch for "ignore what the package says it
|
|
638
|
+
* does", so the config replaces rather than composes, per slot, falling back to the package's own
|
|
639
|
+
* where the config says nothing about that slot.
|
|
640
|
+
*/
|
|
641
|
+
function slotValues(slot, own, configured, override) {
|
|
642
|
+
if (override)
|
|
643
|
+
return configured.length ? configured : own;
|
|
644
|
+
if (slot === 'exec')
|
|
645
|
+
return own.length ? own : configured;
|
|
646
|
+
return slot === 'before' ? [...configured, ...own] : [...own, ...configured];
|
|
647
|
+
}
|
|
604
648
|
/**
|
|
605
649
|
* What this package's own technology says it declares for `script`.
|
|
606
650
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RmanApplication } from '../core/application.js';
|
|
2
|
-
import type { Package } from '../core/package.js';
|
|
3
|
-
import type { Repository } from '../core/repository.js';
|
|
4
|
-
import { VersionScheme } from '../core/version-scheme.js';
|
|
2
|
+
import type { Package } from '../core/classes/package.js';
|
|
3
|
+
import type { Repository } from '../core/classes/repository.js';
|
|
4
|
+
import { VersionScheme } from '../core/classes/version-scheme.js';
|
|
5
5
|
import { type CommitInfo, GitHelper } from '../utils/git.js';
|
|
6
6
|
import { type PackageFilterOptions } from '../utils/package-filter.js';
|
|
7
7
|
/**
|
|
@@ -241,7 +241,11 @@ export declare namespace VersionPlanService {
|
|
|
241
241
|
group: string;
|
|
242
242
|
status: 'bump' | 'skip' | 'error' | 'no-change';
|
|
243
243
|
from: string;
|
|
244
|
-
/**
|
|
244
|
+
/** The version this package would receive. Set for `'bump'`, and for an `'error'` entry that
|
|
245
|
+
* earned one - a package with uncommitted changes aborts the run, and `--show` exists to say
|
|
246
|
+
* what it would get. **Never** set for `'skip'`: `--ignore-dirty` proceeds to write, and a
|
|
247
|
+
* version beside an excluded package would name one it is not getting. So `status`, not `to`,
|
|
248
|
+
* is what decides whether something is applied. */
|
|
245
249
|
to?: string;
|
|
246
250
|
/** Human-readable explanation - e.g. why a package was skipped, or why it's being bumped
|
|
247
251
|
* despite having no commits of its own (a dependency of it changed elsewhere). */
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { RmanApplication } from '../core/application.js';
|
|
3
|
-
import { assertOneScheme, semverScheme, VersionScheme } from '../core/version-scheme.js';
|
|
3
|
+
import { assertOneScheme, semverScheme, VersionScheme } from '../core/classes/version-scheme.js';
|
|
4
4
|
import { GitHelper } from '../utils/git.js';
|
|
5
5
|
import { filterPackages } from '../utils/package-filter.js';
|
|
6
6
|
import { findLastReleaseVersion, formatCalendarVersion, usesCalendarVersion } from '../utils/release-version.js';
|
|
7
|
+
import { groupKeyOf } from '../utils/version-group.js';
|
|
7
8
|
import { ConventionalCommitsService } from './conventional-commits.service.js';
|
|
8
9
|
/**
|
|
9
10
|
* Question A, computed and nothing else: **which packages have changed since their last release,
|
|
@@ -96,21 +97,39 @@ export class VersionPlanService {
|
|
|
96
97
|
const packages = filterPackages(repository.getPackages(), options);
|
|
97
98
|
const dirtyFiles = await git.listDirtyFiles({ absolute: true });
|
|
98
99
|
const isDirty = (pkg) => dirtyFiles.some(f => !path.relative(pkg.dirname, f).startsWith('..'));
|
|
100
|
+
const dirty = packages.filter(isDirty);
|
|
99
101
|
const entries = new Map();
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
102
|
+
/**
|
|
103
|
+
* **A dirty package is removed from the plan only when the run is going to proceed without it.**
|
|
104
|
+
* The two answers are not symmetric, and treating them as one is what left the `To` column
|
|
105
|
+
* blank on the command that exists to show it.
|
|
106
|
+
*
|
|
107
|
+
* - `--ignore-dirty` **writes**. The package is deliberately excluded, so it must not reach a
|
|
108
|
+
* group either: a number its clean siblings receive cannot be derived from commits nobody is
|
|
109
|
+
* releasing, and a `to` printed beside `skip` would name a version that package is not
|
|
110
|
+
* getting. Diverted here, before `eligible`.
|
|
111
|
+
* - Aborting writes **nothing** - `getPlan` is pure and the command throws after printing - so
|
|
112
|
+
* there is no number to keep safe, and the one thing the reader wants is what each package
|
|
113
|
+
* would have got once it is committed. The plan is computed in full and the dirty entries are
|
|
114
|
+
* marked at the very end, below.
|
|
115
|
+
*
|
|
116
|
+
* Excluding them from the abort case cost more than the column. `buildRootEntry` reads
|
|
117
|
+
* `e.to ?? e.from`, and its `groupCount` comes from the groups that were actually built - so a
|
|
118
|
+
* dirty tree quietly moved the repository's own release identity: measured on a four-package
|
|
119
|
+
* repo with `group: false`, three dirty packages left one group standing, which is
|
|
120
|
+
* `usesCalendarVersion`'s "one line" case, and the root reported `0.0.5 -> 2.1.6` on the
|
|
121
|
+
* *semver* path instead of the calendar version it takes with four.
|
|
122
|
+
*/
|
|
123
|
+
const eligible = options.ignoreDirty ? packages.filter(pkg => !dirty.includes(pkg)) : packages;
|
|
124
|
+
for (const pkg of options.ignoreDirty ? dirty : []) {
|
|
125
|
+
entries.set(pkg.name, {
|
|
126
|
+
package: pkg,
|
|
127
|
+
groupKey: this.resolveGroupKey(pkg),
|
|
128
|
+
group: this.groupLabel(this.resolveGroupKey(pkg)),
|
|
129
|
+
status: 'skip',
|
|
130
|
+
from: pkg.version,
|
|
131
|
+
reason: 'uncommitted local changes',
|
|
132
|
+
});
|
|
114
133
|
}
|
|
115
134
|
const commitMessage = repository.rootPackage.config?.version?.commitMessage;
|
|
116
135
|
const changeByPackage = new Map();
|
|
@@ -151,6 +170,25 @@ export class VersionPlanService {
|
|
|
151
170
|
now: options.now ?? (() => new Date()),
|
|
152
171
|
}));
|
|
153
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* The abort case, marked **after** the root entry so the whole table reads as one coherent
|
|
175
|
+
* "if this were committed" preview rather than a mixture of two.
|
|
176
|
+
*
|
|
177
|
+
* `to` survives the overwrite; `status` is what every writer filters on (`VersionService`,
|
|
178
|
+
* `changed`), so an `'error'` entry carrying a version cannot be applied by any of them - and
|
|
179
|
+
* `version` throws on the first error before it would reach `applyPlan` anyway. The reason
|
|
180
|
+
* keeps the boundary it was computed from, because the status column already says `error` and
|
|
181
|
+
* a reader losing `changed since <tag>` loses the only thing that explains the number.
|
|
182
|
+
*/
|
|
183
|
+
if (!options.ignoreDirty) {
|
|
184
|
+
for (const pkg of dirty) {
|
|
185
|
+
const entry = entries.get(pkg.name);
|
|
186
|
+
if (!entry)
|
|
187
|
+
continue;
|
|
188
|
+
entry.status = 'error';
|
|
189
|
+
entry.reason = entry.reason ? `uncommitted local changes (${entry.reason})` : 'uncommitted local changes';
|
|
190
|
+
}
|
|
191
|
+
}
|
|
154
192
|
return result;
|
|
155
193
|
}
|
|
156
194
|
/**
|
|
@@ -230,12 +268,7 @@ export class VersionPlanService {
|
|
|
230
268
|
* group; a non-empty string joins exactly the other packages sharing that string, regardless of
|
|
231
269
|
* the repo's own default; `false` makes it a solo group of one. */
|
|
232
270
|
resolveGroupKey(pkg) {
|
|
233
|
-
|
|
234
|
-
if (g === false)
|
|
235
|
-
return `solo:${pkg.name}`;
|
|
236
|
-
if (typeof g === 'string' && g)
|
|
237
|
-
return `named:${g}`;
|
|
238
|
-
return 'default';
|
|
271
|
+
return groupKeyOf(pkg);
|
|
239
272
|
}
|
|
240
273
|
/** The human-readable name behind a `groupKey` - what a plan's `group` column shows. */
|
|
241
274
|
groupLabel(key) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { Package } from '../core/package.js';
|
|
2
|
-
import type { Repository } from '../core/repository.js';
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
1
|
+
import type { Package } from '../core/classes/package.js';
|
|
2
|
+
import type { Repository } from '../core/classes/repository.js';
|
|
3
|
+
import { Service } from '../core/classes/service.js';
|
|
4
|
+
import type { RunStepValue } from '../core/interfaces/run-step.js';
|
|
5
5
|
import { VersionPlanService } from './version-plan.service.js';
|
|
6
6
|
/**
|
|
7
7
|
* Applying a version plan: the writes. Every manifest edit, dependency-range refresh, stamp,
|
|
@@ -139,7 +139,7 @@ export declare namespace VersionService {
|
|
|
139
139
|
*/
|
|
140
140
|
function stampSourceFiles(pkg: Package, version: string): string[];
|
|
141
141
|
}
|
|
142
|
-
declare module '../core/service.js' {
|
|
142
|
+
declare module '../core/classes/service.js' {
|
|
143
143
|
interface ServiceMap {
|
|
144
144
|
version: VersionService;
|
|
145
145
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { Service } from '../core/classes/service.js';
|
|
4
|
+
import { ConfigInterpolator } from '../core/config/config-interpolator.js';
|
|
5
|
+
import { Manifest } from '../core/interfaces/manifest.js';
|
|
6
6
|
import { GitHelper } from '../utils/git.js';
|
|
7
7
|
import { expandReleaseTag, isCalendarVersion } from '../utils/release-version.js';
|
|
8
8
|
import { stampVersionLabel } from '../utils/version-stamp.js';
|
|
@@ -65,6 +65,9 @@ export class VersionService extends Service {
|
|
|
65
65
|
*/
|
|
66
66
|
for (const entry of bumped)
|
|
67
67
|
assertStampable(entry.package, entry.to);
|
|
68
|
+
/** One for the whole run: it carries no per-package state, and `defer(...)`'s bookkeeping is
|
|
69
|
+
* per call. */
|
|
70
|
+
const interpolator = new ConfigInterpolator();
|
|
68
71
|
for (const entry of bumped) {
|
|
69
72
|
const pkg = entry.package;
|
|
70
73
|
/** The scope these hooks are evaluated against - the only place `${{ pkg.targetVersion }}`
|
|
@@ -80,7 +83,7 @@ export class VersionService extends Service {
|
|
|
80
83
|
const hook = (slot) => RunService.runLifecycleSlot(pkg, VERSION_LIFECYCLE, slot, RunService.normalizeScriptValue(
|
|
81
84
|
/** `at`: the path is what tells a step function from a value one, and this is a fragment -
|
|
82
85
|
* without it a function here was called while the hook was being prepared. */
|
|
83
|
-
|
|
86
|
+
interpolator.interpolate({ config: pkg.config?.version?.[slot], scope, at: ['version', slot] }), `version.${slot}`));
|
|
84
87
|
await hook('before');
|
|
85
88
|
/** Through the manifest, not through a `package.json` field: where a version is written is
|
|
86
89
|
* the provider's business (see `Plugin`'s manifest members), and this is the one place rman changes
|
package/services.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
export { DockerPublishService } from './builtins/publish-targets/docker/docker-publish.service.js';
|
|
1
2
|
export { ChangelogService } from './services/changelog.service.js';
|
|
2
|
-
export { DockerPublishService } from './services/docker-publish.service.js';
|
|
3
3
|
export { ExecService } from './services/exec.service.js';
|
|
4
4
|
export { GithubReleaseService } from './services/github-release.service.js';
|
|
5
5
|
export { ImportService } from './services/import.service.js';
|
package/services.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
export { DockerPublishService } from './builtins/publish-targets/docker/docker-publish.service.js';
|
|
1
2
|
export { ChangelogService } from './services/changelog.service.js';
|
|
2
|
-
export { DockerPublishService } from './services/docker-publish.service.js';
|
|
3
3
|
export { ExecService } from './services/exec.service.js';
|
|
4
4
|
export { GithubReleaseService } from './services/github-release.service.js';
|
|
5
5
|
export { ImportService } from './services/import.service.js';
|
package/utils/branch-guard.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Argv } from 'yargs';
|
|
2
|
-
import type { Repository } from '../core/repository.js';
|
|
2
|
+
import type { Repository } from '../core/classes/repository.js';
|
|
3
3
|
/** Same idea as GitHub Actions' own `branches`/`branches-ignore` workflow filters - restricts a
|
|
4
4
|
* command to running only from certain branches (or refuses certain ones), instead of any. */
|
|
5
5
|
export interface BranchGuardOptions {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A YAML document with syntax colour, for the two commands that print one to be **looked at** -
|
|
3
|
+
* `rman config` and `--config`.
|
|
4
|
+
*
|
|
5
|
+
* **Only call this when `process.stdout.isTTY`.** Colouring a document that is being redirected
|
|
6
|
+
* makes it unloadable, which is the whole reason the callers gate on a terminal.
|
|
7
|
+
*/
|
|
8
|
+
export declare function colorYaml(text: string): string;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import colors from 'ansi-colors';
|
|
2
|
+
/**
|
|
3
|
+
* A YAML document with syntax colour, for the two commands that print one to be **looked at** -
|
|
4
|
+
* `rman config` and `--config`.
|
|
5
|
+
*
|
|
6
|
+
* **Only call this when `process.stdout.isTTY`.** Colouring a document that is being redirected
|
|
7
|
+
* makes it unloadable, which is the whole reason the callers gate on a terminal.
|
|
8
|
+
*/
|
|
9
|
+
/* **Line-based and deliberately shallow.** This is a highlighter, not a parser: it colours what a
|
|
10
|
+
* reader's eye uses to navigate - the key, the list marker, a literal - and leaves anything it is
|
|
11
|
+
* not sure about alone. A real parse would have to round-trip js-yaml's own output to gain nothing
|
|
12
|
+
* a reader would notice, and every extra rule is a new way to mangle a value.
|
|
13
|
+
*
|
|
14
|
+
* **What it colours and why that set**:
|
|
15
|
+
*
|
|
16
|
+
* - the **key**, in cyan, because that is what you scan a config for;
|
|
17
|
+
* - **`${{ ... }}`**, in magenta, because rman's configs are full of them and because a `version`
|
|
18
|
+
* hook is printed *raw* (`DEFERRED_PATHS`) - the one place an unresolved expression is correct
|
|
19
|
+
* rather than a bug, and the colour is what stops it reading as a mistake;
|
|
20
|
+
* - **numbers, booleans and `null`**, in yellow, since `skip: false` and `skip: "false"` mean
|
|
21
|
+
* different things and nothing else in the output tells them apart;
|
|
22
|
+
* - **`[Function: name]`**, in grey, because it is this printer's placeholder rather than anything
|
|
23
|
+
* the config says - the one value in the output that is not a value;
|
|
24
|
+
* - the **`-`** of a list item and a `#` comment, in grey, as structure rather than content.
|
|
25
|
+
*
|
|
26
|
+
* A plain string value is left uncoloured on purpose. It is the *content*, usually the longest
|
|
27
|
+
* thing on the line, and colouring it competes with the key for attention - which is the failure
|
|
28
|
+
* mode of a highlighter that paints everything.
|
|
29
|
+
*
|
|
30
|
+
* **The two places a shallow pass has to be careful, and neither is hypothetical:**
|
|
31
|
+
*
|
|
32
|
+
* - **A `:` inside a value.** js-yaml quotes any scalar holding one, so the line is
|
|
33
|
+
* `key: 'a: b'` - and the key pattern stops at the *first* colon, which is the right one. Nothing
|
|
34
|
+
* to do, but it is why the pattern is written `[^:]*` rather than anything greedier.
|
|
35
|
+
* - **A folded block scalar.** `lineWidth: 100` makes js-yaml emit `describe: >-` and continue on
|
|
36
|
+
* deeper-indented lines, and a continuation line is prose: one holding `(default: ...)` would
|
|
37
|
+
* otherwise have half a sentence coloured as a key. So the block's indent is tracked and its
|
|
38
|
+
* content is left alone but for expressions. A `#` there is prose too, not a comment. */
|
|
39
|
+
export function colorYaml(text) {
|
|
40
|
+
/** The indent of the key that opened a block scalar, while one is open. Anything indented past it
|
|
41
|
+
* is that block's content; the first line that is not ends it. */
|
|
42
|
+
let blockIndent;
|
|
43
|
+
return text
|
|
44
|
+
.split('\n')
|
|
45
|
+
.map(line => {
|
|
46
|
+
const indent = line.length - line.trimStart().length;
|
|
47
|
+
if (blockIndent !== undefined) {
|
|
48
|
+
if (line.trim() === '' || indent > blockIndent)
|
|
49
|
+
return colorExpressions(line);
|
|
50
|
+
blockIndent = undefined;
|
|
51
|
+
}
|
|
52
|
+
if (BLOCK_SCALAR.test(line))
|
|
53
|
+
blockIndent = indent;
|
|
54
|
+
return colorLine(line);
|
|
55
|
+
})
|
|
56
|
+
.join('\n');
|
|
57
|
+
}
|
|
58
|
+
/** `key: >-`, `key: |`, `key: >2-`, and the bare `- >-` of a list item. */
|
|
59
|
+
const BLOCK_SCALAR = /:\s*[|>][0-9]*[-+]?\s*$/;
|
|
60
|
+
const EXPRESSION = /\$\{\{[\s\S]*?\}\}/g;
|
|
61
|
+
const LITERAL = /^(true|false|null|~|-?\d+(?:\.\d+)?)$/;
|
|
62
|
+
const FUNCTION = /^"?\[Function(?::[^\]]*)?\]"?$/;
|
|
63
|
+
function colorLine(line) {
|
|
64
|
+
const comment = /^(\s*)#(.*)$/.exec(line);
|
|
65
|
+
if (comment)
|
|
66
|
+
return comment[1] + colors.gray(`#${comment[2]}`);
|
|
67
|
+
/** `indent`, an optional `- ` for a list item, then either `key:` plus a value or a bare item. */
|
|
68
|
+
const parsed = /^(\s*)(- )?(?:([^\s:][^:]*):(\s|$))?([\s\S]*)$/.exec(line);
|
|
69
|
+
if (!parsed)
|
|
70
|
+
return line;
|
|
71
|
+
const [, indent = '', dash, key, gap = '', rest = ''] = parsed;
|
|
72
|
+
return indent + (dash ? colors.gray(dash) : '') + (key ? `${colors.cyan(key)}:${gap}` : '') + colorValue(rest);
|
|
73
|
+
}
|
|
74
|
+
function colorValue(value) {
|
|
75
|
+
const trimmed = value.trim();
|
|
76
|
+
if (!trimmed)
|
|
77
|
+
return value;
|
|
78
|
+
if (LITERAL.test(trimmed))
|
|
79
|
+
return value.replace(trimmed, colors.yellow(trimmed));
|
|
80
|
+
if (FUNCTION.test(trimmed))
|
|
81
|
+
return value.replace(trimmed, colors.gray(trimmed));
|
|
82
|
+
return colorExpressions(value);
|
|
83
|
+
}
|
|
84
|
+
function colorExpressions(value) {
|
|
85
|
+
return value.replace(EXPRESSION, match => colors.magenta(match));
|
|
86
|
+
}
|
package/utils/git.d.ts
CHANGED
|
@@ -46,6 +46,19 @@ export declare class GitHelper {
|
|
|
46
46
|
/** Tag names matching the glob `pattern` (e.g. `"v*"`, `"pkg-a@*"`), newest version first. */
|
|
47
47
|
listTags(pattern: string): Promise<string[]>;
|
|
48
48
|
/** Whether `tag` exists as an exact git tag name (not a glob - a literal ref check). */
|
|
49
|
+
/**
|
|
50
|
+
* Every tag matching `pattern`, paired with the **commit** it points at - newest version first,
|
|
51
|
+
* the same order `listTags` returns.
|
|
52
|
+
*
|
|
53
|
+
* `%(*objectname)` is the dereferenced target and is empty for a lightweight tag, so the commit
|
|
54
|
+
* is that or `%(objectname)`. rman's own tags are lightweight; a repository's existing ones may
|
|
55
|
+
* not be, and an annotated tag's `objectname` is the *tag object*, which matches no commit and
|
|
56
|
+
* would make the tag silently invisible to anything comparing shas.
|
|
57
|
+
*/
|
|
58
|
+
listTagCommits(pattern: string): Promise<{
|
|
59
|
+
tag: string;
|
|
60
|
+
sha: string;
|
|
61
|
+
}[]>;
|
|
49
62
|
tagExists(tag: string): Promise<boolean>;
|
|
50
63
|
/** The most recent commit that changed `file` (tracked history only) - `undefined` if it has
|
|
51
64
|
* never been committed. Answers "since when has this file last been updated", independent of
|
|
@@ -61,6 +74,19 @@ export declare class GitHelper {
|
|
|
61
74
|
/** The repository's very first commit (the oldest root commit, for a history with several) -
|
|
62
75
|
* `undefined` for a repository with no commits at all. The "since the beginning" boundary for
|
|
63
76
|
* a package being released for the first time, with no earlier tag to measure from. */
|
|
77
|
+
/** HEAD's own sha, or `undefined` in a repository with no commits yet (or none at all) - the
|
|
78
|
+
* same "answer nothing rather than throw" shape `rootCommit` and `describeTag` take, because
|
|
79
|
+
* every caller here already has a "nothing to go on" branch. */
|
|
80
|
+
/** The date a ref points at, as `YYYY-MM-DD`. The **committer** date, not the author's: a
|
|
81
|
+
* rebased or cherry-picked release commit was authored earlier than it shipped, and what a
|
|
82
|
+
* changelog heading states is when the release happened. `undefined` for a ref that resolves to
|
|
83
|
+
* nothing. */
|
|
84
|
+
commitDate(ref: string): Promise<string | undefined>;
|
|
85
|
+
/** The commit `ref` names - a sha, a tag, a branch - or `undefined` when git does not recognize
|
|
86
|
+
* it. `^{commit}` so an annotated tag answers with the commit rather than the tag object, and
|
|
87
|
+
* so a tree or blob answers with nothing rather than a sha that matches no commit. */
|
|
88
|
+
resolveCommit(ref: string): Promise<string | undefined>;
|
|
89
|
+
headSha(): Promise<string | undefined>;
|
|
64
90
|
rootCommit(): Promise<string | undefined>;
|
|
65
91
|
/**
|
|
66
92
|
* Stages and commits exactly `files` (relative to `cwd`, or absolute) with `message` - never a
|