1 | var common = require('./common');
|
2 | var _tempDir = require('./tempdir');
|
3 | var _pwd = require('./pwd');
|
4 | var path = require('path');
|
5 | var fs = require('fs');
|
6 | var child = require('child_process');
|
7 |
|
8 | var DEFAULT_MAXBUFFER_SIZE = 20 * 1024 * 1024;
|
9 |
|
10 | common.register('exec', _exec, {
|
11 | unix: false,
|
12 | canReceivePipe: true,
|
13 | wrapOutput: false,
|
14 | });
|
15 |
|
16 |
|
17 |
|
18 | function execSync(cmd, opts, pipe) {
|
19 | if (!common.config.execPath) {
|
20 | common.error('Unable to find a path to the node binary. Please manually set config.execPath');
|
21 | }
|
22 |
|
23 | var tempDir = _tempDir();
|
24 | var paramsFile = path.resolve(tempDir + '/' + common.randomFileName());
|
25 | var stderrFile = path.resolve(tempDir + '/' + common.randomFileName());
|
26 | var stdoutFile = path.resolve(tempDir + '/' + common.randomFileName());
|
27 |
|
28 | opts = common.extend({
|
29 | silent: common.config.silent,
|
30 | cwd: _pwd().toString(),
|
31 | env: process.env,
|
32 | maxBuffer: DEFAULT_MAXBUFFER_SIZE,
|
33 | encoding: 'utf8',
|
34 | }, opts);
|
35 |
|
36 | if (fs.existsSync(paramsFile)) common.unlinkSync(paramsFile);
|
37 | if (fs.existsSync(stderrFile)) common.unlinkSync(stderrFile);
|
38 | if (fs.existsSync(stdoutFile)) common.unlinkSync(stdoutFile);
|
39 |
|
40 | opts.cwd = path.resolve(opts.cwd);
|
41 |
|
42 | var paramsToSerialize = {
|
43 | command: cmd,
|
44 | execOptions: opts,
|
45 | pipe: pipe,
|
46 | stdoutFile: stdoutFile,
|
47 | stderrFile: stderrFile,
|
48 | };
|
49 |
|
50 | fs.writeFileSync(paramsFile, JSON.stringify(paramsToSerialize), 'utf8');
|
51 |
|
52 | var execArgs = [
|
53 | path.join(__dirname, 'exec-child.js'),
|
54 | paramsFile,
|
55 | ];
|
56 |
|
57 |
|
58 | if (opts.silent) {
|
59 | opts.stdio = 'ignore';
|
60 | } else {
|
61 | opts.stdio = [0, 1, 2];
|
62 | }
|
63 |
|
64 | var code = 0;
|
65 |
|
66 |
|
67 | try {
|
68 |
|
69 |
|
70 | delete opts.shell;
|
71 |
|
72 | child.execFileSync(common.config.execPath, execArgs, opts);
|
73 | } catch (e) {
|
74 |
|
75 | code = e.status;
|
76 | }
|
77 |
|
78 |
|
79 |
|
80 | var stdout;
|
81 | var stderr;
|
82 | if (opts.encoding === 'buffer') {
|
83 | stdout = fs.readFileSync(stdoutFile);
|
84 | stderr = fs.readFileSync(stderrFile);
|
85 | } else {
|
86 | stdout = fs.readFileSync(stdoutFile, opts.encoding);
|
87 | stderr = fs.readFileSync(stderrFile, opts.encoding);
|
88 | }
|
89 |
|
90 |
|
91 | try { common.unlinkSync(paramsFile); } catch (e) {}
|
92 | try { common.unlinkSync(stderrFile); } catch (e) {}
|
93 | try { common.unlinkSync(stdoutFile); } catch (e) {}
|
94 |
|
95 | if (code !== 0) {
|
96 | common.error('', code, { continue: true });
|
97 | }
|
98 | var obj = common.ShellString(stdout, stderr, code);
|
99 | return obj;
|
100 | }
|
101 |
|
102 |
|
103 | function execAsync(cmd, opts, pipe, callback) {
|
104 | opts = common.extend({
|
105 | silent: common.config.silent,
|
106 | cwd: _pwd().toString(),
|
107 | env: process.env,
|
108 | maxBuffer: DEFAULT_MAXBUFFER_SIZE,
|
109 | encoding: 'utf8',
|
110 | }, opts);
|
111 |
|
112 | var c = child.exec(cmd, opts, function (err, stdout, stderr) {
|
113 | if (callback) {
|
114 | if (!err) {
|
115 | callback(0, stdout, stderr);
|
116 | } else if (err.code === undefined) {
|
117 |
|
118 |
|
119 | callback(1, stdout, stderr);
|
120 | } else {
|
121 | callback(err.code, stdout, stderr);
|
122 | }
|
123 | }
|
124 | });
|
125 |
|
126 | if (pipe) c.stdin.end(pipe);
|
127 |
|
128 | if (!opts.silent) {
|
129 | c.stdout.pipe(process.stdout);
|
130 | c.stderr.pipe(process.stderr);
|
131 | }
|
132 |
|
133 | return c;
|
134 | }
|
135 |
|
136 |
|
137 |
|
138 |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 |
|
150 |
|
151 |
|
152 |
|
153 |
|
154 |
|
155 |
|
156 |
|
157 |
|
158 |
|
159 |
|
160 |
|
161 |
|
162 |
|
163 |
|
164 |
|
165 |
|
166 |
|
167 |
|
168 |
|
169 |
|
170 |
|
171 |
|
172 |
|
173 |
|
174 |
|
175 |
|
176 |
|
177 | function _exec(command, options, callback) {
|
178 | options = options || {};
|
179 | if (!command) common.error('must specify command');
|
180 |
|
181 | var pipe = common.readFromPipe();
|
182 |
|
183 |
|
184 | if (typeof options === 'function') {
|
185 | callback = options;
|
186 | options = { async: true };
|
187 | }
|
188 |
|
189 |
|
190 | if (typeof options === 'object' && typeof callback === 'function') {
|
191 | options.async = true;
|
192 | }
|
193 |
|
194 | options = common.extend({
|
195 | silent: common.config.silent,
|
196 | async: false,
|
197 | }, options);
|
198 |
|
199 | try {
|
200 | if (options.async) {
|
201 | return execAsync(command, options, pipe, callback);
|
202 | } else {
|
203 | return execSync(command, options, pipe);
|
204 | }
|
205 | } catch (e) {
|
206 | common.error('internal error');
|
207 | }
|
208 | }
|
209 | module.exports = _exec;
|