forked from sun-zheng-an/gulp-shell
-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
122 lines (99 loc) · 2.99 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
var _ = require('lodash')
var async = require('async')
var exec = require('child_process').exec
var gutil = require('gulp-util')
var path = require('path')
var through = require('through2')
var PLUGIN_NAME = 'gulp-shell'
function normalizeCommands(commands) {
if (typeof commands === 'string') {
commands = [commands]
}
if (!Array.isArray(commands)) {
throw new gutil.PluginError(PLUGIN_NAME, 'Missing commands')
}
return commands
}
function normalizeOptions(options) {
options = _.extend({
verbose: false,
ignoreErrors: false,
errorMessage: 'Command `<%= command %>` failed with exit code <%= error.code %>',
quiet: false,
interactive: false,
cwd: process.cwd(),
maxBuffer: 16 * 1024 * 1024
}, options)
var pathToBin = path.join(process.cwd(), 'node_modules', '.bin')
var pathName = /^win/.test(process.platform) ? 'Path' : 'PATH'
var newPath = pathToBin + path.delimiter + process.env[pathName]
options.env = _.extend(process.env, _.zipObject([[pathName, newPath]]), options.env)
return options
}
function runCommands(commands, options, file, done) {
async.eachSeries(commands, function (command, done) {
var context = _.extend({file: file}, options.templateData)
command = gutil.template(command, context)
if (options.verbose) {
gutil.log(gutil.colors.cyan(command))
}
var child = exec(command, {
env: options.env,
cwd: options.cwd,
maxBuffer: options.maxBuffer,
timeout: options.timeout
}, function (error, stdout, stderr) {
if (options.interactive) {
process.stdin.unpipe(child.stdin)
process.stdin.resume()
process.stdin.pause()
}
if (error && !options.ignoreErrors) {
error.stdout = stdout
error.stderr = stderr
var errorContext = _.extend({
command: command,
file: file,
error: error
}, options.templateData)
error.message = gutil.template(options.errorMessage, errorContext)
}
done(options.ignoreErrors ? null : error)
})
if (options.interactive) {
process.stdin.resume()
process.stdin.setEncoding('utf8')
process.stdin.pipe(child.stdin)
}
if (!options.quiet) {
child.stdout.pipe(process.stdout)
child.stderr.pipe(process.stderr)
}
}, done)
}
function shell(commands, options) {
commands = normalizeCommands(commands)
options = normalizeOptions(options)
var stream = through.obj(function (file, unused, done) {
var self = this
runCommands(commands, options, file, function (error) {
if (error) {
self.emit('error', new gutil.PluginError({
plugin: PLUGIN_NAME,
message: error.message
}))
} else {
self.push(file)
}
done()
})
})
stream.resume()
return stream
}
shell.task = function (commands, options) {
return function (done) {
runCommands(normalizeCommands(commands), normalizeOptions(options), null, done)
}
}
module.exports = shell