set-script.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. const { resolve } = require('path')
  2. const log = require('npmlog')
  3. const rpj = require('read-package-json-fast')
  4. const PackageJson = require('@npmcli/package-json')
  5. const BaseCommand = require('./base-command.js')
  6. class SetScript extends BaseCommand {
  7. /* istanbul ignore next - see test/lib/load-all-commands.js */
  8. static get description () {
  9. return 'Set tasks in the scripts section of package.json'
  10. }
  11. /* istanbul ignore next - see test/lib/load-all-commands.js */
  12. static get params () {
  13. return ['workspace', 'workspaces', 'include-workspace-root']
  14. }
  15. /* istanbul ignore next - see test/lib/load-all-commands.js */
  16. static get name () {
  17. return 'set-script'
  18. }
  19. /* istanbul ignore next - see test/lib/load-all-commands.js */
  20. static get usage () {
  21. return ['[<script>] [<command>]']
  22. }
  23. async completion (opts) {
  24. const argv = opts.conf.argv.remain
  25. if (argv.length === 2) {
  26. // find the script name
  27. const json = resolve(this.npm.localPrefix, 'package.json')
  28. const { scripts = {} } = await rpj(json).catch(er => ({}))
  29. return Object.keys(scripts)
  30. }
  31. }
  32. validate (args) {
  33. if (process.env.npm_lifecycle_event === 'postinstall')
  34. throw new Error('Scripts can’t set from the postinstall script')
  35. // Parse arguments
  36. if (args.length !== 2)
  37. throw new Error(`Expected 2 arguments: got ${args.length}`)
  38. }
  39. exec (args, cb) {
  40. this.setScript(args).then(() => cb()).catch(cb)
  41. }
  42. async setScript (args) {
  43. this.validate(args)
  44. const warn = await this.doSetScript(this.npm.localPrefix, args[0], args[1])
  45. if (warn)
  46. log.warn('set-script', `Script "${args[0]}" was overwritten`)
  47. }
  48. execWorkspaces (args, filters, cb) {
  49. this.setScriptWorkspaces(args, filters).then(() => cb()).catch(cb)
  50. }
  51. async setScriptWorkspaces (args, filters) {
  52. this.validate(args)
  53. await this.setWorkspaces(filters)
  54. for (const [name, path] of this.workspaces) {
  55. try {
  56. const warn = await this.doSetScript(path, args[0], args[1])
  57. if (warn) {
  58. log.warn('set-script', `Script "${args[0]}" was overwritten`)
  59. log.warn(` in workspace: ${name}`)
  60. log.warn(` at location: ${path}`)
  61. }
  62. } catch (err) {
  63. log.error('set-script', err.message)
  64. log.error(` in workspace: ${name}`)
  65. log.error(` at location: ${path}`)
  66. process.exitCode = 1
  67. }
  68. }
  69. }
  70. // returns a Boolean that will be true if
  71. // the requested script was overwritten
  72. // and false if it was set as a new script
  73. async doSetScript (path, name, value) {
  74. let warn = false
  75. const pkgJson = await PackageJson.load(path)
  76. const { scripts } = pkgJson.content
  77. const overwriting =
  78. scripts
  79. && scripts[name]
  80. && scripts[name] !== value
  81. if (overwriting)
  82. warn = true
  83. pkgJson.update({
  84. scripts: {
  85. ...scripts,
  86. [name]: value,
  87. },
  88. })
  89. await pkgJson.save()
  90. return warn
  91. }
  92. }
  93. module.exports = SetScript