Skip to content

Commit 45632b3

Browse files
authored
fix(W-16338640): Backward compatibility for CLI commands (#137)
1 parent 351dc1f commit 45632b3

File tree

4 files changed

+334
-167
lines changed

4 files changed

+334
-167
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@
66
lib/
77
node_modules/
88
package-lock.json
9+
.idea/

package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
"@types/sinon": "^10.0.13",
2929
"@types/supports-color": "^5.3.0",
3030
"@types/uuid": "^8.3.0",
31+
"@types/yargs-parser": "^21.0.3",
32+
"@types/yargs-unparser": "^2.0.3",
3133
"@typescript-eslint/eslint-plugin": "6.21.0",
3234
"@typescript-eslint/parser": "6.21.0",
3335
"chai": "^4.4.1",
@@ -48,6 +50,10 @@
4850
"tslint": "^6.1.3",
4951
"typescript": "^4.8.4"
5052
},
53+
"peerDependencies": {
54+
"yargs-parser": ">=18.x",
55+
"yargs-unparser": "^2.0.0"
56+
},
5157
"engines": {
5258
"node": ">= 16.20.0"
5359
},

src/command.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import {Command as Base} from '@oclif/core'
2+
import {ArgOutput, FlagOutput, Input, ParserOutput} from '@oclif/core/lib/interfaces/parser'
3+
import {NonExistentFlagsError} from '@oclif/core/lib/parser/errors'
24
import {deprecate} from 'util'
5+
import parser from 'yargs-parser'
6+
import unparser from 'yargs-unparser'
37

48
const pjson = require('../package.json')
59

@@ -14,6 +18,7 @@ export abstract class Command extends Base {
1418
base = `${pjson.name}@${pjson.version}`
1519
_heroku!: APIClient
1620
_legacyHerokuClient: any
21+
allowArbitraryFlags: boolean = false;
1722

1823
get heroku(): APIClient {
1924
if (this._heroku) return this._heroku
@@ -43,4 +48,34 @@ export abstract class Command extends Base {
4348
get out(): any {
4449
return deprecatedCLI()
4550
}
51+
52+
protected async parse<F extends FlagOutput, B extends FlagOutput, A extends ArgOutput>(options?: Input<F, B, A>, argv?: string[]): Promise<ParserOutput<F, B, A>> {
53+
if (this.allowArbitraryFlags) {
54+
try {
55+
return await super.parse(options, argv)
56+
} catch (error) {
57+
const {flags: nonExistentFlags} = error as NonExistentFlagsError
58+
const parsed = parser(this.argv)
59+
const nonExistentFlagsWithValues = {...parsed}
60+
61+
for (const flag of nonExistentFlags) {
62+
const key = flag.replace('--', '')
63+
delete parsed[key]
64+
}
65+
66+
for (const key in parsed) {
67+
if (Reflect.has(parsed, key)) {
68+
delete nonExistentFlagsWithValues[key]
69+
}
70+
}
71+
72+
this.argv = unparser(parsed as unparser.Arguments)
73+
const result = await super.parse(options, argv)
74+
result.nonExistentFlags = unparser(nonExistentFlagsWithValues as unparser.Arguments)
75+
return result
76+
}
77+
}
78+
79+
return super.parse(options, argv)
80+
}
4681
}

0 commit comments

Comments
 (0)