Skip to content

Commit 2fb71b2

Browse files
authored
fix: better handling of quoted strings (#153)
BREAKING CHANGE: quotes and beginning and endings of strings are not removed during parsing.
1 parent ee122f8 commit 2fb71b2

File tree

5 files changed

+49
-15
lines changed

5 files changed

+49
-15
lines changed

example.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
var parser = require('./')
2-
var parse = parser(['-cats', 'meow'])
2+
var parse = parser('--foo "-bar"')
33
console.log(parse)

index.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ function parse (args, opts) {
99
// allow a string argument to be passed in rather
1010
// than an argv array.
1111
args = tokenizeArgString(args)
12+
1213
// aliases might have transitive relationships, normalize this.
1314
var aliases = combineAliases(opts.alias || {})
1415
var configuration = assign({
@@ -450,6 +451,14 @@ function parse (args, opts) {
450451
}
451452

452453
function processValue (key, val) {
454+
// strings may be quoted, clean this up as we assign values.
455+
if (typeof val === 'string' &&
456+
(val[0] === "'" || val[0] === '"') &&
457+
val[val.length - 1] === val[0]
458+
) {
459+
val = val.substring(1, val.length - 1)
460+
}
461+
453462
// handle parsing boolean arguments --foo=true --bar false.
454463
if (checkAllAliases(key, flags.bools) || checkAllAliases(key, flags.counts)) {
455464
if (typeof val === 'string') val = val === 'true'

lib/tokenize-arg-string.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,8 @@ module.exports = function (argString) {
2727
if (c === opening) {
2828
if (!args[i]) args[i] = ''
2929
opening = null
30-
continue
3130
} else if ((c === "'" || c === '"') && !opening) {
3231
opening = c
33-
continue
3432
}
3533

3634
if (!args[i]) args[i] = ''

test/tokenize-arg-string.js

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,42 +15,42 @@ describe('TokenizeArgString', function () {
1515
it('handles quoted string with no spaces', function () {
1616
var args = tokenizeArgString("--foo 'hello'")
1717
args[0].should.equal('--foo')
18-
args[1].should.equal('hello')
18+
args[1].should.equal("'hello'")
1919
})
2020

2121
it('handles single quoted string with spaces', function () {
2222
var args = tokenizeArgString("--foo 'hello world' --bar='foo bar'")
2323
args[0].should.equal('--foo')
24-
args[1].should.equal('hello world')
25-
args[2].should.equal('--bar=foo bar')
24+
args[1].should.equal("'hello world'")
25+
args[2].should.equal("--bar='foo bar'")
2626
})
2727

2828
it('handles double quoted string with spaces', function () {
2929
var args = tokenizeArgString('--foo "hello world" --bar="foo bar"')
3030
args[0].should.equal('--foo')
31-
args[1].should.equal('hello world')
32-
args[2].should.equal('--bar=foo bar')
31+
args[1].should.equal('"hello world"')
32+
args[2].should.equal('--bar="foo bar"')
3333
})
3434

3535
it('handles single quoted empty string', function () {
3636
var args = tokenizeArgString('--foo \'\' --bar=\'\'')
3737
args[0].should.equal('--foo')
38-
args[1].should.equal('')
39-
args[2].should.equal('--bar=')
38+
args[1].should.equal("''")
39+
args[2].should.equal("--bar=''")
4040
})
4141

4242
it('handles double quoted empty string', function () {
4343
var args = tokenizeArgString('--foo "" --bar=""')
4444
args[0].should.equal('--foo')
45-
args[1].should.equal('')
46-
args[2].should.equal('--bar=')
45+
args[1].should.equal('""')
46+
args[2].should.equal('--bar=""')
4747
})
4848

4949
it('handles quoted string with embeded quotes', function () {
5050
var args = tokenizeArgString('--foo "hello \'world\'" --bar=\'foo "bar"\'')
5151
args[0].should.equal('--foo')
52-
args[1].should.equal('hello \'world\'')
53-
args[2].should.equal('--bar=foo "bar"')
52+
args[1].should.equal('"hello \'world\'"')
53+
args[2].should.equal('--bar=\'foo "bar"\'')
5454
})
5555

5656
// https://github.com/yargs/yargs-parser/pull/100
@@ -59,6 +59,6 @@ describe('TokenizeArgString', function () {
5959
var args = tokenizeArgString(' foo bar "foo bar" ')
6060
args[0].should.equal('foo')
6161
expect(args[1]).equal('bar')
62-
expect(args[2]).equal('foo bar')
62+
expect(args[2]).equal('"foo bar"')
6363
})
6464
})

test/yargs-parser.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2796,4 +2796,31 @@ describe('yargs-parser', function () {
27962796
argv.foo[3].bla.should.equal('banana')
27972797
})
27982798
})
2799+
2800+
// see: https://github.com/yargs/yargs-parser/issues/145
2801+
describe('strings with quotes and dashes', () => {
2802+
it('handles double quoted strings', function () {
2803+
const args = parser('--foo "hello world" --bar="goodnight\'moon"')
2804+
args.foo.should.equal('hello world')
2805+
args.bar.should.equal('goodnight\'moon')
2806+
const args2 = parser(['--foo', '"hello world"', '--bar="goodnight\'moon"'])
2807+
args2.foo.should.equal('hello world')
2808+
args2.bar.should.equal('goodnight\'moon')
2809+
})
2810+
2811+
it('handles single quoted strings', function () {
2812+
const args = parser("--foo 'hello world' --bar='goodnight\"moon'")
2813+
args.foo.should.equal('hello world')
2814+
args.bar.should.equal('goodnight"moon')
2815+
const args2 = parser(['--foo', "'hello world'", "--bar='goodnight\"moon'"])
2816+
args2.foo.should.equal('hello world')
2817+
args2.bar.should.equal('goodnight"moon')
2818+
})
2819+
2820+
it('handles strings with dashes', function () {
2821+
const args = parser('--foo "-hello world" --bar="--goodnight moon"')
2822+
args.foo.should.equal('-hello world')
2823+
args.bar.should.equal('--goodnight moon')
2824+
})
2825+
})
27992826
})

0 commit comments

Comments
 (0)