-
Notifications
You must be signed in to change notification settings - Fork 73
/
Copy pathmain.ts
96 lines (78 loc) · 3.21 KB
/
main.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import {URL, fileURLToPath} from 'node:url'
import {ux} from './cli-ux'
import {Config} from './config'
import {getHelpFlagAdditions, loadHelpClass, normalizeArgv} from './help'
import * as Interfaces from './interfaces'
import {OCLIF_MARKER_OWNER, Performance} from './performance'
const debug = require('debug')('oclif:main')
export const helpAddition = (argv: string[], config: Interfaces.Config): boolean => {
if (argv.length === 0 && !config.pjson.oclif.default) return true
const mergedHelpFlags = getHelpFlagAdditions(config)
for (const arg of argv) {
if (mergedHelpFlags.includes(arg)) return true
if (arg === '--') return false
}
return false
}
export const versionAddition = (argv: string[], config?: Interfaces.Config): boolean => {
const additionalVersionFlags = config?.pjson.oclif.additionalVersionFlags ?? []
const mergedVersionFlags = [...new Set(['--version', ...additionalVersionFlags]).values()]
if (mergedVersionFlags.includes(argv[0])) return true
return false
}
export async function run(argv?: string[], options?: Interfaces.LoadOptions): Promise<unknown> {
const marker = Performance.mark(OCLIF_MARKER_OWNER, 'main.run')
const initMarker = Performance.mark(OCLIF_MARKER_OWNER, 'main.run#init')
const collectPerf = async () => {
marker?.stop()
if (!initMarker?.stopped) initMarker?.stop()
await Performance.collect()
Performance.debug()
}
debug(`process.execPath: ${process.execPath}`)
debug(`process.execArgv: ${process.execArgv}`)
debug('process.argv: %O', process.argv)
argv = argv ?? process.argv.slice(2)
// Handle the case when a file URL string or URL is passed in such as 'import.meta.url'; covert to file path.
if (options && ((typeof options === 'string' && options.startsWith('file://')) || options instanceof URL)) {
options = fileURLToPath(options)
}
const config = await Config.load(options ?? require.main?.filename ?? __dirname)
let [id, ...argvSlice] = normalizeArgv(config, argv)
// run init hook
await config.runHook('init', {argv: argvSlice, id})
// display version if applicable
if (versionAddition(argv, config)) {
ux.log(config.userAgent)
await collectPerf()
return
}
// display help version if applicable
if (helpAddition(argv, config)) {
const Help = await loadHelpClass(config)
const help = new Help(config, config.pjson.oclif.helpOptions ?? config.pjson.helpOptions)
await help.showHelp(argv)
await collectPerf()
return
}
// find & run command
const cmd = config.findCommand(id)
if (!cmd) {
const topic = config.flexibleTaxonomy ? null : config.findTopic(id)
if (topic) return config.runCommand('help', [id])
if (config.pjson.oclif.default) {
id = config.pjson.oclif.default
argvSlice = argv
}
}
initMarker?.stop()
// If the the default command is '.' (signifying that the CLI is a single command CLI) and '.' is provided
// as an argument, we need to add back the '.' to argv since it was stripped out earlier as part of the
// command id.
if (config.pjson.oclif.default === '.' && id === '.' && argv[0] === '.') argvSlice = ['.', ...argvSlice]
try {
return await config.runCommand(id, argvSlice, cmd)
} finally {
await collectPerf()
}
}