-
Notifications
You must be signed in to change notification settings - Fork 46
/
index.js
133 lines (120 loc) · 3.57 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
'use strict';
const path = require('path');
const through2 = require('through2');
const dargs = require('dargs');
const gutil = require('gulp-util');
const groupBy = require('lodash.groupby');
const PQueue = require('p-queue');
const commandRunner = require('./lib/command-runner');
const commands = {
tsd: ['reinstall', '--save'],
bower: ['install', '--config.interactive=false'],
npm: ['install'],
pip: ['install', '-r', 'requirements.txt'],
composer: ['install'],
typings: ['install']
};
const defaultFileToCommand = {
'tsd.json': 'tsd',
'bower.json': 'bower',
'package.json': 'npm',
'requirements.txt': 'pip',
'composer.json': 'composer',
'typings.json': 'typings'
};
const noop = () => {};
module.exports = function (opts = {}, done = noop) {
if (typeof opts === 'function') {
done = opts;
opts = {};
}
const fileToCommand = Object.assign(
{},
defaultFileToCommand,
opts.commands
);
const toRun = [];
return through2(
{objectMode: true},
function (file, enc, cb) {
if (!file.path) {
return cb();
}
if (fileToCommand[path.basename(file.path)]) {
const cmd = {
cmd: fileToCommand[path.basename(file.path)],
args: (commands[fileToCommand[path.basename(file.path)]] || []).slice()
};
if (['bower', 'npm'].includes(cmd.cmd) && opts.production) {
cmd.args.push('--production');
}
if (cmd.cmd === 'npm' && opts.ignoreScripts) {
cmd.args.push('--ignore-scripts');
}
if (opts.args) {
cmd.args = cmd.args.concat(opts.args).map(arg => arg.toString());
}
if (Array.isArray(opts[cmd.cmd])) {
cmd.args = cmd.args.concat(opts[cmd.cmd].map(arg => arg.toString()));
} else if (typeof opts[cmd.cmd] === 'object') {
cmd.args = cmd.args.concat(dargs(opts[cmd.cmd]));
} else if (opts[cmd.cmd]) {
cmd.args = cmd.args.concat(opts[cmd.cmd].toString());
}
if (cmd.cmd === 'bower' && opts.allowRoot) {
cmd.args.push('--allow-root');
}
if (cmd.cmd === 'npm' && opts.noOptional) {
cmd.args.push('--no-optional');
}
cmd.cwd = path.dirname(file.path);
toRun.push(cmd);
}
this.push(file);
cb();
},
cb => {
if (toRun.length === 0) {
return cb();
}
if (skipInstall()) {
log('Skipping install.', 'Run `' + gutil.colors.yellow(formatCommands(toRun)) + '` manually');
return cb();
}
const groupedCommands = groupBy(toRun, 'cmd');
Promise.all(Object.keys(groupedCommands).map(cmd => {
const commands = groupedCommands[cmd];
const queue = new PQueue({concurrency: 1});
return Promise.all(commands.map(command => queue.add(() => logFailure(command)(commandRunner.run(command)))));
}))
.then(() => done())
.then(() => cb(), cb); // eslint-disable-line promise/no-callback-in-promise
}
);
};
function logFailure(command) {
return promise => {
return promise.catch(err => {
log(err.message, ', run `' + gutil.colors.yellow(formatCommand(command)) + '` manually');
throw err;
});
};
}
function log(...args) {
if (isTest()) {
return;
}
gutil.log(...args);
}
function formatCommands(cmds) {
return cmds.map(formatCommand).join(' && ');
}
function formatCommand(command) {
return command.cmd + ' ' + command.args.join(' ');
}
function skipInstall() {
return process.argv.slice(2).includes('--skip-install');
}
function isTest() {
return process.env.NODE_ENV === 'test';
}