Skip to content

Commit 441f059

Browse files
authored
fix(perf): address slow parse when using unknown-options-as-args (#394)
1 parent fb22816 commit 441f059

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

lib/yargs-parser.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ export class YargsParser {
210210

211211
for (let i = 0; i < args.length; i++) {
212212
const arg = args[i]
213+
const truncatedArg = arg.replace(/^-{3,}/, '---')
213214
let broken: boolean
214215
let key: string | undefined
215216
let letters: string[]
@@ -221,7 +222,7 @@ export class YargsParser {
221222
if (arg !== '--' && isUnknownOptionAsArg(arg)) {
222223
pushPositional(arg)
223224
// ---, ---=, ----, etc,
224-
} else if (arg.match(/---+(=|$)/)) {
225+
} else if (truncatedArg.match(/---+(=|$)/)) {
225226
// options without key name are invalid.
226227
pushPositional(arg)
227228
continue
@@ -969,6 +970,7 @@ export class YargsParser {
969970
}
970971

971972
function isUnknownOption (arg: string): boolean {
973+
arg = arg.replace(/^-{3,}/, '--')
972974
// ignore negative numbers
973975
if (arg.match(negative)) { return false }
974976
// if this is a short option group and all of them are configured, it isn't unknown

test/yargs-parser.cjs

+33
Original file line numberDiff line numberDiff line change
@@ -3963,4 +3963,37 @@ describe('yargs-parser', function () {
39633963
}).to.throw(/yargs parser supports a minimum Node.js version of 55/)
39643964
delete process.env.YARGS_MIN_NODE_VERSION
39653965
})
3966+
3967+
// Refs: https://github.com/yargs/yargs-parser/issues/386
3968+
describe('perf', () => {
3969+
const i = 100000
3970+
describe('unknown-options-as-args', () => {
3971+
it('parses long chain of "-" with reasonable performance', function () {
3972+
this.timeout(500)
3973+
const s = (new Array(i).fill('-').join('')) + 'a'
3974+
const parsed = parser([s], { configuration: { 'unknown-options-as-args': true } })
3975+
parsed._[0].should.equal(s)
3976+
})
3977+
it('parses long chain of "-a-a" with reasonable performance', function () {
3978+
this.timeout(500)
3979+
const s = '-' + (new Array(i).fill('-a').join('')) + '=35'
3980+
const parsed = parser([s], { configuration: { 'unknown-options-as-args': true } })
3981+
parsed._[0].should.equal(s)
3982+
})
3983+
})
3984+
it('parses long chain of "-" with reasonable performance', function () {
3985+
this.timeout(500)
3986+
const s = (new Array(i).fill('-').join('')) + 'a'
3987+
const arg = (new Array(i - 2).fill('-').join('')) + 'a'
3988+
const parsed = parser([s])
3989+
parsed[arg].should.equal(true)
3990+
})
3991+
it('parses long chain of "-a-a" with reasonable performance', function () {
3992+
this.timeout(500)
3993+
const s = '-' + (new Array(i).fill('-a').join('')) + '=35'
3994+
const arg = 'a' + (new Array(i - 1).fill('A').join(''))
3995+
const parsed = parser([s])
3996+
parsed[arg].should.equal(35)
3997+
})
3998+
})
39663999
})

0 commit comments

Comments
 (0)