diff options
author | nlf <quitlahok@gmail.com> | 2021-03-30 18:05:41 +0300 |
---|---|---|
committer | Gar <gar+gh@danger.computer> | 2021-04-01 00:01:07 +0300 |
commit | ec520ce32d5e834a32ebd58491df4200e01ce690 (patch) | |
tree | 94954aea6f6291354efd5a6a7fddf981365164eb /lib | |
parent | 8bcc5d73f35434e781ff56419dd7f0c380efd072 (diff) |
feat(set-script): implement workspaces
Implements workspaces for set-script, also refactors tests to mock as
little as possible.
PR-URL: https://github.com/npm/cli/pull/2998
Credit: @nlf
Close: #2998
Reviewed-by: @wraithgar
Diffstat (limited to 'lib')
-rw-r--r-- | lib/set-script.js | 81 |
1 files changed, 64 insertions, 17 deletions
diff --git a/lib/set-script.js b/lib/set-script.js index 9d4aadad5..b31e123be 100644 --- a/lib/set-script.js +++ b/lib/set-script.js @@ -3,6 +3,7 @@ const fs = require('fs') const parseJSON = require('json-parse-even-better-errors') const rpj = require('read-package-json-fast') const { resolve } = require('path') +const getWorkspaces = require('./workspaces/get-workspaces.js') const BaseCommand = require('./base-command.js') class SetScript extends BaseCommand { @@ -12,6 +13,11 @@ class SetScript extends BaseCommand { } /* istanbul ignore next - see test/lib/load-all-commands.js */ + static get params () { + return ['workspace', 'workspaces'] + } + + /* istanbul ignore next - see test/lib/load-all-commands.js */ static get name () { return 'set-script' } @@ -31,49 +37,90 @@ class SetScript extends BaseCommand { } } - exec (args, cb) { - this.set(args).then(() => cb()).catch(cb) - } - - async set (args) { + validate (args) { if (process.env.npm_lifecycle_event === 'postinstall') throw new Error('Scripts can’t set from the postinstall script') // Parse arguments if (args.length !== 2) throw new Error(`Expected 2 arguments: got ${args.length}`) + } + exec (args, cb) { + this.set(args).then(() => cb()).catch(cb) + } + + async set (args) { + this.validate(args) + const warn = this.setScript(this.npm.localPrefix, args[0], args[1]) + if (warn) + log.warn('set-script', `Script "${args[0]}" was overwritten`) + } + + execWorkspaces (args, filters, cb) { + this.setWorkspaces(args, filters).then(() => cb()).catch(cb) + } + + async setWorkspaces (args, filters) { + this.validate(args) + const workspaces = + await getWorkspaces(filters, { path: this.npm.localPrefix }) + + for (const [name, path] of workspaces) { + try { + const warn = this.setScript(path, args[0], args[1]) + if (warn) { + log.warn('set-script', `Script "${args[0]}" was overwritten`) + log.warn(` in workspace: ${name}`) + log.warn(` at location: ${path}`) + } + } catch (err) { + log.error('set-script', err.message) + log.error(` in workspace: ${name}`) + log.error(` at location: ${path}`) + process.exitCode = 1 + } + } + } + + // returns a Boolean that will be true if + // the requested script was overwritten + // and false if it was set as a new script + setScript (path, name, value) { // Set the script let manifest let warn = false + try { - manifest = fs.readFileSync(this.npm.localPrefix + '/package.json', 'utf-8') + manifest = fs.readFileSync(resolve(path, 'package.json'), 'utf-8') } catch (error) { throw new Error('package.json not found') } + try { manifest = parseJSON(manifest) } catch (error) { throw new Error(`Invalid package.json: ${error}`) } + if (!manifest.scripts) manifest.scripts = {} - if (manifest.scripts[args[0]] && manifest.scripts[args[0]] !== args[1]) + + if (manifest.scripts[name] && manifest.scripts[name] !== value) warn = true - manifest.scripts[args[0]] = args[1] + manifest.scripts[name] = value + // format content - const packageJsonInfo = await rpj(this.npm.localPrefix + '/package.json') const { [Symbol.for('indent')]: indent, [Symbol.for('newline')]: newline, - } = packageJsonInfo - const format = indent === undefined ? ' ' : indent - const eol = newline === undefined ? '\n' : newline - const content = (JSON.stringify(manifest, null, format) + '\n') - .replace(/\n/g, eol) - fs.writeFileSync(this.npm.localPrefix + '/package.json', content) - if (warn) - log.warn('set-script', `Script "${args[0]}" was overwritten`) + } = manifest + + const content = (JSON.stringify(manifest, null, indent) + '\n') + .replace(/\n/g, newline) + fs.writeFileSync(resolve(path, 'package.json'), content) + + return warn } } module.exports = SetScript |