Skip to content

Commit d37318e

Browse files
authored
fix: arg parsing on windows, close #239 (#244)
1 parent a131819 commit d37318e

File tree

4 files changed

+117
-1
lines changed

4 files changed

+117
-1
lines changed

__snapshots__/utils-spec.js

+42
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,45 @@
1+
exports['utils crossArguments concates arguments if wrapped by " 1'] = [
2+
"start",
3+
"8080",
4+
"test argument --option"
5+
]
6+
7+
exports['utils crossArguments concates arguments if wrapped by \' 1'] = [
8+
"start",
9+
"8080",
10+
"test argument --option"
11+
]
12+
13+
exports['utils crossArguments concates arguments if wrapped by ` 1'] = [
14+
"start",
15+
"8080",
16+
"test argument --option"
17+
]
18+
19+
exports['utils crossArguments ignores end char (") if not at the end of an argument 1'] = [
20+
"start",
21+
"8080",
22+
"test argu\"ment --option"
23+
]
24+
25+
exports['utils crossArguments ignores end char (\') if not at the end of an argument 1'] = [
26+
"start",
27+
"8080",
28+
"test argu'ment --option"
29+
]
30+
31+
exports['utils crossArguments ignores end char (`) if not at the end of an argument 1'] = [
32+
"start",
33+
"8080",
34+
"test argu`ment --option"
35+
]
36+
37+
exports['utils crossArguments ignores end chars that are != the startChar of an argument 1'] = [
38+
"start",
39+
"8080",
40+
"test argument' --option"
41+
]
42+
143
exports['utils getArguments allows 5 arguments 1'] = {
244
"args": [
345
"start",

src/bin/start.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
const debug = require('debug')('start-server-and-test')
44

5-
const args = process.argv.slice(2)
65
const startAndTest = require('..').startAndTest
76
const utils = require('../utils')
7+
const args = utils.crossArguments(process.argv.slice(2))
88

99
debug('parsing CLI arguments: %o', args)
1010
const parsed = utils.getArguments(args)

src/utils-spec.js

+33
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,39 @@ describe('utils', () => {
2626
})
2727
})
2828

29+
context('crossArguments', () => {
30+
const crossArguments = utils.crossArguments
31+
;['"', "'", '`'].forEach(char => {
32+
it(`concates arguments if wrapped by ${char}`, () => {
33+
snapshot(
34+
crossArguments([
35+
'start',
36+
'8080',
37+
`${char}test`,
38+
'argument',
39+
`--option${char}`
40+
])
41+
)
42+
})
43+
it(`ignores end char (${char}) if not at the end of an argument`, () => {
44+
snapshot(
45+
crossArguments([
46+
'start',
47+
'8080',
48+
`${char}test`,
49+
`argu${char}ment`,
50+
`--option${char}`
51+
])
52+
)
53+
})
54+
})
55+
it(`ignores end chars that are != the startChar of an argument`, () => {
56+
snapshot(
57+
crossArguments(['start', '8080', `"test`, `argument'`, `--option"`])
58+
)
59+
})
60+
})
61+
2962
context('getArguments', () => {
3063
const getArguments = utils.getArguments
3164

src/utils.js

+41
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,46 @@ const is = require('check-more-types')
33
const { join } = require('path')
44
const { existsSync } = require('fs')
55

6+
/**
7+
* Returns new array of command line arguments
8+
* where leading and trailing " and ' are indicating
9+
* the beginning and end of an argument.
10+
*/
11+
const crossArguments = cliArgs => {
12+
let concatModeChar = false
13+
const indicationChars = ["'", '"', '`']
14+
const combinedArgs = []
15+
for (let i = 0; i < cliArgs.length; i++) {
16+
let arg = cliArgs[i]
17+
if (
18+
!concatModeChar &&
19+
indicationChars.some(char => cliArgs[i].startsWith(char))
20+
) {
21+
arg = arg.slice(1)
22+
}
23+
if (concatModeChar && cliArgs[i].endsWith(concatModeChar)) {
24+
arg = arg.slice(0, -1)
25+
}
26+
27+
if (concatModeChar && combinedArgs.length) {
28+
combinedArgs[combinedArgs.length - 1] += ' ' + arg
29+
} else {
30+
combinedArgs.push(arg)
31+
}
32+
33+
if (
34+
!concatModeChar &&
35+
indicationChars.some(char => cliArgs[i].startsWith(char))
36+
) {
37+
concatModeChar = cliArgs[i][0]
38+
}
39+
if (concatModeChar && cliArgs[i].endsWith(concatModeChar)) {
40+
concatModeChar = false
41+
}
42+
}
43+
return combinedArgs
44+
}
45+
646
/**
747
* Returns parsed command line arguments.
848
* If start command is NPM script name defined in the package.json
@@ -166,6 +206,7 @@ function printArguments ({ services, test }) {
166206
// placing functions into a common object
167207
// makes them methods for easy stubbing
168208
const UTILS = {
209+
crossArguments,
169210
getArguments,
170211
isPackageScriptName,
171212
isUrlOrPort,

0 commit comments

Comments
 (0)