UNPKG

1.96 kBJavaScriptView Raw
1const sh = require('shelljs');
2const debug = require('debug')('release-it:shell');
3const { format } = require('./util');
4
5sh.config.silent = !debug.enabled;
6
7const noop = Promise.resolve();
8const forcedCmdRe = /^!/;
9
10class Shell {
11 constructor({ global = {}, container }) {
12 this.global = global;
13 this.log = container.log;
14 this.config = container.config;
15 this.Cache = new Set();
16 }
17
18 // TODO: there should be a single `exec` method
19 _exec(command, options = {}) {
20 const normalizedCmd = command.replace(forcedCmdRe, '').trim();
21 const program = normalizedCmd.split(' ')[0];
22 const programArgs = normalizedCmd.split(' ').slice(1);
23 const isWrite = options.write !== false;
24 const cacheable = options.cache === true;
25
26 if (this.global.isDryRun && isWrite) {
27 this.log.exec(normalizedCmd, this.global.isDryRun);
28 return noop;
29 }
30
31 if (cacheable && command in this.Cache) {
32 return this.Cache[command];
33 }
34
35 const awaitExec = new Promise((resolve, reject) => {
36 const cb = (code, stdout, stderr) => {
37 stdout = stdout.toString().trim();
38 this.log.exec(normalizedCmd);
39 this.log.verbose(stdout);
40 debug({ command, options, code, stdout, stderr });
41 if (code === 0) {
42 resolve(stdout);
43 } else {
44 if (stdout && stderr) {
45 this.log.log(`\n${stdout}`);
46 }
47 reject(new Error(stderr || stdout));
48 }
49 };
50
51 if (program in sh && typeof sh[program] === 'function' && forcedCmdRe.test(command)) {
52 cb(0, sh[program](...programArgs));
53 } else {
54 sh.exec(normalizedCmd, { async: true }, cb);
55 }
56 });
57
58 if (cacheable && !(command in this.Cache)) {
59 this.Cache[command] = awaitExec;
60 }
61
62 return awaitExec;
63 }
64
65 exec(command, options = {}, context = {}) {
66 return command ? this._exec(format(command, context), options) : noop;
67 }
68}
69
70module.exports = Shell;