diff options
author | Gar <gar+gh@danger.computer> | 2021-04-08 20:08:23 +0300 |
---|---|---|
committer | Gar <gar+gh@danger.computer> | 2021-04-15 20:30:37 +0300 |
commit | 8c9e24778db867cb3148bc247c7e321639aa9f58 (patch) | |
tree | 70b5db93056e1dc0b0542d88d348c5a8107213fd /lib | |
parent | 3b476a24cf0b2823fdf92505b84bddde4fcc8b14 (diff) |
feat(version): add workspace support
PR-URL: https://github.com/npm/cli/pull/3055
Credit: @wraithgar
Close: #3055
Reviewed-by: @darcyclarke
Diffstat (limited to 'lib')
-rw-r--r-- | lib/base-command.js | 20 | ||||
-rw-r--r-- | lib/utils/config/definitions.js | 1 | ||||
-rw-r--r-- | lib/version.js | 78 | ||||
-rw-r--r-- | lib/workspaces/get-workspaces.js | 3 |
4 files changed, 92 insertions, 10 deletions
diff --git a/lib/base-command.js b/lib/base-command.js index 91c7c5357..322fd8963 100644 --- a/lib/base-command.js +++ b/lib/base-command.js @@ -4,6 +4,7 @@ const ConfigDefinitions = require('./utils/config/definitions.js') class BaseCommand { constructor (npm) { + this.wrapWidth = 80 this.npm = npm } @@ -27,8 +28,7 @@ class BaseCommand { usage = `${usage}${this.constructor.usage.map(u => `npm ${this.constructor.name} ${u}`).join('\n')}` if (this.constructor.params) - // TODO word wrap this along params boundaries - usage = `${usage}\n\nOptions:\n[${this.constructor.params.map(p => ConfigDefinitions[p].usage).join('] [')}]` + usage = `${usage}\n\nOptions:\n${this.wrappedParams}` // Mostly this just appends aliases, this could be more clear usage = usageUtil(this.constructor.name, usage) @@ -36,6 +36,22 @@ class BaseCommand { return usage } + get wrappedParams () { + let results = '' + let line = '' + + for (const param of this.constructor.params) { + const usage = `[${ConfigDefinitions[param].usage}]` + if (line.length && (line.length + usage.length) > this.wrapWidth) { + results = [results, line].filter(Boolean).join('\n') + line = '' + } + line = [line, usage].filter(Boolean).join(' ') + } + results = [results, line].filter(Boolean).join('\n') + return results + } + usageError (msg) { if (!msg) { return Object.assign(new Error(`\nUsage: ${this.usage}`), { diff --git a/lib/utils/config/definitions.js b/lib/utils/config/definitions.js index d87c43dda..db1f25e95 100644 --- a/lib/utils/config/definitions.js +++ b/lib/utils/config/definitions.js @@ -1389,6 +1389,7 @@ define('prefix', { define('preid', { default: '', + hint: 'prerelease-id', type: String, description: ` The "prerelease identifier" to use as a prefix for the "prerelease" part diff --git a/lib/version.js b/lib/version.js index 18b7d7d6c..3ef3801e7 100644 --- a/lib/version.js +++ b/lib/version.js @@ -1,6 +1,11 @@ -const libversion = require('libnpmversion') +const libnpmversion = require('libnpmversion') +const { resolve } = require('path') +const { promisify } = require('util') +const readFile = promisify(require('fs').readFile) +const getWorkspaces = require('./workspaces/get-workspaces.js') const BaseCommand = require('./base-command.js') + class Version extends BaseCommand { static get description () { return 'Bump a package version' @@ -12,8 +17,22 @@ class Version extends BaseCommand { } /* istanbul ignore next - see test/lib/load-all-commands.js */ + static get params () { + return [ + 'allow-same-version', + 'commit-hooks', + 'git-tag-version', + 'json', + 'preid', + 'sign-git-tag', + 'workspace', + 'workspaces', + ] + } + + /* istanbul ignore next - see test/lib/load-all-commands.js */ static get usage () { - return ['[<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease [--preid=<prerelease-id>] | from-git]'] + return ['[<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git]'] } async completion (opts) { @@ -37,6 +56,10 @@ class Version extends BaseCommand { return this.version(args).then(() => cb()).catch(cb) } + execWorkspaces (args, filters, cb) { + this.versionWorkspaces(args, filters).then(() => cb()).catch(cb) + } + async version (args) { switch (args.length) { case 0: @@ -48,20 +71,42 @@ class Version extends BaseCommand { } } + async versionWorkspaces (args, filters) { + switch (args.length) { + case 0: + return this.listWorkspaces(filters) + case 1: + return this.changeWorkspaces(args, filters) + default: + throw this.usage + } + } + async change (args) { const prefix = this.npm.config.get('tag-version-prefix') - const version = await libversion(args[0], { + const version = await libnpmversion(args[0], { ...this.npm.flatOptions, path: this.npm.prefix, }) return this.npm.output(`${prefix}${version}`) } - async list () { - const results = {} - const { promisify } = require('util') - const { resolve } = require('path') - const readFile = promisify(require('fs').readFile) + async changeWorkspaces (args, filters) { + const prefix = this.npm.config.get('tag-version-prefix') + const workspaces = + await getWorkspaces(filters, { path: this.npm.localPrefix }) + for (const [name, path] of workspaces) { + this.npm.output(name) + const version = await libnpmversion(args[0], { + ...this.npm.flatOptions, + 'git-tag-version': false, + path, + }) + this.npm.output(`${prefix}${version}`) + } + } + + async list (results = {}) { const pj = resolve(this.npm.prefix, 'package.json') const pkg = await readFile(pj, 'utf8') @@ -80,5 +125,22 @@ class Version extends BaseCommand { else this.npm.output(results) } + + async listWorkspaces (filters) { + const results = {} + const workspaces = + await getWorkspaces(filters, { path: this.npm.localPrefix }) + for (const [, path] of workspaces) { + const pj = resolve(path, 'package.json') + // getWorkspaces has already parsed this so we know it won't error + const pkg = await readFile(pj, 'utf8') + .then(data => JSON.parse(data)) + + if (pkg.name && pkg.version) + results[pkg.name] = pkg.version + } + return this.list(results) + } } + module.exports = Version diff --git a/lib/workspaces/get-workspaces.js b/lib/workspaces/get-workspaces.js index 64812d540..91b007455 100644 --- a/lib/workspaces/get-workspaces.js +++ b/lib/workspaces/get-workspaces.js @@ -3,7 +3,10 @@ const mapWorkspaces = require('@npmcli/map-workspaces') const minimatch = require('minimatch') const rpj = require('read-package-json-fast') +// Returns an Map of paths to workspaces indexed by workspace name +// { foo => '/path/to/foo' } const getWorkspaces = async (filters, { path }) => { + // TODO we need a better error to be bubbled up here if this rpj call fails const pkg = await rpj(resolve(path, 'package.json')) const workspaces = await mapWorkspaces({ cwd: path, pkg }) const res = filters.length ? new Map() : workspaces |