UNPKG

2.35 kBJavaScriptView Raw
1const sh = require('shelljs');
2const execa = require('execa');
3const debug = require('debug')('release-it:shell');
4const { format } = require('./util');
5
6sh.config.silent = !debug.enabled;
7
8const noop = Promise.resolve();
9
10class Shell {
11 constructor({ global = {}, container }) {
12 this.global = global;
13 this.log = container.log;
14 this.config = container.config;
15 }
16
17 exec(command, options = {}, context = {}) {
18 if (!command || !command.length) return;
19 return typeof command === 'string'
20 ? this.execFormattedCommand(format(command, context), options)
21 : this.execFormattedCommand(command, options);
22 }
23
24 async execFormattedCommand(command, options = {}) {
25 const isDryRun = this.global.isDryRun;
26 const isWrite = options.write !== false;
27 const isExternal = options.external === true;
28
29 if (isDryRun && isWrite) {
30 this.log.exec(command, { isDryRun });
31 return noop;
32 }
33
34 this.log.exec(command, { isExternal });
35
36 if (typeof command === 'string') {
37 return this.execStringCommand(command, options, { isExternal });
38 } else {
39 return this.execWithArguments(command, options, { isExternal });
40 }
41 }
42
43 execStringCommand(command, options, { isExternal }) {
44 return new Promise((resolve, reject) => {
45 sh.exec(command, { async: true }, (code, stdout, stderr) => {
46 stdout = stdout.toString().trim();
47 this.log.verbose(stdout, { isExternal });
48 debug({ command, options, code, stdout, stderr });
49 if (code === 0) {
50 resolve(stdout);
51 } else {
52 if (stdout && stderr) {
53 this.log.log(`\n${stdout}`);
54 }
55 reject(new Error(stderr || stdout));
56 }
57 });
58 });
59 }
60
61 async execWithArguments(command, options, { isExternal }) {
62 const [program, ...programArgs] = command;
63
64 try {
65 const { stdout: out, stderr } = await execa(program, programArgs);
66 const stdout = out === '""' ? '' : out;
67 this.log.verbose(stdout, { isExternal });
68 debug({ command, options, stdout, stderr });
69 return Promise.resolve(stdout || stderr);
70 } catch (error) {
71 if (error.stdout) {
72 this.log.log(`\n${error.stdout}`);
73 }
74 debug({ error });
75 return Promise.reject(new Error(error.stderr || error.message));
76 }
77 }
78}
79
80module.exports = Shell;