/
runner.ts
109 lines (93 loc) 路 3.04 KB
/
runner.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
/* eslint-disable no-console */
import { resolve } from 'node:path'
import prompts from '@posva/prompts'
import { execaCommand } from 'execa'
import c from 'kleur'
import { version } from '../package.json'
import type { Agent } from './agents'
import { agents } from './agents'
import { getDefaultAgent, getGlobalAgent } from './config'
import type { DetectOptions } from './detect'
import { detect } from './detect'
import { getVoltaPrefix, remove } from './utils'
import { UnsupportedCommand } from './parse'
const DEBUG_SIGN = '?'
export interface RunnerContext {
programmatic?: boolean
hasLock?: boolean
cwd?: string
}
export type Runner = (agent: Agent, args: string[], ctx?: RunnerContext) => Promise<string | undefined> | string | undefined
export async function runCli(fn: Runner, options: DetectOptions = {}) {
const args = process.argv.slice(2).filter(Boolean)
try {
await run(fn, args, options)
}
catch (error) {
if (error instanceof UnsupportedCommand && !options.programmatic)
console.log(c.red(`\u2717 ${error.message}`))
if (!options.programmatic)
process.exit(1)
throw error
}
}
export async function run(fn: Runner, args: string[], options: DetectOptions = {}) {
const debug = args.includes(DEBUG_SIGN)
if (debug)
remove(args, DEBUG_SIGN)
let cwd = options.cwd ?? process.cwd()
let command
if (args.length === 1 && (args[0] === '--version' || args[0] === '-v')) {
console.log(`@antfu/ni v${version}`)
return
}
if (args.length === 1 && ['-h', '--help'].includes(args[0])) {
const dash = c.dim('-')
console.log(c.green(c.bold('@antfu/ni')) + c.dim(` use the right package manager v${version}\n`))
console.log(`ni ${dash} install`)
console.log(`nr ${dash} run`)
console.log(`nlx ${dash} execute`)
console.log(`nu ${dash} upgrade`)
console.log(`nun ${dash} uninstall`)
console.log(`nci ${dash} clean install`)
console.log(`na ${dash} agent alias`)
console.log(c.yellow('\ncheck https://github.com/antfu/ni for more documentation.'))
return
}
if (args[0] === '-C') {
cwd = resolve(cwd, args[1])
args.splice(0, 2)
}
const isGlobal = args.includes('-g')
if (isGlobal) {
command = await fn(await getGlobalAgent(), args)
}
else {
let agent = await detect({ ...options, cwd }) || await getDefaultAgent(options.programmatic)
if (agent === 'prompt') {
agent = (await prompts({
name: 'agent',
type: 'select',
message: 'Choose the agent',
choices: agents.filter(i => !i.includes('@')).map(value => ({ title: value, value })),
})).agent
if (!agent)
return
}
command = await fn(agent as Agent, args, {
programmatic: options.programmatic,
hasLock: Boolean(agent),
cwd,
})
}
if (!command)
return
const voltaPrefix = getVoltaPrefix()
if (voltaPrefix)
command = voltaPrefix.concat(' ').concat(command)
if (debug) {
console.log(command)
return
}
await execaCommand(command, { stdio: 'inherit', encoding: 'utf-8', cwd })
}