rman 1.0.6 → 1.0.8

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 CHANGED
@@ -123,7 +123,8 @@ rman list --scope '@myorg/*' --ignore '*-internal'
123
123
 
124
124
  ### `rman info`
125
125
 
126
- Prints local environment (OS/CPU/memory, Node/npm/Yarn versions, git) and repository information.
126
+ Prints local environment (OS/CPU/memory, Node + whichever package manager `.rmanrc
127
+ "packageManager"` configures, git) and repository information.
127
128
 
128
129
  ```bash
129
130
  rman info
@@ -29,6 +29,10 @@ export function initCli(repository, program) {
29
29
  describe: 'Generate for the whole repository even when the current directory is inside a single ' +
30
30
  'package (which otherwise scopes it to just that package). No effect elsewhere.',
31
31
  type: 'boolean',
32
+ })
33
+ .option('include-skipped', {
34
+ describe: 'Also generate for a package with .rmanrc "publish.skip" - excluded by default',
35
+ type: 'boolean',
32
36
  }),
33
37
  handler: async (args) => {
34
38
  const from = args.from;
@@ -44,6 +48,7 @@ export function initCli(repository, program) {
44
48
  from,
45
49
  filePath: args.filePath,
46
50
  root: args.root,
51
+ includeSkipped: args.includeSkipped,
47
52
  };
48
53
  const entries = args.write
49
54
  ? await ChangelogService.generateToFile(repository, options)
@@ -1,5 +1,6 @@
1
1
  import colors from 'ansi-colors';
2
2
  import semver from 'semver';
3
+ import { CiService } from '../services/ci.service.js';
3
4
  import { SystemInfo } from '../services/system-info.js';
4
5
  function printSystemInfo(systemInfo) {
5
6
  const maxName = Object.keys(systemInfo).reduce((l, p) => Object.keys(systemInfo[p]).reduce((i, x) => Math.max(i, x.length), l), 0);
@@ -48,7 +49,7 @@ export function initCli(repository, program) {
48
49
  type: 'boolean',
49
50
  }),
50
51
  handler: async (args) => {
51
- const systemInfo = await SystemInfo.getSystemInfo();
52
+ const systemInfo = await SystemInfo.getSystemInfo(CiService.resolvePackageManager(repository));
52
53
  const repositoryInfo = SystemInfo.getRepositoryInfo(repository);
53
54
  if (args.json) {
54
55
  console.log(JSON.stringify({ ...systemInfo, repository: repositoryInfo }, undefined, 2));
package/constants.js CHANGED
@@ -1 +1 @@
1
- export const version = '1.0.6';
1
+ export const version = '1.0.8';
package/core/config.d.ts CHANGED
@@ -63,6 +63,13 @@ export declare namespace RmanConfig {
63
63
  * one that publishes both sets `['npm', 'docker']`. */
64
64
  target?: PublishTarget | PublishTarget[];
65
65
  docker?: DockerPublishOptions;
66
+ /** Excludes this package from `publish` entirely (npm and docker both), regardless of
67
+ * `target`/`"private"` - a single, explicit "never published" statement, e.g. for a package
68
+ * released through some separate, unrelated process. `changelog` also skips it by default
69
+ * (see its own `--include-skipped`) - there's little point changelogging something that's
70
+ * never actually released. Independent of `version`, which never consults this at all - a
71
+ * package can still be meaningfully versioned without ever being published. */
72
+ skip?: boolean;
66
73
  }
67
74
  type PublishTarget = 'npm' | 'docker';
68
75
  /** Required once `"docker"` is one of this package's `publish.target`s - `publish --target
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "rman",
3
3
  "description": "Repository manager",
4
- "version": "1.0.6",
4
+ "version": "1.0.8",
5
5
  "author": "Panates",
6
6
  "license": "MIT",
7
7
  "dependencies": {
@@ -120,6 +120,11 @@
120
120
  "docker": {
121
121
  "$ref": "#/definitions/dockerPublishConfig",
122
122
  "description": "Required once \"docker\" is one of this package's \"publish.target\"s."
123
+ },
124
+ "skip": {
125
+ "type": "boolean",
126
+ "default": false,
127
+ "description": "Excludes this package from \"publish\" entirely (npm and docker both), regardless of \"target\"/\"private\" - a single, explicit \"never published\" statement. \"changelog\" also skips it by default (see its own --include-skipped). Independent of \"version\", which never consults this."
123
128
  }
124
129
  }
125
130
  },
@@ -28,6 +28,9 @@ export declare namespace ChangelogService {
28
28
  * what's actually published) doesn't get changes silently skipped over - see
29
29
  * `detectChangeHash`'s `catchUpFile`. */
30
30
  filePath?: string;
31
+ /** A package with `.rmanrc "publish.skip"` is excluded by default - little point changelogging
32
+ * something that's never actually released. Set true to generate for it anyway. */
33
+ includeSkipped?: boolean;
31
34
  }
32
35
  /** One package's (root included) generated changelog entry - what `getEntries`/`generate`
33
36
  * return. */
@@ -63,7 +63,7 @@ export var ChangelogService;
63
63
  async function getEntries(repository, options = {}, deps = {}) {
64
64
  const cwdScope = options.root ? undefined : repository.currentPackage;
65
65
  const packages = repository.getPackages().filter(p => p !== repository.rootPackage);
66
- const targets = cwdScope ? [cwdScope] : filterPackages([repository.rootPackage, ...packages], options);
66
+ const targets = (cwdScope ? [cwdScope] : filterPackages([repository.rootPackage, ...packages], options)).filter(pkg => options.includeSkipped || !pkg.config.publish?.skip);
67
67
  const git = new GitHelper({ cwd: repository.dirname });
68
68
  // dropped up front, not just while grouping - a package whose only commits are version bumps
69
69
  // should get no entry at all, rather than a heading with nothing real underneath it.
@@ -22,7 +22,7 @@ export var DockerPublishService;
22
22
  */
23
23
  async function getPlan(repository, options = {}, deps = {}) {
24
24
  const git = new GitHelper({ cwd: repository.dirname });
25
- const packages = filterPackages(repository.getPackages({ toposort: true }), options).filter(targetsDocker);
25
+ const packages = filterPackages(repository.getPackages({ toposort: true }), options).filter(pkg => targetsDocker(pkg) && !pkg.config.publish?.skip);
26
26
  const dirtyFiles = await git.listDirtyFiles({ absolute: true });
27
27
  const isDirty = (pkg) => dirtyFiles.some(f => !path.relative(pkg.dirname, f).startsWith('..'));
28
28
  const imageExists = deps.imageExists ?? defaultImageExists;
@@ -41,7 +41,15 @@ export var PublishService;
41
41
  const entries = new Map();
42
42
  const toCheck = [];
43
43
  for (const pkg of packages) {
44
- if (pkg.isPrivate) {
44
+ if (pkg.config.publish?.skip) {
45
+ entries.set(pkg.name, {
46
+ package: pkg,
47
+ version: pkg.version,
48
+ status: 'skip',
49
+ reason: 'excluded via .rmanrc "publish.skip"',
50
+ });
51
+ }
52
+ else if (pkg.isPrivate) {
45
53
  entries.set(pkg.name, { package: pkg, version: pkg.version, status: 'skip', reason: 'private package' });
46
54
  }
47
55
  else if (isDirty(pkg)) {
@@ -8,9 +8,15 @@ export declare namespace SystemInfo {
8
8
  root: string;
9
9
  packageCount: number;
10
10
  }
11
- /** Whatever `envinfo` reports (OS/CPU/Memory/Shell, Node/Yarn/npm, git, installed
12
- * rman/typescript versions), grouped by category - shape is `envinfo`'s own, not ours. */
11
+ /** Whatever `envinfo` reports (OS/CPU/Memory/Shell, Node + the resolved package manager, git,
12
+ * installed rman/typescript versions), grouped by category - shape is `envinfo`'s own, not ours. */
13
13
  type SystemInfo = Record<string, Record<string, unknown>>;
14
- function getSystemInfo(options?: envinfo.RunConfig): Promise<SystemInfo.SystemInfo>;
14
+ /**
15
+ * `packageManager` (the repository's resolved `.rmanrc "packageManager"`, default `'npm'`)
16
+ * decides which package manager's version actually gets queried/reported - a pnpm-configured
17
+ * repo has no real use for npm's own version, since every package-manager-aware command
18
+ * (`ci`/`publish`) already shells out to pnpm, not npm, for it.
19
+ */
20
+ function getSystemInfo(packageManager?: 'npm' | 'yarn' | 'pnpm' | 'bun', options?: envinfo.RunConfig): Promise<SystemInfo.SystemInfo>;
15
21
  function getRepositoryInfo(repository: Repository): SystemInfo.RepositoryInfo;
16
22
  }
@@ -1,15 +1,34 @@
1
1
  import envinfo from 'envinfo';
2
2
  export var SystemInfo;
3
3
  (function (SystemInfo) {
4
- async function getSystemInfo(options) {
4
+ /** `.rmanrc "packageManager"` value -> the `Binaries` key `envinfo` recognizes for it (`npm`/
5
+ * `pnpm`/`bun` are lowercase, `Yarn` isn't - envinfo's own naming, not ours). */
6
+ const PACKAGE_MANAGER_BINARY = {
7
+ npm: 'npm',
8
+ yarn: 'Yarn',
9
+ pnpm: 'pnpm',
10
+ bun: 'bun',
11
+ };
12
+ /**
13
+ * `packageManager` (the repository's resolved `.rmanrc "packageManager"`, default `'npm'`)
14
+ * decides which package manager's version actually gets queried/reported - a pnpm-configured
15
+ * repo has no real use for npm's own version, since every package-manager-aware command
16
+ * (`ci`/`publish`) already shells out to pnpm, not npm, for it.
17
+ */
18
+ async function getSystemInfo(packageManager, options) {
5
19
  return JSON.parse(await envinfo.run({
6
20
  System: ['OS', 'CPU', 'Memory', 'Shell'],
7
- Binaries: ['Node', 'Yarn', 'npm'],
21
+ Binaries: ['Node', PACKAGE_MANAGER_BINARY[packageManager ?? 'npm']],
8
22
  Utilities: ['Git'],
9
23
  npmPackages: ['rman', 'typescript'],
10
24
  npmGlobalPackages: ['typescript'],
11
25
  ...options,
12
- }, { json: true }));
26
+ },
27
+ // showNotFound: without it, envinfo *omits* a configured-but-uninstalled package manager
28
+ // from Binaries entirely (indistinguishable from never having asked) instead of reporting
29
+ // "Not Found" - worth surfacing, since it means .rmanrc "packageManager" points at
30
+ // something that isn't actually on this machine.
31
+ { json: true, showNotFound: true }));
13
32
  }
14
33
  SystemInfo.getSystemInfo = getSystemInfo;
15
34
  function getRepositoryInfo(repository) {
@@ -172,6 +172,10 @@ export var VersionService;
172
172
  scope: entry.package.name,
173
173
  root: true,
174
174
  from,
175
+ // version doesn't consult "publish.skip" at all (a package can still be meaningfully
176
+ // versioned/changelogged without ever being published) - this entry was already decided
177
+ // to bump, so its folded-in changelog shouldn't then be silently dropped by that flag.
178
+ includeSkipped: true,
175
179
  });
176
180
  for (const ce of changelogEntries) {
177
181
  changelogFileByPackage.set(ce.package.name, path.relative(repository.dirname, path.join(ce.package.dirname, ce.filePath)));
@@ -43,13 +43,17 @@ export interface DetectChangeHashOptions {
43
43
  * Resolves the commit/hash a package's changes should be measured "since" - the boundary
44
44
  * `changelog --from` uses, but reusable anywhere a command wants to answer "what changed for this
45
45
  * package". An explicit `options.from` (anything but `"npm"`) is returned as-is, applying the same
46
- * way to every package. Otherwise, it's auto-detected from the package's currently-published npm
47
- * version: looked up via `npmViewVersion`, then mapped to a git tag using `.rmanrc
48
- * changelog.tagPattern` (so independent and fixed monorepo versioning schemes both work - see
49
- * `tagPattern`) - and, if `catchUpFile` is given and exists, widened to also cover anything that
50
- * file hasn't caught up on yet (see its doc comment). Returns `undefined` when nothing can be
51
- * resolved at all (unpublished, no network, no matching tag, no catch-up file) - callers should
52
- * fall back to their own default in that case (e.g. `GitHelper.listCommits`'s "not yet pushed"
53
- * default when no hash is given).
46
+ * way to every package. Otherwise, it's auto-detected in order: (1) the package's
47
+ * currently-published npm version - looked up via `npmViewVersion`, then mapped to a git tag using
48
+ * `.rmanrc changelog.tagPattern` (so independent and fixed monorepo versioning schemes both work -
49
+ * see `tagPattern`); (2) failing that (never published, private, no network, ...), this package's
50
+ * own most recent release tag directly - the same `findLatestTag` lookup `version` itself uses, so
51
+ * a package that's never been on npm (e.g. Docker-only) but has real tags from a previous `version`
52
+ * run still gets a correct boundary, not just "everything ever". Either way, if `catchUpFile` is
53
+ * given and exists, the result is widened to also cover anything that file hasn't caught up on yet
54
+ * (see its doc comment). Returns `undefined` when nothing can be resolved at all (never published
55
+ * *and* never tagged, no catch-up file - a genuinely first-ever release) - callers should fall back
56
+ * to their own default in that case (e.g. `GitHelper.listCommits`'s "not yet pushed" default when
57
+ * no hash is given).
54
58
  */
55
59
  export declare function detectChangeHash(git: GitHelper, pkg: Package, options?: DetectChangeHashOptions): Promise<string | undefined>;
@@ -47,14 +47,18 @@ export async function defaultNpmViewVersion(name, cwd) {
47
47
  * Resolves the commit/hash a package's changes should be measured "since" - the boundary
48
48
  * `changelog --from` uses, but reusable anywhere a command wants to answer "what changed for this
49
49
  * package". An explicit `options.from` (anything but `"npm"`) is returned as-is, applying the same
50
- * way to every package. Otherwise, it's auto-detected from the package's currently-published npm
51
- * version: looked up via `npmViewVersion`, then mapped to a git tag using `.rmanrc
52
- * changelog.tagPattern` (so independent and fixed monorepo versioning schemes both work - see
53
- * `tagPattern`) - and, if `catchUpFile` is given and exists, widened to also cover anything that
54
- * file hasn't caught up on yet (see its doc comment). Returns `undefined` when nothing can be
55
- * resolved at all (unpublished, no network, no matching tag, no catch-up file) - callers should
56
- * fall back to their own default in that case (e.g. `GitHelper.listCommits`'s "not yet pushed"
57
- * default when no hash is given).
50
+ * way to every package. Otherwise, it's auto-detected in order: (1) the package's
51
+ * currently-published npm version - looked up via `npmViewVersion`, then mapped to a git tag using
52
+ * `.rmanrc changelog.tagPattern` (so independent and fixed monorepo versioning schemes both work -
53
+ * see `tagPattern`); (2) failing that (never published, private, no network, ...), this package's
54
+ * own most recent release tag directly - the same `findLatestTag` lookup `version` itself uses, so
55
+ * a package that's never been on npm (e.g. Docker-only) but has real tags from a previous `version`
56
+ * run still gets a correct boundary, not just "everything ever". Either way, if `catchUpFile` is
57
+ * given and exists, the result is widened to also cover anything that file hasn't caught up on yet
58
+ * (see its doc comment). Returns `undefined` when nothing can be resolved at all (never published
59
+ * *and* never tagged, no catch-up file - a genuinely first-ever release) - callers should fall back
60
+ * to their own default in that case (e.g. `GitHelper.listCommits`'s "not yet pushed" default when
61
+ * no hash is given).
58
62
  */
59
63
  export async function detectChangeHash(git, pkg, options = {}) {
60
64
  if (options.from && options.from !== 'npm')
@@ -69,6 +73,8 @@ export async function detectChangeHash(git, pkg, options = {}) {
69
73
  const tag = starIdx === -1 ? expanded : expanded.slice(0, starIdx) + publishedVersion + expanded.slice(starIdx + 1);
70
74
  npmHash = (await git.tagExists(tag)) ? tag : undefined;
71
75
  }
76
+ if (!npmHash)
77
+ npmHash = await findLatestTag(git, pkg);
72
78
  const fileHash = options.catchUpFile ? await git.lastCommitTouching(options.catchUpFile) : undefined;
73
79
  if (!fileHash)
74
80
  return npmHash;