-
Notifications
You must be signed in to change notification settings - Fork 67
/
util.ts
129 lines (100 loc) · 4.11 KB
/
util.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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import * as ejs from 'ejs'
import {Config as IConfig, HelpOptions} from '../interfaces'
import {Help, HelpBase} from '.'
import ModuleLoader from '../module-loader'
import {collectUsableIds} from '../config/util'
import {Deprecation} from '../interfaces/parser'
interface HelpBaseDerived {
new(config: IConfig, opts?: Partial<HelpOptions>): HelpBase;
}
function extractClass(exported: any): HelpBaseDerived {
return exported && exported.default ? exported.default : exported
}
export async function loadHelpClass(config: IConfig): Promise<HelpBaseDerived> {
const pjson = config.pjson
const configuredClass = pjson && pjson.oclif && pjson.oclif.helpClass
if (configuredClass) {
try {
const exported = await ModuleLoader.load(config, configuredClass) as HelpBaseDerived
return extractClass(exported) as HelpBaseDerived
} catch (error: any) {
throw new Error(`Unable to load configured help class "${configuredClass}", failed with message:\n${error.message}`)
}
}
return Help
}
export function template(context: any): (t: string) => string {
function render(t: string): string {
return ejs.render(t, context)
}
return render
}
function collateSpacedCmdIDFromArgs(argv: string[], config: IConfig): string[] {
if (argv.length === 1) return argv
const findId = (argv: string[]): string | undefined => {
const ids = collectUsableIds(config.commandIDs)
const final: string[] = []
const idPresent = (id: string) => ids.includes(id)
const isFlag = (s: string) => s.startsWith('-')
const isArgWithValue = (s: string) => s.includes('=')
const finalizeId = (s?: string) => s ? [...final, s].join(':') : final.join(':')
const hasArgs = () => {
const id = finalizeId()
if (!id) return false
const cmd = config.findCommand(id)
return Boolean(cmd && (cmd.strict === false || cmd.args?.length > 0))
}
for (const arg of argv) {
if (idPresent(finalizeId(arg))) final.push(arg)
// If the parent topic has a command that expects positional arguments, then we cannot
// assume that any subsequent string could be part of the command name
else if (isArgWithValue(arg) || isFlag(arg) || hasArgs()) break
else final.push(arg)
}
return finalizeId()
}
const id = findId(argv)
if (id) {
const argvSlice = argv.slice(id.split(':').length)
return [id, ...argvSlice]
}
return argv // ID is argv[0]
}
export function toStandardizedId(commandID: string, config: IConfig): string {
return commandID.replace(new RegExp(config.topicSeparator, 'g'), ':')
}
export function toConfiguredId(commandID: string, config: IConfig): string {
const defaultTopicSeparator = ':'
return commandID.replace(new RegExp(defaultTopicSeparator, 'g'), config.topicSeparator || defaultTopicSeparator)
}
export function standardizeIDFromArgv(argv: string[], config: IConfig): string[] {
if (argv.length === 0) return argv
if (config.topicSeparator === ' ') argv = collateSpacedCmdIDFromArgs(argv, config)
else if (config.topicSeparator !== ':') argv[0] = toStandardizedId(argv[0], config)
return argv
}
export function getHelpFlagAdditions(config: IConfig): string[] {
const helpFlags = ['--help']
const additionalHelpFlags = config.pjson.oclif.additionalHelpFlags ?? []
return [...new Set([...helpFlags, ...additionalHelpFlags]).values()]
}
export function formatFlagDeprecationWarning(flag: string, opts: true | Deprecation): string {
let message = `The "${flag}" flag has been deprecated`
if (opts === true) return `${message}.`
if (opts.message) return opts.message
if (opts.version) {
message += ` and will be removed in version ${opts.version}`
}
message += opts.to ? `. Use "${opts.to}" instead.` : '.'
return message
}
export function formatCommandDeprecationWarning(command: string, opts?: Deprecation): string {
let message = `The "${command}" command has been deprecated`
if (!opts) return `${message}.`
if (opts.message) return opts.message
if (opts.version) {
message += ` and will be removed in version ${opts.version}`
}
message += opts.to ? `. Use "${opts.to}" instead.` : '.'
return message
}