rman 1.0.12 → 1.2.1

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.
Files changed (102) hide show
  1. package/README.md +90 -70
  2. package/cli.js +226 -14
  3. package/commands/build.command.js +1 -0
  4. package/commands/changed.command.js +2 -2
  5. package/commands/changelog.command.js +13 -15
  6. package/commands/config.command.js +61 -0
  7. package/commands/diff.command.js +9 -4
  8. package/commands/exec.command.js +2 -8
  9. package/commands/github-release.command.js +1 -0
  10. package/commands/info.command.d.ts +9 -0
  11. package/commands/info.command.js +12 -2
  12. package/commands/run.command.js +5 -8
  13. package/commands/test.command.js +1 -0
  14. package/commands/version.command.js +53 -14
  15. package/constants.js +1 -1
  16. package/core/config.d.ts +265 -17
  17. package/core/config.js +651 -76
  18. package/core/custom-command.d.ts +133 -0
  19. package/core/custom-command.js +99 -0
  20. package/core/extends-config.d.ts +27 -0
  21. package/core/extends-config.js +89 -0
  22. package/core/manifest.d.ts +222 -0
  23. package/core/manifest.js +150 -0
  24. package/core/merge-config.d.ts +70 -0
  25. package/core/merge-config.js +193 -0
  26. package/core/package.d.ts +73 -7
  27. package/core/package.js +86 -24
  28. package/core/plugin.d.ts +112 -0
  29. package/core/plugin.js +189 -0
  30. package/core/repository.d.ts +91 -1
  31. package/core/repository.js +277 -132
  32. package/core/resolve-target.d.ts +12 -0
  33. package/core/resolve-target.js +33 -0
  34. package/core/run-step.d.ts +75 -0
  35. package/core/run-step.js +1 -0
  36. package/core/version-scheme.d.ts +134 -0
  37. package/core/version-scheme.js +148 -0
  38. package/core/workspace.d.ts +68 -0
  39. package/core/workspace.js +83 -0
  40. package/index.d.ts +55 -8
  41. package/index.js +42 -7
  42. package/interfaces/rman-config.interface.d.ts +222 -46
  43. package/package.json +16 -7
  44. package/services/change-hash.service.d.ts +88 -0
  45. package/services/change-hash.service.js +112 -0
  46. package/services/changelog.service.d.ts +8 -13
  47. package/services/changelog.service.js +12 -11
  48. package/services/conventional-commits.service.d.ts +73 -0
  49. package/services/conventional-commits.service.js +116 -0
  50. package/services/docker-publish.service.js +1 -1
  51. package/services/exec.service.js +1 -1
  52. package/services/github-release.service.d.ts +2 -2
  53. package/services/github-release.service.js +10 -5
  54. package/services/list.service.js +5 -2
  55. package/services/run.service.d.ts +112 -6
  56. package/services/run.service.js +265 -89
  57. package/services/system-info.d.ts +22 -7
  58. package/services/system-info.js +8 -23
  59. package/services/version-plan.service.d.ts +244 -0
  60. package/services/version-plan.service.js +414 -0
  61. package/services/version.service.d.ts +102 -82
  62. package/services/version.service.js +226 -434
  63. package/services.d.ts +5 -3
  64. package/services.js +5 -3
  65. package/utils/bin-path.d.ts +59 -0
  66. package/utils/bin-path.js +82 -0
  67. package/utils/child-tracker.d.ts +16 -0
  68. package/utils/child-tracker.js +30 -0
  69. package/utils/exec.d.ts +13 -2
  70. package/utils/exec.js +17 -17
  71. package/utils/git.d.ts +9 -3
  72. package/utils/git.js +10 -2
  73. package/utils/package-filter.d.ts +33 -2
  74. package/utils/package-filter.js +47 -7
  75. package/utils/printable-config.d.ts +15 -0
  76. package/utils/printable-config.js +42 -0
  77. package/utils/release-version.js +3 -3
  78. package/utils/run-bin.d.ts +46 -0
  79. package/utils/run-bin.js +63 -0
  80. package/utils/version-stamp.d.ts +14 -6
  81. package/utils/version-stamp.js +25 -13
  82. package/commands/ci.command.js +0 -30
  83. package/commands/clean.command.d.ts +0 -3
  84. package/commands/clean.command.js +0 -36
  85. package/commands/publish.command.d.ts +0 -3
  86. package/commands/publish.command.js +0 -225
  87. package/rmanrc.schema.json +0 -392
  88. package/services/ci.service.d.ts +0 -40
  89. package/services/ci.service.js +0 -204
  90. package/services/clean.service.d.ts +0 -42
  91. package/services/clean.service.js +0 -226
  92. package/services/publish.service.d.ts +0 -79
  93. package/services/publish.service.js +0 -273
  94. package/utils/change-hash.d.ts +0 -68
  95. package/utils/change-hash.js +0 -98
  96. package/utils/conventional-commits.d.ts +0 -52
  97. package/utils/conventional-commits.js +0 -90
  98. package/utils/npm-run-path.d.ts +0 -67
  99. package/utils/npm-run-path.js +0 -63
  100. package/utils/workspace-range.d.ts +0 -17
  101. package/utils/workspace-range.js +0 -28
  102. /package/commands/{ci.command.d.ts → config.command.d.ts} +0 -0
@@ -1,68 +0,0 @@
1
- import type { Package } from '../core/package.js';
2
- import type { GitHelper } from './git.js';
3
- /** `.rmanrc changelog.tagPattern` (cascaded, per-package overridable) - a glob for this package's
4
- * release tags. `{name}` (if present) is replaced with the package's own name, e.g. `{name}@*`
5
- * for independent per-package versioning (`@scope/pkg@1.2.3`, the same scheme lerna/changesets
6
- * use - `@`/`/` are both fine in a git tag name). Without `{name}`, it's a single repo-wide tag
7
- * shared by every package (e.g. the default `v*`). */
8
- export declare function tagPattern(pkg: Package): string;
9
- /** This package's most recent release tag - the `{name}`-bearing pattern looks up that package's
10
- * *own* tags directly (newest by version sort); a repo-wide pattern instead finds the nearest tag
11
- * HEAD actually descends from, since no single package "owns" that tag. `undefined` if never
12
- * tagged at all (a fresh package, or one that's never been released). Shared by `changelog`
13
- * (reading the last-documented version) and `version` (finding the boundary a bump measures
14
- * "since"). */
15
- export declare function findLatestTag(git: GitHelper, pkg: Package): Promise<string | undefined>;
16
- /** The forward direction of `findLatestTag`: expands `pkg`'s (cascaded) `.rmanrc
17
- * changelog.tagPattern` into the concrete tag name `version` belongs under - `{name}` becomes the
18
- * package's own name, `*` becomes `version`. Shared by `version` (creating the tag),
19
- * `github-release` (finding the release that tag belongs to), and `detectChangeHash`'s own npm
20
- * fallback (mapping a published version back onto a tag), so all three name tags identically. */
21
- export declare function expandTag(pkg: Package, version: string): string;
22
- /** The pattern expansion `expandTag` performs, on any pattern - `{name}` becomes `name`, `*` becomes
23
- * `version`. Shared with the repository's own release tag, which uses a different pattern (see
24
- * `releaseTagPattern`) but names tags the same way. */
25
- export declare function applyTagPattern(pattern: string, name: string, version: string): string;
26
- /** Strips the pattern's literal prefix (everything before its first `*`) from `tag` to get just
27
- * the version part - e.g. tag `@sqb/builder@1.2.3` against pattern `@sqb/builder@*` -> `1.2.3`.
28
- * A pattern with no `*` is returned as its own "version" verbatim (an exact tag, nothing to strip). */
29
- export declare function extractVersion(tag: string, expandedPattern: string): string;
30
- /** Looks up `name`'s currently-published version on the npm registry, or `undefined` if it isn't
31
- * published there at all (private, scoped-but-unpublished, no network, ...) - the real npm CLI
32
- * call `detectChangeHash` uses by default; injectable via its `npmViewVersion` option so tests
33
- * aren't making real registry calls. */
34
- export declare function defaultNpmViewVersion(name: string, cwd: string): Promise<string | undefined>;
35
- export interface DetectChangeHashOptions {
36
- /** Use this commit/hash directly instead of auto-detecting - applies the same way to every
37
- * package. `"npm"` (or omitting `from` entirely) triggers auto-detection instead of being
38
- * treated as a literal ref. */
39
- from?: string;
40
- /** Overrides the real npm registry lookup made when auto-detecting - mainly for tests, so they
41
- * don't depend on network access or a real published package. */
42
- npmViewVersion?: (name: string, cwd: string) => Promise<string | undefined>;
43
- /** An existing record of what's already been documented (typically a changelog file) - only
44
- * consulted while auto-detecting (ignored when `from` is an explicit hash). Guards against a
45
- * gap: if this file's own last-modifying commit is *older* than the npm-detected tag - e.g. the
46
- * file was last updated for 1.1.0, but 1.2.0-1.5.0 were released without ever documenting them,
47
- * and npm now reports 1.5.0 - starting from the tag alone would silently skip everything the
48
- * file never recorded. The boundary becomes the merge-base of the two, so the result always
49
- * covers at least as much as the file is missing. Has no effect when the file doesn't exist. */
50
- catchUpFile?: string;
51
- }
52
- /**
53
- * Resolves the commit/hash a package's changes should be measured "since" - the boundary
54
- * `changelog --from` uses, but reusable anywhere a command wants to answer "what changed for this
55
- * package". An explicit `options.from` (anything but `"npm"`) is returned as-is, applying the same
56
- * way to every package. Otherwise, it's auto-detected in order: (1) this package's own most recent
57
- * release tag - the same network-free `findLatestTag` lookup `version`/`changed` themselves use,
58
- * so all three commands agree on "since when" for any repo whose tags are the ones `rman version`
59
- * actually created; (2) failing that (no tag at all yet - e.g. onboarding `rman` onto a repo with
60
- * real npm history but no `rman`-created tags), the package's currently-published npm version -
61
- * looked up via `npmViewVersion`, then mapped to a git tag using `.rmanrc changelog.tagPattern`
62
- * (see `tagPattern`). Either way, if `catchUpFile` is given and exists, the result is widened to
63
- * also cover anything that file hasn't caught up on yet (see its doc comment). Returns `undefined`
64
- * when nothing can be resolved at all (never tagged *and* never published, no catch-up file - a
65
- * genuinely first-ever release) - callers should fall back to their own default in that case (e.g.
66
- * the whole history, since nothing has ever been released).
67
- */
68
- export declare function detectChangeHash(git: GitHelper, pkg: Package, options?: DetectChangeHashOptions): Promise<string | undefined>;
@@ -1,98 +0,0 @@
1
- import { execFile } from 'node:child_process';
2
- import { promisify } from 'node:util';
3
- /** `.rmanrc changelog.tagPattern` (cascaded, per-package overridable) - a glob for this package's
4
- * release tags. `{name}` (if present) is replaced with the package's own name, e.g. `{name}@*`
5
- * for independent per-package versioning (`@scope/pkg@1.2.3`, the same scheme lerna/changesets
6
- * use - `@`/`/` are both fine in a git tag name). Without `{name}`, it's a single repo-wide tag
7
- * shared by every package (e.g. the default `v*`). */
8
- export function tagPattern(pkg) {
9
- const cfg = pkg.config?.changelog;
10
- return typeof cfg?.tagPattern === 'string' && cfg.tagPattern ? cfg.tagPattern : DEFAULT_TAG_PATTERN;
11
- }
12
- /** This package's most recent release tag - the `{name}`-bearing pattern looks up that package's
13
- * *own* tags directly (newest by version sort); a repo-wide pattern instead finds the nearest tag
14
- * HEAD actually descends from, since no single package "owns" that tag. `undefined` if never
15
- * tagged at all (a fresh package, or one that's never been released). Shared by `changelog`
16
- * (reading the last-documented version) and `version` (finding the boundary a bump measures
17
- * "since"). */
18
- export async function findLatestTag(git, pkg) {
19
- const pattern = tagPattern(pkg);
20
- const expanded = pattern.replace('{name}', pkg.name);
21
- return pattern.includes('{name}') ? (await git.listTags(expanded))[0] : await git.describeTag(expanded);
22
- }
23
- /** The forward direction of `findLatestTag`: expands `pkg`'s (cascaded) `.rmanrc
24
- * changelog.tagPattern` into the concrete tag name `version` belongs under - `{name}` becomes the
25
- * package's own name, `*` becomes `version`. Shared by `version` (creating the tag),
26
- * `github-release` (finding the release that tag belongs to), and `detectChangeHash`'s own npm
27
- * fallback (mapping a published version back onto a tag), so all three name tags identically. */
28
- export function expandTag(pkg, version) {
29
- return applyTagPattern(tagPattern(pkg), pkg.name, version);
30
- }
31
- /** The pattern expansion `expandTag` performs, on any pattern - `{name}` becomes `name`, `*` becomes
32
- * `version`. Shared with the repository's own release tag, which uses a different pattern (see
33
- * `releaseTagPattern`) but names tags the same way. */
34
- export function applyTagPattern(pattern, name, version) {
35
- const expanded = pattern.replace('{name}', name);
36
- const starIdx = expanded.indexOf('*');
37
- return starIdx === -1 ? expanded : expanded.slice(0, starIdx) + version + expanded.slice(starIdx + 1);
38
- }
39
- /** Strips the pattern's literal prefix (everything before its first `*`) from `tag` to get just
40
- * the version part - e.g. tag `@sqb/builder@1.2.3` against pattern `@sqb/builder@*` -> `1.2.3`.
41
- * A pattern with no `*` is returned as its own "version" verbatim (an exact tag, nothing to strip). */
42
- export function extractVersion(tag, expandedPattern) {
43
- const starIdx = expandedPattern.indexOf('*');
44
- if (starIdx === -1)
45
- return tag;
46
- const prefix = expandedPattern.slice(0, starIdx);
47
- return tag.startsWith(prefix) ? tag.slice(prefix.length) : tag;
48
- }
49
- /** Looks up `name`'s currently-published version on the npm registry, or `undefined` if it isn't
50
- * published there at all (private, scoped-but-unpublished, no network, ...) - the real npm CLI
51
- * call `detectChangeHash` uses by default; injectable via its `npmViewVersion` option so tests
52
- * aren't making real registry calls. */
53
- export async function defaultNpmViewVersion(name, cwd) {
54
- try {
55
- const { stdout } = await execFileAsync('npm', ['view', name, 'version'], { cwd });
56
- return stdout.trim() || undefined;
57
- }
58
- catch {
59
- return undefined;
60
- }
61
- }
62
- /**
63
- * Resolves the commit/hash a package's changes should be measured "since" - the boundary
64
- * `changelog --from` uses, but reusable anywhere a command wants to answer "what changed for this
65
- * package". An explicit `options.from` (anything but `"npm"`) is returned as-is, applying the same
66
- * way to every package. Otherwise, it's auto-detected in order: (1) this package's own most recent
67
- * release tag - the same network-free `findLatestTag` lookup `version`/`changed` themselves use,
68
- * so all three commands agree on "since when" for any repo whose tags are the ones `rman version`
69
- * actually created; (2) failing that (no tag at all yet - e.g. onboarding `rman` onto a repo with
70
- * real npm history but no `rman`-created tags), the package's currently-published npm version -
71
- * looked up via `npmViewVersion`, then mapped to a git tag using `.rmanrc changelog.tagPattern`
72
- * (see `tagPattern`). Either way, if `catchUpFile` is given and exists, the result is widened to
73
- * also cover anything that file hasn't caught up on yet (see its doc comment). Returns `undefined`
74
- * when nothing can be resolved at all (never tagged *and* never published, no catch-up file - a
75
- * genuinely first-ever release) - callers should fall back to their own default in that case (e.g.
76
- * the whole history, since nothing has ever been released).
77
- */
78
- export async function detectChangeHash(git, pkg, options = {}) {
79
- if (options.from && options.from !== 'npm')
80
- return options.from;
81
- let tagHash = await findLatestTag(git, pkg);
82
- if (!tagHash) {
83
- const npmViewVersion = options.npmViewVersion ?? defaultNpmViewVersion;
84
- const publishedVersion = await npmViewVersion(pkg.name, git.cwd);
85
- if (publishedVersion) {
86
- const tag = expandTag(pkg, publishedVersion);
87
- tagHash = (await git.tagExists(tag)) ? tag : undefined;
88
- }
89
- }
90
- const fileHash = options.catchUpFile ? await git.lastCommitTouching(options.catchUpFile) : undefined;
91
- if (!fileHash)
92
- return tagHash;
93
- if (!tagHash)
94
- return fileHash;
95
- return (await git.mergeBase(tagHash, fileHash)) ?? tagHash;
96
- }
97
- const execFileAsync = promisify(execFile);
98
- const DEFAULT_TAG_PATTERN = 'v*';
@@ -1,52 +0,0 @@
1
- /**
2
- * `type(scope): description`, optionally with a `!` breaking-change marker - Conventional
3
- * Commits' subject-line shape. Anything that doesn't match falls into "Other Changes" as-is (for
4
- * changelog entries) or defaults to a patch-level change (for version bump severity) - see
5
- * `parseConventionalCommit`.
6
- */
7
- export declare const CONVENTIONAL_PATTERN: RegExp;
8
- /** A bare version-bump commit (`"6.0.1"`, `"v2.3.0-beta.1"`, ...) - many release tools commit the
9
- * version bump itself with just the new version number as the message. That's a release marker,
10
- * not a real change worth describing (or worth bumping a version over on its own), so it's
11
- * dropped everywhere a real change is being looked for. */
12
- export declare const VERSION_BUMP_PATTERN: RegExp;
13
- /**
14
- * Whether `subject` is a release marker rather than a real change - dropped everywhere real
15
- * changes are looked for (changelog entries, and what counts as "changed" for a version bump).
16
- *
17
- * Covers the bare-version form other tools use (`VERSION_BUMP_PATTERN`) plus every message shape
18
- * `version` itself writes: its commit message (`commitMessageTemplate`, or the built-in
19
- * `"chore(release): v{version}"` when a repo doesn't override it), the multi-version form that
20
- * template falls back to when one commit spans several versions (`chore(release): a@1.2.0,
21
- * b@1.3.0`), and the monorepo root's own version-sync commit. Without this, rman's own release
22
- * commits show up in the changelogs it generates - visible whenever the boundary reaches back past
23
- * a previous release (see `detectChangeHash`'s `catchUpFile`).
24
- */
25
- export declare function isReleaseCommit(subject: string, commitMessageTemplate?: string): boolean;
26
- export interface ParsedCommitSubject {
27
- type: string;
28
- scope?: string;
29
- /** A `!` right before the `:` (e.g. `feat!:`) - Conventional Commits' inline breaking-change
30
- * marker. Doesn't cover a `BREAKING CHANGE:` footer, since only the subject line is available. */
31
- breaking: boolean;
32
- description: string;
33
- }
34
- /** Parses a commit subject as Conventional Commits, or `undefined` if it doesn't match at all
35
- * (a non-conventional message - still a real change, just with no `type` to key off of). */
36
- export declare function parseConventionalCommit(subject: string): ParsedCommitSubject | undefined;
37
- /** Whether a commit `body` carries a Conventional Commits `BREAKING CHANGE:` (or
38
- * `BREAKING-CHANGE:`) footer - the other, footer-based way to mark a breaking change, alongside
39
- * the inline `!` the subject line alone can carry (see `parseConventionalCommit`, whose own
40
- * `breaking` only ever reflects that marker, never a footer, since it only sees the subject). */
41
- export declare function hasBreakingChangeFooter(body: string): boolean;
42
- /**
43
- * A `Release-As: patch|minor|major` footer in a commit `body` - lets that one commit's own
44
- * contribution to a detected bump severity be overridden by hand, regardless of what its subject
45
- * line (or a `BREAKING CHANGE:` footer) would otherwise imply. The motivating case: a `feat:`
46
- * commit that needs to ship right now as a patch, without waiting for the rest of a minor's worth
47
- * of work to land - `Release-As: patch` on just that commit ships it alone, at patch severity,
48
- * while a later genuine `feat:` (with no override) still correctly triggers a minor of its own.
49
- * Case-insensitive; the last match wins if a body somehow has more than one, matching how multiple
50
- * git trailers of the same key are conventionally read (later overrides earlier).
51
- */
52
- export declare function parseReleaseAs(body: string): 'patch' | 'minor' | 'major' | undefined;
@@ -1,90 +0,0 @@
1
- /**
2
- * `type(scope): description`, optionally with a `!` breaking-change marker - Conventional
3
- * Commits' subject-line shape. Anything that doesn't match falls into "Other Changes" as-is (for
4
- * changelog entries) or defaults to a patch-level change (for version bump severity) - see
5
- * `parseConventionalCommit`.
6
- */
7
- export const CONVENTIONAL_PATTERN = /^(\w+)(\(([^)]+)\))?(!)?:\s*(.+)$/;
8
- /** A bare version-bump commit (`"6.0.1"`, `"v2.3.0-beta.1"`, ...) - many release tools commit the
9
- * version bump itself with just the new version number as the message. That's a release marker,
10
- * not a real change worth describing (or worth bumping a version over on its own), so it's
11
- * dropped everywhere a real change is being looked for. */
12
- export const VERSION_BUMP_PATTERN = /^v?\d+\.\d+\.\d+(?:[-+][\w.]+)?$/;
13
- /**
14
- * Whether `subject` is a release marker rather than a real change - dropped everywhere real
15
- * changes are looked for (changelog entries, and what counts as "changed" for a version bump).
16
- *
17
- * Covers the bare-version form other tools use (`VERSION_BUMP_PATTERN`) plus every message shape
18
- * `version` itself writes: its commit message (`commitMessageTemplate`, or the built-in
19
- * `"chore(release): v{version}"` when a repo doesn't override it), the multi-version form that
20
- * template falls back to when one commit spans several versions (`chore(release): a@1.2.0,
21
- * b@1.3.0`), and the monorepo root's own version-sync commit. Without this, rman's own release
22
- * commits show up in the changelogs it generates - visible whenever the boundary reaches back past
23
- * a previous release (see `detectChangeHash`'s `catchUpFile`).
24
- */
25
- export function isReleaseCommit(subject, commitMessageTemplate) {
26
- if (VERSION_BUMP_PATTERN.test(subject))
27
- return true;
28
- if (ROOT_SYNC_PATTERN.test(subject))
29
- return true;
30
- if (MULTI_VERSION_RELEASE_PATTERN.test(subject))
31
- return true;
32
- // The built-in message is checked even when a repo overrides it: the override only applies to
33
- // commits spanning a single version (see `buildCommitMessage`), and a repo that adopted one later
34
- // still has older releases committed under the default.
35
- if (templatePattern(DEFAULT_COMMIT_MESSAGE).test(subject))
36
- return true;
37
- return !!commitMessageTemplate && templatePattern(commitMessageTemplate).test(subject);
38
- }
39
- /** Parses a commit subject as Conventional Commits, or `undefined` if it doesn't match at all
40
- * (a non-conventional message - still a real change, just with no `type` to key off of). */
41
- export function parseConventionalCommit(subject) {
42
- const m = CONVENTIONAL_PATTERN.exec(subject);
43
- if (!m)
44
- return undefined;
45
- const [, type, , scope, breakingMark, description] = m;
46
- return { type: type.toLowerCase(), scope, breaking: !!breakingMark, description };
47
- }
48
- /** Whether a commit `body` carries a Conventional Commits `BREAKING CHANGE:` (or
49
- * `BREAKING-CHANGE:`) footer - the other, footer-based way to mark a breaking change, alongside
50
- * the inline `!` the subject line alone can carry (see `parseConventionalCommit`, whose own
51
- * `breaking` only ever reflects that marker, never a footer, since it only sees the subject). */
52
- export function hasBreakingChangeFooter(body) {
53
- return /^BREAKING[ -]CHANGE:/im.test(body);
54
- }
55
- /** A semver version, as it appears inside a commit subject - the `\d+\.\d+\.\d+` core of
56
- * `VERSION_BUMP_PATTERN`, reusable inside the larger patterns below. */
57
- const SEMVER_SOURCE = String.raw `\d+\.\d+\.\d+(?:[-+][\w.]+)?`;
58
- /** Mirrors `VersionService`'s own default `version.commitMessage` - kept in sync by
59
- * `version.command.ts`'s documented default, not imported, to keep this module dependency-free. */
60
- const DEFAULT_COMMIT_MESSAGE = 'chore(release): v{version}';
61
- /** `VersionService.applyPlan`'s trailing commit for a monorepo root's informational version. */
62
- const ROOT_SYNC_PATTERN = new RegExp(String.raw `^chore: sync root version to ${SEMVER_SOURCE}$`);
63
- /** What the commit-message template falls back to when one commit covers several versions at once
64
- * (a cross-group ripple) - `{version}` has nothing single to substitute, so each bumped package is
65
- * listed by name instead. */
66
- const MULTI_VERSION_RELEASE_PATTERN = new RegExp(String.raw `^chore\(release\): \S+@${SEMVER_SOURCE}(?:, \S+@${SEMVER_SOURCE})*$`);
67
- function escapeRegExp(value) {
68
- return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
69
- }
70
- /** Turns a `version.commitMessage` template into a matcher for the commits it produces: every
71
- * literal part escaped, each `{version}` placeholder standing in for any semver. */
72
- function templatePattern(template) {
73
- const source = template.split('{version}').map(escapeRegExp).join(SEMVER_SOURCE);
74
- return new RegExp(`^${source}$`);
75
- }
76
- /**
77
- * A `Release-As: patch|minor|major` footer in a commit `body` - lets that one commit's own
78
- * contribution to a detected bump severity be overridden by hand, regardless of what its subject
79
- * line (or a `BREAKING CHANGE:` footer) would otherwise imply. The motivating case: a `feat:`
80
- * commit that needs to ship right now as a patch, without waiting for the rest of a minor's worth
81
- * of work to land - `Release-As: patch` on just that commit ships it alone, at patch severity,
82
- * while a later genuine `feat:` (with no override) still correctly triggers a minor of its own.
83
- * Case-insensitive; the last match wins if a body somehow has more than one, matching how multiple
84
- * git trailers of the same key are conventionally read (later overrides earlier).
85
- */
86
- export function parseReleaseAs(body) {
87
- const matches = [...body.matchAll(/^release-as:\s*(patch|minor|major)\s*$/gim)];
88
- const last = matches.at(-1);
89
- return last ? last[1].toLowerCase() : undefined;
90
- }
@@ -1,67 +0,0 @@
1
- export interface RunPathOptions {
2
- /**
3
- Working directory.
4
- @default process.cwd()
5
- */
6
- readonly cwd?: string;
7
- /**
8
- PATH to be appended. Default: [`PATH`](https://github.com/sindresorhus/path-key).
9
- Set it to an empty string to exclude the default PATH.
10
- */
11
- readonly path?: string;
12
- /**
13
- Path to the Node.js executable to use in child processes if that is different from the current one. Its directory is pushed to the front of PATH.
14
- This can be either an absolute path or a path relative to the `cwd` option.
15
- @default process.execPath
16
- */
17
- readonly execPath?: string;
18
- }
19
- export type ProcessEnv = Record<string, string | undefined>;
20
- export interface EnvOptions {
21
- /**
22
- The working directory.
23
- @default process.cwd()
24
- */
25
- readonly cwd?: string;
26
- /**
27
- Accepts an object of environment variables, like `process.env`,
28
- and modifies the PATH using the correct [PATH key](https://github.com/sindresorhus/path-key).
29
- Use this if you're modifying the PATH for use in the `child_process` options.
30
- */
31
- readonly env?: ProcessEnv;
32
- /**
33
- The path to the current Node.js executable. Its directory is pushed to the front of PATH.
34
- This can be either an absolute path or a path relative to the `cwd` option.
35
- @default process.execPath
36
- */
37
- readonly execPath?: string;
38
- }
39
- /**
40
- Get your [PATH](https://en.wikipedia.org/wiki/PATH_(variable)) prepended with locally installed binaries.
41
- @returns The augmented path string.
42
- @example
43
- ```
44
- import childProcess from 'node:child_process';
45
- import {npmRunPath} from 'npm-run-path';
46
- console.log(process.env.PATH);
47
- //=> '/usr/local/bin'
48
- console.log(npmRunPath());
49
- //=> '/Users/sindresorhus/dev/foo/node_modules/.bin:/Users/sindresorhus/dev/node_modules/.bin:/Users/sindresorhus/node_modules/.bin:/Users/node_modules/.bin:/node_modules/.bin:/usr/local/bin'
50
- ```
51
- */
52
- export declare function npmRunPath(options?: RunPathOptions): string;
53
- /**
54
- @returns The augmented [`process.env`](https://nodejs.org/api/process.html#process_process_env) object.
55
- @example
56
- ```
57
- import childProcess from 'node:child_process';
58
- import {npmRunPathEnv} from 'npm-run-path';
59
- // `foo` is a locally installed binary
60
- childProcess.execFileSync('foo', {
61
- env: npmRunPathEnv()
62
- });
63
- ```
64
- */
65
- export declare function npmRunPathEnv(options?: EnvOptions): {
66
- [key: string]: string | undefined;
67
- };
@@ -1,63 +0,0 @@
1
- /**
2
- * Inspired from [npm-run-path](https://github.com/sindresorhus/npm-run-path)
3
- */
4
- import path from 'path';
5
- import process from 'process';
6
- /**
7
- Get your [PATH](https://en.wikipedia.org/wiki/PATH_(variable)) prepended with locally installed binaries.
8
- @returns The augmented path string.
9
- @example
10
- ```
11
- import childProcess from 'node:child_process';
12
- import {npmRunPath} from 'npm-run-path';
13
- console.log(process.env.PATH);
14
- //=> '/usr/local/bin'
15
- console.log(npmRunPath());
16
- //=> '/Users/sindresorhus/dev/foo/node_modules/.bin:/Users/sindresorhus/dev/node_modules/.bin:/Users/sindresorhus/node_modules/.bin:/Users/node_modules/.bin:/node_modules/.bin:/usr/local/bin'
17
- ```
18
- */
19
- export function npmRunPath(options = {}) {
20
- const cwd = options.cwd || process.cwd();
21
- const path_ = options.path || process.env[pathKey()];
22
- const execPath = options.execPath || process.execPath;
23
- let previous;
24
- let cwdPath = path.resolve(cwd);
25
- const result = [];
26
- while (previous !== cwdPath) {
27
- result.push(path.join(cwdPath, 'node_modules/.bin'));
28
- previous = cwdPath;
29
- cwdPath = path.resolve(cwdPath, '..');
30
- }
31
- // Ensure the running `node` binary is used.
32
- result.push(path.resolve(cwd, execPath, '..'));
33
- return [...result, path_].join(path.delimiter);
34
- }
35
- /**
36
- @returns The augmented [`process.env`](https://nodejs.org/api/process.html#process_process_env) object.
37
- @example
38
- ```
39
- import childProcess from 'node:child_process';
40
- import {npmRunPathEnv} from 'npm-run-path';
41
- // `foo` is a locally installed binary
42
- childProcess.execFileSync('foo', {
43
- env: npmRunPathEnv()
44
- });
45
- ```
46
- */
47
- export function npmRunPathEnv(options = {}) {
48
- const env = { ...(options.env || process.env) };
49
- const path_ = pathKey({ env });
50
- const opts = { ...options, path: env[path_] };
51
- env[path_] = npmRunPath(opts);
52
- return env;
53
- }
54
- function pathKey(options) {
55
- const env = options?.env || process.env;
56
- const platform = options?.platform || process.platform;
57
- if (platform !== 'win32') {
58
- return 'PATH';
59
- }
60
- return (Object.keys(env)
61
- .reverse()
62
- .find(key => key.toUpperCase() === 'PATH') || 'Path');
63
- }
@@ -1,17 +0,0 @@
1
- export interface ParsedWorkspaceRange {
2
- /** `'*'`/`'^'`/`'~'` for the bare selector forms; `'explicit'` when the protocol is followed by
3
- * a concrete semver version/range instead (e.g. `"workspace:^1.0.0"`, `"workspace:1.0.0"`). */
4
- selector: '*' | '^' | '~' | 'explicit';
5
- /** Only set when `selector === 'explicit'` - the literal range following `"workspace:"`. */
6
- range?: string;
7
- }
8
- /** Parses a dependency range value for the pnpm/yarn `"workspace:"` protocol - `undefined` when
9
- * `value` isn't a workspace range at all (a plain semver range, or not a string). */
10
- export declare function parseWorkspaceRange(value: unknown): ParsedWorkspaceRange | undefined;
11
- /**
12
- * Resolves a parsed workspace range against `version` (the dependency's actual current version)
13
- * into the real range a registry consumer would need - the same substitution pnpm/yarn's own
14
- * publish performs: `"*"` pins the exact version (no operator), `"^"`/`"~"` prepend themselves to
15
- * it, and an explicit range is used verbatim (it was already a real range, just workspace-prefixed).
16
- */
17
- export declare function resolveWorkspaceRange(parsed: ParsedWorkspaceRange, version: string): string;
@@ -1,28 +0,0 @@
1
- /** Parses a dependency range value for the pnpm/yarn `"workspace:"` protocol - `undefined` when
2
- * `value` isn't a workspace range at all (a plain semver range, or not a string). */
3
- export function parseWorkspaceRange(value) {
4
- if (typeof value !== 'string' || !value.startsWith('workspace:'))
5
- return undefined;
6
- const rest = value.slice('workspace:'.length);
7
- if (rest === '*' || rest === '^' || rest === '~')
8
- return { selector: rest };
9
- return { selector: 'explicit', range: rest };
10
- }
11
- /**
12
- * Resolves a parsed workspace range against `version` (the dependency's actual current version)
13
- * into the real range a registry consumer would need - the same substitution pnpm/yarn's own
14
- * publish performs: `"*"` pins the exact version (no operator), `"^"`/`"~"` prepend themselves to
15
- * it, and an explicit range is used verbatim (it was already a real range, just workspace-prefixed).
16
- */
17
- export function resolveWorkspaceRange(parsed, version) {
18
- switch (parsed.selector) {
19
- case '*':
20
- return version;
21
- case '^':
22
- return `^${version}`;
23
- case '~':
24
- return `~${version}`;
25
- case 'explicit':
26
- return parsed.range;
27
- }
28
- }