Skip to content

Commit c24d171

Browse files
committed
New: race option (fixes #42)
1 parent b740e19 commit c24d171

File tree

14 files changed

+107
-9
lines changed

14 files changed

+107
-9
lines changed

docs/node-api.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ Run npm-scripts.
5858
- **options.printName** `boolean` --
5959
Set the flag to print the task name before running each task.
6060
Default is `false`.
61+
- **options.race** `boolean` --
62+
Set the flag to kill all npm-scripts when a npm-script finished with zero.
63+
This option is valid only with `options.parallel` option.
64+
Default is `false`.
6165
- **options.silent** `boolean` --
6266
The flag to set `silent` to the log level of npm.
6367
Default is `false`.

docs/npm-run-all.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ Options:
4444
-p, --parallel <tasks> - Run a group of tasks in parallel.
4545
e.g. 'npm-run-all -p foo bar' is similar to
4646
'npm run foo & npm run bar'.
47+
-r, --race - - - - - - - Set the flag to kill all tasks when a task
48+
finished with zero. This option is valid only
49+
with 'parallel' option.
4750
-s, --sequential <tasks> - Run a group of tasks sequentially.
4851
--serial <tasks> e.g. 'npm-run-all -s foo bar' is similar to
4952
'npm run foo && npm run bar'.

docs/run-p.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ Options:
4040
coloring their output if this option was given.
4141
-n, --print-name - - - - Set the flag to print the task name before
4242
running each task.
43+
-r, --race - - - - - - - Set the flag to kill all tasks when a task
44+
finished with zero.
4345
-s, --silent - - - - - - Set 'silent' to the log level of npm.
4446
4547
Shorthand aliases can be combined.

src/bin/common/parse-cli-args.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const assign = require("object-assign")
1919

2020
const OVERWRITE_OPTION = /^--([^:]+?):([^=]+?)(?:=(.+))?$/
2121
const CONFIG_PATTERN = /^npm_package_config_(.+)$/
22-
const CONCAT_OPTIONS = /^-[clnps]+$/
22+
const CONCAT_OPTIONS = /^-[clnprs]+$/
2323

2424
/**
2525
* Overwrites a specified package config.
@@ -86,6 +86,7 @@ class ArgumentSet {
8686
this.groups = []
8787
this.printLabel = false
8888
this.printName = false
89+
this.race = false
8990
this.rest = []
9091
this.silent = process.env.npm_config_loglevel === "silent"
9192
this.singleMode = Boolean(options.singleMode)
@@ -100,6 +101,13 @@ class ArgumentSet {
100101
get lastGroup() {
101102
return this.groups[this.groups.length - 1]
102103
}
104+
105+
/**
106+
* Gets "parallel" flag.
107+
*/
108+
get parallel() {
109+
return this.groups.some(g => g.parallel)
110+
}
103111
}
104112

105113
/**
@@ -134,6 +142,11 @@ function parseCLIArgsCore(set, args) { // eslint-disable-line complexity
134142
set.printName = true
135143
break
136144

145+
case "-r":
146+
case "--race":
147+
set.race = true
148+
break
149+
137150
case "--silent":
138151
set.silent = true
139152
break
@@ -192,6 +205,12 @@ function parseCLIArgsCore(set, args) { // eslint-disable-line complexity
192205
}
193206
}
194207

208+
if (!set.parallel && set.race) {
209+
throw new Error(`Invalid Option: ${
210+
args.indexOf("--race") !== -1 ? "race" : "r"
211+
} (without parallel)`)
212+
}
213+
195214
return set
196215
}
197216

src/bin/npm-run-all/help.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ Options:
4545
-p, --parallel <tasks> - Run a group of tasks in parallel.
4646
e.g. 'npm-run-all -p foo bar' is similar to
4747
'npm run foo & npm run bar'.
48+
-r, --race - - - - - - - Set the flag to kill all tasks when a task
49+
finished with zero. This option is valid only
50+
with 'parallel' option.
4851
-s, --sequential <tasks> - Run a group of tasks sequentially.
4952
--serial <tasks> e.g. 'npm-run-all -s foo bar' is similar to
5053
'npm run foo && npm run bar'.

src/bin/npm-run-all/main.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ module.exports = function npmRunAll(args, stdout, stderr) {
3636
printLabel,
3737
printName,
3838
silent,
39+
race,
3940
rest,
4041
} = parseCLIArgs(args)
4142

@@ -57,6 +58,7 @@ module.exports = function npmRunAll(args, stdout, stderr) {
5758
packageConfig,
5859
silent,
5960
arguments: rest,
61+
race,
6062
}
6163
))
6264
},

src/bin/run-p/help.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ Options:
4242
coloring their output if this option was given.
4343
-n, --print-name - - - - Set the flag to print the task name before
4444
running each task.
45+
-r, --race - - - - - - - Set the flag to kill all tasks when a task
46+
finished with zero.
4547
-s, --silent - - - - - - Set 'silent' to the log level of npm.
4648
4749
Shorthand aliases can be combined.

src/bin/run-p/main.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ module.exports = function npmRunAll(args, stdout, stderr) {
3636
printLabel,
3737
printName,
3838
silent,
39+
race,
3940
rest,
4041
} = parseCLIArgs(args, {parallel: true}, {singleMode: true})
4142

@@ -56,6 +57,7 @@ module.exports = function npmRunAll(args, stdout, stderr) {
5657
packageConfig,
5758
silent,
5859
arguments: rest,
60+
race,
5961
}
6062
)
6163
}

src/lib/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ module.exports = function npmRunAll(
186186
printLabel = false,
187187
printName = false,
188188
arguments: args = [],
189+
race = false,
189190
} = {}
190191
) {
191192
try {
@@ -232,6 +233,7 @@ module.exports = function npmRunAll(
232233
},
233234
printName,
234235
packageInfo,
236+
race,
235237
})
236238
})
237239
}

src/lib/run-tasks-in-parallel.js

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,30 +38,41 @@ module.exports = function runTasksInParallel(tasks, options) {
3838
* @returns {void}
3939
*/
4040
function abortTasks() {
41-
if (!aborted && !options.continueOnError) {
42-
aborted = true
43-
taskPromises.forEach(t => t.abort())
44-
}
41+
aborted = true
42+
taskPromises.forEach(t => t.abort())
4543
}
4644

4745
// When one of tasks exited with non-zero, abort all tasks.
4846
// And wait for all tasks exit.
4947
let errorResult = null
5048
const parallelPromise = Promise.all(taskPromises.map((promise, index) =>
5149
promise.then(result => {
52-
// Save the result.
53-
if (!aborted) {
54-
results[index].code = result.code
50+
if (aborted) {
51+
return
5552
}
5653

54+
// Save the result.
55+
results[index].code = result.code
56+
5757
// Aborts all tasks if it's an error.
5858
if (errorResult == null && result.code) {
5959
errorResult = errorResult || result
60+
if (!options.continueOnError) {
61+
abortTasks()
62+
}
63+
}
64+
65+
// Aborts all tasks if options.race is true.
66+
if (options.race && !result.code) {
6067
abortTasks()
6168
}
6269
})
6370
))
64-
parallelPromise.catch(abortTasks)
71+
parallelPromise.catch(() => {
72+
if (!aborted && !options.continueOnError) {
73+
abortTasks()
74+
}
75+
})
6576

6677
// Make fail if there are tasks that exited non-zero.
6778
return parallelPromise.then(() => {

test-workspace/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"test-task:append:a:c": "node tasks/append.js ac",
1919
"test-task:append:a:d": "node tasks/append.js ad",
2020
"test-task:append:b": "node tasks/append.js b",
21+
"test-task:append1": "node tasks/append1.js",
2122
"test-task:append2": "node tasks/append2.js",
2223
"test-task:error": "node tasks/error.js",
2324
"test-task:stdout": "node tasks/stdout.js > test.txt",

test-workspace/tasks/append1.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
"use strict"
2+
3+
var appendResult = require("./lib/util").appendResult
4+
5+
appendResult(process.argv[2])

test/fail.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ describe("[fail] it should fail", () => {
4949
it("npm-run-all command", () => shouldFail(runAll(["--invalid"])))
5050
it("run-s command", () => shouldFail(runSeq(["--parallel"])))
5151
it("run-p command", () => shouldFail(runPar(["--sequential"])))
52+
53+
it("npm-run-all command with --race without --parallel", () => shouldFail(runAll(["--race"])))
54+
it("npm-run-all command with --r without --parallel", () => shouldFail(runAll(["--r"])))
55+
it("run-s command with --race", () => shouldFail(runSeq(["--race"])))
56+
it("run-s command with --r", () => shouldFail(runSeq(["--r"])))
5257
})
5358

5459
describe("if invalid `options.taskList` is given.", () => {

test/parallel.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,4 +259,41 @@ describe("[parallel]", () => {
259259
)
260260
)
261261
})
262+
263+
describe("should abort other tasks when a task finished, when --race option was specified:", () => {
264+
it("Node API", () =>
265+
nodeApi(["test-task:append1 a", "test-task:append2 b"], {parallel: true, race: true})
266+
.then(() => {
267+
assert(result() === "a" || result() === "ab" || result() === "ba")
268+
})
269+
)
270+
271+
it("npm-run-all command (--race)", () =>
272+
runAll(["--race", "--parallel", "test-task:append1 a", "test-task:append2 b"])
273+
.then(() => {
274+
assert(result() === "a" || result() === "ab" || result() === "ba")
275+
})
276+
)
277+
278+
it("npm-run-all command (-r)", () =>
279+
runAll(["-rp", "test-task:append1 a", "test-task:append2 b"])
280+
.then(() => {
281+
assert(result() === "a" || result() === "ab" || result() === "ba")
282+
})
283+
)
284+
285+
it("run-p command (--race)", () =>
286+
runPar(["--race", "test-task:append1 a", "test-task:append2 b"])
287+
.then(() => {
288+
assert(result() === "a" || result() === "ab" || result() === "ba")
289+
})
290+
)
291+
292+
it("run-p command (-r)", () =>
293+
runPar(["-r", "test-task:append1 a", "test-task:append2 b"])
294+
.then(() => {
295+
assert(result() === "a" || result() === "ab" || result() === "ba")
296+
})
297+
)
298+
})
262299
})

0 commit comments

Comments
 (0)