zarro 1.92.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (201) hide show
  1. package/LICENSE +10 -0
  2. package/README.md +260 -0
  3. package/gulp-tasks/.editorconfig +8 -0
  4. package/gulp-tasks/.git +1 -0
  5. package/gulp-tasks/.gitignore +9 -0
  6. package/gulp-tasks/.gitmodules +0 -0
  7. package/gulp-tasks/LICENSE +24 -0
  8. package/gulp-tasks/README.md +144 -0
  9. package/gulp-tasks/build.js +135 -0
  10. package/gulp-tasks/clean.js +37 -0
  11. package/gulp-tasks/cover-dotnet.js +56 -0
  12. package/gulp-tasks/default-report-generator.js +51 -0
  13. package/gulp-tasks/default-tools-installer.js +33 -0
  14. package/gulp-tasks/default.js +17 -0
  15. package/gulp-tasks/dotnet-publish.js +23 -0
  16. package/gulp-tasks/generate-reports.js +7 -0
  17. package/gulp-tasks/get-local-nuget.js +16 -0
  18. package/gulp-tasks/git-submodules.js +83 -0
  19. package/gulp-tasks/increment-package-json-version.js +12 -0
  20. package/gulp-tasks/increment-package-json-version.ts +17 -0
  21. package/gulp-tasks/install-tools.js +24 -0
  22. package/gulp-tasks/modules/add-stream-on-any-handler.js +31 -0
  23. package/gulp-tasks/modules/alter-package-json-version.js +64 -0
  24. package/gulp-tasks/modules/alter-package-json-version.ts +113 -0
  25. package/gulp-tasks/modules/are-all-dotnet-core.js +96 -0
  26. package/gulp-tasks/modules/ask.js +31 -0
  27. package/gulp-tasks/modules/ask.ts +41 -0
  28. package/gulp-tasks/modules/collect-files.js +15 -0
  29. package/gulp-tasks/modules/collect-files.ts +16 -0
  30. package/gulp-tasks/modules/config-generator.js +10 -0
  31. package/gulp-tasks/modules/defaults.js +9 -0
  32. package/gulp-tasks/modules/download-nuget.js +104 -0
  33. package/gulp-tasks/modules/ensure-folder-exists.js +21 -0
  34. package/gulp-tasks/modules/env-helpers.js +49 -0
  35. package/gulp-tasks/modules/env-helpers.ts +67 -0
  36. package/gulp-tasks/modules/env.js +364 -0
  37. package/gulp-tasks/modules/exec.js +257 -0
  38. package/gulp-tasks/modules/exec.ts +346 -0
  39. package/gulp-tasks/modules/fail-after.js +30 -0
  40. package/gulp-tasks/modules/fail-after.ts +34 -0
  41. package/gulp-tasks/modules/fallback.js +6 -0
  42. package/gulp-tasks/modules/find-dirs.js +39 -0
  43. package/gulp-tasks/modules/find-local-nuget.js +42 -0
  44. package/gulp-tasks/modules/find-npm-base.js +42 -0
  45. package/gulp-tasks/modules/fs.js +79 -0
  46. package/gulp-tasks/modules/gather-paths.js +23 -0
  47. package/gulp-tasks/modules/gather-paths.ts +29 -0
  48. package/gulp-tasks/modules/generate-env-help-for.js +30 -0
  49. package/gulp-tasks/modules/get-tools-folder.js +12 -0
  50. package/gulp-tasks/modules/git-push-tags.js +33 -0
  51. package/gulp-tasks/modules/git-push-tags.ts +42 -0
  52. package/gulp-tasks/modules/git-push.js +51 -0
  53. package/gulp-tasks/modules/git-tag.js +36 -0
  54. package/gulp-tasks/modules/gulp-dotnetcover.js +537 -0
  55. package/gulp-tasks/modules/gulp-git-tag-from-csproj.js +50 -0
  56. package/gulp-tasks/modules/gulp-git-tag-from-csproj.ts +71 -0
  57. package/gulp-tasks/modules/gulp-git-tag-from-package-nuspec.js +55 -0
  58. package/gulp-tasks/modules/gulp-increment-nuget-package-dependency-version.js +40 -0
  59. package/gulp-tasks/modules/gulp-increment-nuget-package-version.js +87 -0
  60. package/gulp-tasks/modules/gulp-increment-nuget-package-version.ts +122 -0
  61. package/gulp-tasks/modules/gulp-msbuild.js +1 -0
  62. package/gulp-tasks/modules/gulp-npm-run.js +40 -0
  63. package/gulp-tasks/modules/gulp-npm-run.ts +52 -0
  64. package/gulp-tasks/modules/gulp-nuget-pack.js +168 -0
  65. package/gulp-tasks/modules/gulp-nuget-restore.js +106 -0
  66. package/gulp-tasks/modules/gulp-nunit-runner/.jshintrc +5 -0
  67. package/gulp-tasks/modules/gulp-nunit-runner/.npmignore +16 -0
  68. package/gulp-tasks/modules/gulp-nunit-runner/LICENSE +21 -0
  69. package/gulp-tasks/modules/gulp-nunit-runner/README.md +300 -0
  70. package/gulp-tasks/modules/gulp-nunit-runner/index.js +1 -0
  71. package/gulp-tasks/modules/gulp-nunit-runner/lib/index.js +205 -0
  72. package/gulp-tasks/modules/gulp-nunit-runner/lib/teamcity.js +86 -0
  73. package/gulp-tasks/modules/gulp-purge.js +88 -0
  74. package/gulp-tasks/modules/gulp-util.js +5 -0
  75. package/gulp-tasks/modules/gulp-version.js +8 -0
  76. package/gulp-tasks/modules/gulp-with-help.js +1 -0
  77. package/gulp-tasks/modules/gulp-xbuild.js +62 -0
  78. package/gulp-tasks/modules/gulp.js +92 -0
  79. package/gulp-tasks/modules/http-downloader.js +113 -0
  80. package/gulp-tasks/modules/import-npm-tasks.js +33 -0
  81. package/gulp-tasks/modules/increment-version-string.js +18 -0
  82. package/gulp-tasks/modules/increment-version.js +30 -0
  83. package/gulp-tasks/modules/increment-version.ts +41 -0
  84. package/gulp-tasks/modules/install-local-tools.js +122 -0
  85. package/gulp-tasks/modules/load-xml-file.js +12 -0
  86. package/gulp-tasks/modules/load-xml-file.ts +15 -0
  87. package/gulp-tasks/modules/log-config.js +31 -0
  88. package/gulp-tasks/modules/log.js +142 -0
  89. package/gulp-tasks/modules/longest-string-length.js +13 -0
  90. package/gulp-tasks/modules/looks-like-a-promise.js +11 -0
  91. package/gulp-tasks/modules/ls-r.js +52 -0
  92. package/gulp-tasks/modules/multi-split.js +29 -0
  93. package/gulp-tasks/modules/net-framework-test-assembly-filter.js +45 -0
  94. package/gulp-tasks/modules/nuget-push.js +66 -0
  95. package/gulp-tasks/modules/nuget-update-self.js +9 -0
  96. package/gulp-tasks/modules/nuget.js +8 -0
  97. package/gulp-tasks/modules/nuget.ts +14 -0
  98. package/gulp-tasks/modules/pad-left.js +4 -0
  99. package/gulp-tasks/modules/pad-right.js +4 -0
  100. package/gulp-tasks/modules/pad.js +25 -0
  101. package/gulp-tasks/modules/parse-xml-string.js +5 -0
  102. package/gulp-tasks/modules/parse-xml-string.ts +6 -0
  103. package/gulp-tasks/modules/parse-xml.js +14 -0
  104. package/gulp-tasks/modules/parse-xml.ts +15 -0
  105. package/gulp-tasks/modules/path-unquote.js +6 -0
  106. package/gulp-tasks/modules/promisify-function.js +19 -0
  107. package/gulp-tasks/modules/promisify-function.ts +18 -0
  108. package/gulp-tasks/modules/promisify-stream.js +73 -0
  109. package/gulp-tasks/modules/promisify.js +1 -0
  110. package/gulp-tasks/modules/quote-if-required.js +14 -0
  111. package/gulp-tasks/modules/read-all-git-branches.js +10 -0
  112. package/gulp-tasks/modules/read-all-git-branches.ts +13 -0
  113. package/gulp-tasks/modules/read-all-git-remotes.js +36 -0
  114. package/gulp-tasks/modules/read-all-git-remotes.ts +44 -0
  115. package/gulp-tasks/modules/read-csproj-package-version.js +16 -0
  116. package/gulp-tasks/modules/read-csproj-package-version.ts +26 -0
  117. package/gulp-tasks/modules/read-csproj-version.js +16 -0
  118. package/gulp-tasks/modules/read-csproj-version.ts +26 -0
  119. package/gulp-tasks/modules/read-current-git-branch.js +12 -0
  120. package/gulp-tasks/modules/read-current-git-branch.ts +16 -0
  121. package/gulp-tasks/modules/read-git-commit-delta-count.js +21 -0
  122. package/gulp-tasks/modules/read-git-commit-delta-count.ts +33 -0
  123. package/gulp-tasks/modules/read-git-info.js +28 -0
  124. package/gulp-tasks/modules/read-git-info.ts +31 -0
  125. package/gulp-tasks/modules/read-git-remote.js +17 -0
  126. package/gulp-tasks/modules/read-git-remote.ts +23 -0
  127. package/gulp-tasks/modules/read-last-fetch-time.js +21 -0
  128. package/gulp-tasks/modules/read-last-fetch-time.ts +17 -0
  129. package/gulp-tasks/modules/read-main-branch-name.js +48 -0
  130. package/gulp-tasks/modules/read-main-branch-name.ts +76 -0
  131. package/gulp-tasks/modules/read-nuspec-version.js +14 -0
  132. package/gulp-tasks/modules/read-nuspec-version.ts +22 -0
  133. package/gulp-tasks/modules/read-package-json.js +16 -0
  134. package/gulp-tasks/modules/read-package-json.ts +22 -0
  135. package/gulp-tasks/modules/read-package-version.js +8 -0
  136. package/gulp-tasks/modules/read-package-version.ts +10 -0
  137. package/gulp-tasks/modules/read-text-file.js +14 -0
  138. package/gulp-tasks/modules/read-text-file.ts +14 -0
  139. package/gulp-tasks/modules/reduce-gulp-noise.js +34 -0
  140. package/gulp-tasks/modules/register-environment-variables.js +526 -0
  141. package/gulp-tasks/modules/require-module.js +28 -0
  142. package/gulp-tasks/modules/resolve-git-branch.js +11 -0
  143. package/gulp-tasks/modules/resolve-git-branch.ts +13 -0
  144. package/gulp-tasks/modules/resolve-git-remote.js +11 -0
  145. package/gulp-tasks/modules/resolve-git-remote.ts +13 -0
  146. package/gulp-tasks/modules/resolve-masks.js +47 -0
  147. package/gulp-tasks/modules/resolve-nuget.js +135 -0
  148. package/gulp-tasks/modules/resolve-test-masks.js +10 -0
  149. package/gulp-tasks/modules/rewrite-file.js +26 -0
  150. package/gulp-tasks/modules/rewrite-file.ts +34 -0
  151. package/gulp-tasks/modules/rimraf.js +21 -0
  152. package/gulp-tasks/modules/rimraf.ts +31 -0
  153. package/gulp-tasks/modules/run-sequence.js +16 -0
  154. package/gulp-tasks/modules/safe-git.js +23 -0
  155. package/gulp-tasks/modules/safe-git.ts +23 -0
  156. package/gulp-tasks/modules/seed.js +12 -0
  157. package/gulp-tasks/modules/set-task-name.js +9 -0
  158. package/gulp-tasks/modules/sleep.js +5 -0
  159. package/gulp-tasks/modules/spawn-nuget.js +13 -0
  160. package/gulp-tasks/modules/spawn.js +103 -0
  161. package/gulp-tasks/modules/split-path.js +3 -0
  162. package/gulp-tasks/modules/stat.js +8 -0
  163. package/gulp-tasks/modules/status.js +57 -0
  164. package/gulp-tasks/modules/status.ts +71 -0
  165. package/gulp-tasks/modules/test-path.js +3 -0
  166. package/gulp-tasks/modules/testutil-finder.js +176 -0
  167. package/gulp-tasks/modules/throw-if-no-files.js +15 -0
  168. package/gulp-tasks/modules/uniq.js +6 -0
  169. package/gulp-tasks/modules/uniq.ts +5 -0
  170. package/gulp-tasks/modules/verify-exe.js +17 -0
  171. package/gulp-tasks/modules/version-reading-shared.js +12 -0
  172. package/gulp-tasks/modules/version-reading-shared.ts +16 -0
  173. package/gulp-tasks/modules/write-text-file.js +10 -0
  174. package/gulp-tasks/modules/zarro-error.js +6 -0
  175. package/gulp-tasks/nuget-restore.js +57 -0
  176. package/gulp-tasks/pack.js +118 -0
  177. package/gulp-tasks/purge.js +94 -0
  178. package/gulp-tasks/release-npm.js +58 -0
  179. package/gulp-tasks/release-npm.ts +81 -0
  180. package/gulp-tasks/start/_package.json +39 -0
  181. package/gulp-tasks/start/gulpfile.js +204 -0
  182. package/gulp-tasks/start/update-starter-packages.js +63 -0
  183. package/gulp-tasks/test-dotnet.js +195 -0
  184. package/gulp-tasks/update-git-submodules.js +11 -0
  185. package/gulp-tasks/update-git-submodules.ts +29 -0
  186. package/gulp-tasks/update-self.js +65 -0
  187. package/gulp-tasks/update-self.ts +88 -0
  188. package/gulp-tasks/verify-up-to-date.js +77 -0
  189. package/gulp-tasks/verify-up-to-date.ts +119 -0
  190. package/index-modules/contains-any.js +31 -0
  191. package/index-modules/gather-args.js +21 -0
  192. package/index-modules/handlers/help.js +17 -0
  193. package/index-modules/handlers/init.js +57 -0
  194. package/index-modules/handlers/invoke-gulp.js +111 -0
  195. package/index-modules/handlers/show-env.js +46 -0
  196. package/index-modules/is-dir.js +6 -0
  197. package/index-modules/is-file.js +6 -0
  198. package/index.js +53 -0
  199. package/package.json +96 -0
  200. package/tsconfig.json +66 -0
  201. package/types.d.ts +753 -0
@@ -0,0 +1,257 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ (function () {
4
+ // MUST use for running batch files
5
+ // you can use this for other commands but spawn is better
6
+ // as it handles IO better
7
+ const quoteIfRequired = require("./quote-if-required"), failAfter = requireModule("fail-after"), os = require("os"), spawn = require("./spawn"), debug = require("debug")("exec"), log = require("./log"), child_process = require("child_process");
8
+ function makeDefaultOptions() {
9
+ return {
10
+ cwd: process.cwd(),
11
+ shell: true
12
+ };
13
+ }
14
+ function doExecFile(cmd, args, opts, handlers) {
15
+ return new Promise((resolve, reject) => {
16
+ try {
17
+ child_process.execFile(cmd, args, opts, function (error, stdout, stderr) {
18
+ const stdErrString = (stderr || "").toString();
19
+ const stdOutString = (stdout || "").toString();
20
+ if ((handlers === null || handlers === void 0 ? void 0 : handlers.stdout) && stdOutString) {
21
+ handlers.stdout(stdOutString);
22
+ }
23
+ if (handlers === null || handlers === void 0 ? void 0 : handlers.stderr) {
24
+ handlers.stderr(stdErrString);
25
+ }
26
+ if (error) {
27
+ return reject({
28
+ error: error,
29
+ stderr: stderr,
30
+ stdout: stdout
31
+ });
32
+ }
33
+ resolve(stdout.toString());
34
+ });
35
+ }
36
+ catch (e) {
37
+ console.error(`EXEC ERROR: ${e} / ${cmd} ${args}`);
38
+ reject(e);
39
+ }
40
+ });
41
+ }
42
+ function trim(data) {
43
+ return ("" + (data || "")).trim();
44
+ }
45
+ function isWarning(str) {
46
+ return str.indexOf(" WARN ") > -1;
47
+ }
48
+ function isError(str) {
49
+ return str.indexOf(" ERROR ") > -1;
50
+ }
51
+ function printLines(collector, suppress, data) {
52
+ const lines = trim(data).split("\n");
53
+ lines.forEach(function (line) {
54
+ line = trim(line);
55
+ collector.push(line);
56
+ if (suppress) {
57
+ return;
58
+ }
59
+ if (isError(line)) {
60
+ log.error(line);
61
+ }
62
+ else if (isWarning(line)) {
63
+ log.warning(line);
64
+ }
65
+ else {
66
+ log.info(line);
67
+ }
68
+ });
69
+ }
70
+ function start(cmd, args, opts) {
71
+ if (os.platform() == "win32") {
72
+ const cmdArgs = ["/c", cmd];
73
+ cmdArgs.push.apply(cmdArgs, args);
74
+ log.suppressTimeStamps();
75
+ return child_process.spawn("cmd.exe", cmdArgs, opts);
76
+ }
77
+ else {
78
+ return child_process.spawn(cmd, args, opts);
79
+ }
80
+ }
81
+ function doWindowsStart(cmd, args, opts, handlers) {
82
+ var _a;
83
+ handlers = handlers || {};
84
+ const collectedStdOut = [];
85
+ const collectedStdErr = [];
86
+ opts.suppressOutput = (_a = opts.suppressOutput) !== null && _a !== void 0 ? _a : false;
87
+ const stdoutHandler = handlers.stdout || (printLines.bind(null, collectedStdOut, opts.suppressOutput));
88
+ const stderrHandler = handlers.stderr || ((line) => {
89
+ collectedStdErr.push(line);
90
+ if (!opts.suppressOutput) {
91
+ log.error(line);
92
+ }
93
+ });
94
+ return new Promise((resolve, reject) => {
95
+ try {
96
+ log.suppressTimeStamps();
97
+ const proc = start(cmd, args, opts);
98
+ if (proc.stdout) {
99
+ proc.stdout.on("data", (data) => {
100
+ stdoutHandler(data.toString());
101
+ });
102
+ }
103
+ if (proc.stderr) {
104
+ proc.stderr.on("data", (data) => {
105
+ stderrHandler(trim(data.toString()));
106
+ });
107
+ }
108
+ proc.on("close", function (exitCode) {
109
+ log.showTimeStamps();
110
+ if (exitCode) {
111
+ const e = new Error(`
112
+ Command exited with code ${exitCode}
113
+ More info:
114
+ command: ${cmd}
115
+ args: ${args.join(" ")}
116
+ stderr:
117
+ ${collectedStdErr.join("\n ")}
118
+ stdout:
119
+ ${collectedStdOut.join("\n ")}
120
+ `.trim());
121
+ reject(attachExecInfo(e, exitCode, cmd, args, false, opts, collectedStdOut, collectedStdErr));
122
+ }
123
+ else {
124
+ resolve(collectedStdOut.join("\n"));
125
+ }
126
+ });
127
+ proc.on("error", function (err) {
128
+ log.showTimeStamps();
129
+ log.error("failed to start process");
130
+ log.error(err);
131
+ reject(attachExecInfo(err, -1, cmd, args, false, opts));
132
+ });
133
+ }
134
+ catch (e) {
135
+ reject(attachExecInfo(e, -1, cmd, args, false, opts));
136
+ }
137
+ });
138
+ }
139
+ function attachExecInfo(e, exitCode, cmd, args, timedOut, opts, collectedStdOut, collectedStdErr) {
140
+ const err = e;
141
+ err.info = {
142
+ exitCode,
143
+ cmd,
144
+ args,
145
+ opts,
146
+ stdout: collectedStdOut || [],
147
+ stderr: collectedStdErr || [],
148
+ timedOut
149
+ };
150
+ return err;
151
+ }
152
+ function doExec(cmd, args, opts, handlers) {
153
+ debugger;
154
+ return (opts === null || opts === void 0 ? void 0 : opts._useExecFile)
155
+ ? doExecFile(cmd, args, opts, handlers)
156
+ : doWindowsStart(cmd, args, opts, handlers);
157
+ }
158
+ function noop() {
159
+ // intentionally blank
160
+ }
161
+ function makeSafe(consumer) {
162
+ return (data) => {
163
+ try {
164
+ consumer(data);
165
+ }
166
+ catch (e) {
167
+ // suppress
168
+ }
169
+ };
170
+ }
171
+ async function doSpawn(cmd, args, opts, handlers) {
172
+ var _a, _b;
173
+ const stderr = [], stdout = [], merged = [], callerStdErr = (_a = handlers === null || handlers === void 0 ? void 0 : handlers.stderr) !== null && _a !== void 0 ? _a : noop, callerStdOut = (_b = handlers === null || handlers === void 0 ? void 0 : handlers.stdout) !== null && _b !== void 0 ? _b : noop, safeCallerStdErr = makeSafe(callerStdErr), safeCallerStdOut = makeSafe(callerStdOut), stdErrPrinter = (opts === null || opts === void 0 ? void 0 : opts.suppressOutput) ? noop : console.error.bind(console), stdOutPrinter = (opts === null || opts === void 0 ? void 0 : opts.suppressOutput) ? noop : console.log.bind(console);
174
+ const myHandlers = {
175
+ stderr: data => {
176
+ const dataStr = data.toString();
177
+ stderr.push(dataStr);
178
+ merged.push(dataStr);
179
+ stdErrPrinter(dataStr);
180
+ safeCallerStdErr(dataStr);
181
+ },
182
+ stdout: data => {
183
+ const dataStr = data.toString();
184
+ stdout.push(dataStr);
185
+ merged.push(dataStr);
186
+ stdOutPrinter(dataStr);
187
+ safeCallerStdOut(dataStr);
188
+ }
189
+ };
190
+ const spawnOptions = Object.assign(Object.assign({}, opts), myHandlers);
191
+ try {
192
+ await spawn(cmd, args, spawnOptions);
193
+ return (opts === null || opts === void 0 ? void 0 : opts.mergeIo) ? merged.join("\n")
194
+ : stdout.join("\n");
195
+ }
196
+ catch (e) {
197
+ attachExecInfo(e, e.exitCode, cmd, args, false, opts);
198
+ if (e.stderr) {
199
+ e.info.stderr = e.stderr;
200
+ }
201
+ if (e.stdout) {
202
+ e.info.stdout = e.stdout;
203
+ }
204
+ throw e;
205
+ }
206
+ }
207
+ async function exec(cmd, args, opts, handlers) {
208
+ args = args || [];
209
+ opts = Object.assign({}, makeDefaultOptions(), opts);
210
+ opts.maxBuffer = Number.MAX_SAFE_INTEGER;
211
+ cmd = quoteIfRequired(cmd);
212
+ if (exec.alwaysSuppressOutput) {
213
+ opts.suppressOutput = true;
214
+ }
215
+ if (debug) {
216
+ debug("executing:");
217
+ debug(`- cmd: ${cmd}`);
218
+ debug(`- args: ${JSON.stringify(args)}`);
219
+ debug(`- opts: ${JSON.stringify(opts)}`);
220
+ debug(`- handlers: ${JSON.stringify(handlers)}`);
221
+ }
222
+ let timeout = 0;
223
+ if ((opts === null || opts === void 0 ? void 0 : opts.timeout) && opts.timeout > 0) {
224
+ // extend the provided timeout -- node will stop the child process
225
+ // and we need to race a failing promise there first
226
+ timeout = opts.timeout;
227
+ opts.timeout += 50;
228
+ }
229
+ // noinspection ES6MissingAwait
230
+ const promise = os.platform() === "win32"
231
+ ? doExec(cmd, args, opts, handlers || {})
232
+ : doSpawn(cmd, args, Object.assign({}, opts), handlers);
233
+ if (!timeout) {
234
+ return promise;
235
+ }
236
+ try {
237
+ const fail = failAfter(timeout);
238
+ const result = await Promise.race([
239
+ promise,
240
+ fail.promise
241
+ ]);
242
+ fail.cancel();
243
+ return result;
244
+ }
245
+ catch (e) {
246
+ const execError = e;
247
+ if (execError.info) {
248
+ // info was attached elsewhere
249
+ throw execError;
250
+ }
251
+ const err = new Error("timed out");
252
+ attachExecInfo(err, 1, cmd, args, true, opts);
253
+ throw err;
254
+ }
255
+ }
256
+ module.exports = exec;
257
+ })();
@@ -0,0 +1,346 @@
1
+ export type IoConsumer = (d: string) => void
2
+
3
+ export interface IoHandlers {
4
+ stdout?: IoConsumer;
5
+ stderr?: IoConsumer;
6
+ }
7
+
8
+ export interface ExecError extends Error {
9
+ info: {
10
+ exitCode: number;
11
+ cmd: string;
12
+ args: string[];
13
+ opts?: ExecOpts;
14
+ stdout: string[];
15
+ stderr: string[];
16
+ timedOut: boolean;
17
+ }
18
+ }
19
+
20
+ (function() {
21
+ // MUST use for running batch files
22
+ // you can use this for other commands but spawn is better
23
+ // as it handles IO better
24
+ const
25
+ quoteIfRequired = require("./quote-if-required"),
26
+ failAfter = requireModule<FailAfter>("fail-after"),
27
+ os = require("os"),
28
+ spawn = require("./spawn"),
29
+ debug = require("debug")("exec"),
30
+ log = require("./log"),
31
+ child_process = require("child_process");
32
+
33
+ function makeDefaultOptions() {
34
+ return {
35
+ cwd: process.cwd(),
36
+ shell: true
37
+ };
38
+ }
39
+
40
+ function doExecFile(
41
+ cmd: string,
42
+ args: string[],
43
+ opts: ExecOpts,
44
+ handlers?: IoHandlers): Promise<string> {
45
+
46
+ return new Promise((resolve, reject) => {
47
+ try {
48
+ child_process.execFile(cmd, args, opts, function(error: Error, stdout: Buffer, stderr: Buffer) {
49
+ const stdErrString = (stderr || "").toString();
50
+ const stdOutString = (stdout || "").toString();
51
+ if (handlers?.stdout && stdOutString) {
52
+ handlers.stdout(stdOutString);
53
+ }
54
+ if (handlers?.stderr) {
55
+ handlers.stderr(stdErrString);
56
+ }
57
+ if (error) {
58
+ return reject({
59
+ error: error,
60
+ stderr: stderr,
61
+ stdout: stdout
62
+ });
63
+ }
64
+ resolve(stdout.toString());
65
+ });
66
+ } catch (e) {
67
+ console.error(`EXEC ERROR: ${ e } / ${ cmd } ${ args }`);
68
+ reject(e);
69
+ }
70
+ });
71
+ }
72
+
73
+ function trim(data: string) {
74
+ return ("" + (data || "")).trim();
75
+ }
76
+
77
+ function isWarning(str: string) {
78
+ return str.indexOf(" WARN ") > -1;
79
+ }
80
+
81
+ function isError(str: string) {
82
+ return str.indexOf(" ERROR ") > -1;
83
+ }
84
+
85
+ function printLines(collector: string[], suppress: boolean, data: string) {
86
+ const lines = trim(data).split("\n");
87
+ lines.forEach(function(line) {
88
+ line = trim(line);
89
+ collector.push(line);
90
+ if (suppress) {
91
+ return;
92
+ }
93
+ if (isError(line)) {
94
+ log.error(line);
95
+ } else if (isWarning(line)) {
96
+ log.warning(line);
97
+ } else {
98
+ log.info(line);
99
+ }
100
+ });
101
+ }
102
+
103
+ function start(
104
+ cmd: string,
105
+ args: string[],
106
+ opts: ExecOpts
107
+ ) {
108
+ if (os.platform() == "win32") {
109
+ const cmdArgs = ["/c", cmd];
110
+ cmdArgs.push.apply(cmdArgs, args);
111
+ log.suppressTimeStamps();
112
+ return child_process.spawn("cmd.exe", cmdArgs, opts);
113
+ } else {
114
+ return child_process.spawn(cmd, args, opts);
115
+ }
116
+ }
117
+
118
+ function doWindowsStart(
119
+ cmd: string,
120
+ args: string[],
121
+ opts: ExecOpts,
122
+ handlers?: IoHandlers): Promise<string> {
123
+ handlers = handlers || {};
124
+ const collectedStdOut: string[] = [];
125
+ const collectedStdErr: string[] = [];
126
+ opts.suppressOutput = opts.suppressOutput ?? false;
127
+ const stdoutHandler = handlers.stdout || (printLines.bind(null, collectedStdOut, opts.suppressOutput)) as IoConsumer;
128
+ const stderrHandler = handlers.stderr || ((line: string) => {
129
+ collectedStdErr.push(line);
130
+ if (!opts.suppressOutput) {
131
+ log.error(line);
132
+ }
133
+ });
134
+ return new Promise((resolve, reject) => {
135
+ try {
136
+ log.suppressTimeStamps();
137
+ const proc = start(cmd, args, opts);
138
+ if (proc.stdout) {
139
+ proc.stdout.on("data", (data: Buffer & string) => {
140
+ stdoutHandler(data.toString());
141
+ });
142
+ }
143
+ if (proc.stderr) {
144
+ proc.stderr.on("data", (data: Buffer & string) => {
145
+ stderrHandler(trim(data.toString()));
146
+ });
147
+ }
148
+ proc.on("close", function(exitCode: number) {
149
+ log.showTimeStamps();
150
+ if (exitCode) {
151
+ const e = new Error(`
152
+ Command exited with code ${ exitCode }
153
+ More info:
154
+ command: ${ cmd }
155
+ args: ${ args.join(" ") }
156
+ stderr:
157
+ ${ collectedStdErr.join("\n ") }
158
+ stdout:
159
+ ${ collectedStdOut.join("\n ") }
160
+ `.trim()
161
+ ) as ExecError;
162
+ reject(
163
+ attachExecInfo(
164
+ e, exitCode, cmd, args, false, opts, collectedStdOut, collectedStdErr
165
+ )
166
+ );
167
+ } else {
168
+ resolve(collectedStdOut.join("\n"));
169
+ }
170
+ });
171
+ proc.on("error", function(err: Error) {
172
+ log.showTimeStamps();
173
+ log.error("failed to start process");
174
+ log.error(err);
175
+ reject(attachExecInfo(err, -1, cmd, args, false, opts));
176
+ });
177
+ } catch (e) {
178
+ reject(attachExecInfo(e, -1, cmd, args, false, opts));
179
+ }
180
+ });
181
+ }
182
+
183
+ function attachExecInfo(
184
+ e: Error,
185
+ exitCode: number,
186
+ cmd: string,
187
+ args: string[],
188
+ timedOut: boolean,
189
+ opts?: ExecOpts,
190
+ collectedStdOut?: string[],
191
+ collectedStdErr?: string[],
192
+ ): ExecError {
193
+ const err = e as ExecError;
194
+ err.info = {
195
+ exitCode,
196
+ cmd,
197
+ args,
198
+ opts,
199
+ stdout: collectedStdOut || [],
200
+ stderr: collectedStdErr || [],
201
+ timedOut
202
+ }
203
+ return err;
204
+ }
205
+
206
+ function doExec(
207
+ cmd: string,
208
+ args: string[],
209
+ opts: ExecOpts,
210
+ handlers?: IoHandlers): Promise<string> {
211
+ debugger;
212
+ return (opts?._useExecFile)
213
+ ? doExecFile(cmd, args, opts, handlers)
214
+ : doWindowsStart(cmd, args, opts, handlers);
215
+ }
216
+
217
+ function noop() {
218
+ // intentionally blank
219
+ }
220
+
221
+ function makeSafe(consumer: IoConsumer) {
222
+ return (data: string) => {
223
+ try {
224
+ consumer(data);
225
+ } catch (e) {
226
+ // suppress
227
+ }
228
+ };
229
+ }
230
+
231
+ async function doSpawn(
232
+ cmd: string,
233
+ args: string[],
234
+ opts: ExecOpts,
235
+ handlers?: IoHandlers): Promise<string> {
236
+ const
237
+ stderr: string[] = [],
238
+ stdout: string[] = [],
239
+ merged: string[] = [],
240
+ callerStdErr = handlers?.stderr ?? noop,
241
+ callerStdOut = handlers?.stdout ?? noop,
242
+ safeCallerStdErr = makeSafe(callerStdErr),
243
+ safeCallerStdOut = makeSafe(callerStdOut),
244
+ stdErrPrinter = opts?.suppressOutput ? noop : console.error.bind(console),
245
+ stdOutPrinter = opts?.suppressOutput ? noop : console.log.bind(console);
246
+ const myHandlers: IoHandlers = {
247
+ stderr: data => {
248
+ const dataStr = data.toString();
249
+ stderr.push(dataStr);
250
+ merged.push(dataStr);
251
+ stdErrPrinter(dataStr);
252
+ safeCallerStdErr(dataStr);
253
+ },
254
+ stdout: data => {
255
+ const dataStr = data.toString();
256
+ stdout.push(dataStr)
257
+ merged.push(dataStr);
258
+ stdOutPrinter(dataStr);
259
+ safeCallerStdOut(dataStr);
260
+ }
261
+ }
262
+ const spawnOptions = {
263
+ ...opts,
264
+ ...myHandlers
265
+ };
266
+ try {
267
+ await spawn(
268
+ cmd,
269
+ args,
270
+ spawnOptions
271
+ )
272
+ return opts?.mergeIo
273
+ ? merged.join("\n")
274
+ : stdout.join("\n");
275
+ } catch (e) {
276
+ attachExecInfo(e, e.exitCode, cmd, args, false, opts);
277
+ if (e.stderr) {
278
+ e.info.stderr = e.stderr;
279
+ }
280
+ if (e.stdout) {
281
+ e.info.stdout = e.stdout;
282
+ }
283
+ throw e;
284
+ }
285
+ }
286
+
287
+ async function exec(
288
+ cmd: string,
289
+ args?: string[],
290
+ opts?: ExecOpts,
291
+ handlers?: IoHandlers
292
+ ): Promise<string> {
293
+ args = args || [];
294
+ opts = Object.assign({}, makeDefaultOptions(), opts);
295
+ opts.maxBuffer = Number.MAX_SAFE_INTEGER;
296
+ cmd = quoteIfRequired(cmd);
297
+ if ((exec as any).alwaysSuppressOutput) {
298
+ opts.suppressOutput = true;
299
+ }
300
+ if (debug) {
301
+ debug("executing:")
302
+ debug(`- cmd: ${ cmd }`);
303
+ debug(`- args: ${ JSON.stringify(args) }`);
304
+ debug(`- opts: ${ JSON.stringify(opts) }`);
305
+ debug(`- handlers: ${ JSON.stringify(handlers) }`);
306
+ }
307
+
308
+ let timeout = 0;
309
+ if (opts?.timeout && opts.timeout > 0) {
310
+ // extend the provided timeout -- node will stop the child process
311
+ // and we need to race a failing promise there first
312
+ timeout = opts.timeout;
313
+ opts.timeout += 50;
314
+ }
315
+ // noinspection ES6MissingAwait
316
+ const promise = os.platform() === "win32"
317
+ ? doExec(cmd, args, opts, handlers || {})
318
+ : doSpawn(cmd, args, Object.assign({}, opts), handlers);
319
+
320
+ if (!timeout) {
321
+ return promise;
322
+ }
323
+
324
+ try {
325
+ const fail = failAfter(timeout);
326
+ const result = await Promise.race([
327
+ promise,
328
+ fail.promise
329
+ ]) as string;
330
+ fail.cancel();
331
+ return result;
332
+ } catch (e) {
333
+ const execError = e as ExecError;
334
+ if (execError.info) {
335
+ // info was attached elsewhere
336
+ throw execError
337
+ }
338
+ const err = new Error("timed out");
339
+ attachExecInfo(err, 1, cmd, args, true, opts);
340
+ throw err;
341
+ }
342
+ }
343
+
344
+
345
+ module.exports = exec;
346
+ })();