-
Notifications
You must be signed in to change notification settings - Fork 22
/
install.ts
79 lines (66 loc) · 3 KB
/
install.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
import {Command, flags} from '@oclif/command'
import chalk from 'chalk'
import cli from 'cli-ux'
import Plugins from '../../plugins'
export default class PluginsInstall extends Command {
static description = `installs a plugin into the CLI
Can be installed from npm or a git url.
Installation of a user-installed plugin will override a core plugin.
e.g. If you have a core plugin that has a 'hello' command, installing a user-installed plugin with a 'hello' command will override the core plugin implementation. This is useful if a user needs to update core plugin functionality in the CLI without the need to patch and update the whole CLI.
`
static usage = 'plugins:install PLUGIN...'
static examples = [
'$ <%= config.bin %> plugins:install <%- config.pjson.oclif.examplePlugin || "myplugin" %> ',
'$ <%= config.bin %> plugins:install https://github.com/someuser/someplugin',
'$ <%= config.bin %> plugins:install someuser/someplugin',
]
static strict = false
static args = [{name: 'plugin', description: 'plugin to install', required: true}]
static flags = {
help: flags.help({char: 'h'}),
verbose: flags.boolean({char: 'v'}),
force: flags.boolean({char: 'f', description: 'yarn install with force flag'}),
}
static aliases = ['plugins:add']
plugins = new Plugins(this.config)
// In this case we want these operations to happen
// sequentially so the `no-await-in-loop` rule is ugnored
/* eslint-disable no-await-in-loop */
async run() {
const {flags, argv} = this.parse(PluginsInstall)
if (flags.verbose) this.plugins.verbose = true
const aliases = this.config.pjson.oclif.aliases || {}
for (let name of argv) {
if (aliases[name] === null) this.error(`${name} is blacklisted`)
name = aliases[name] || name
const p = await this.parsePlugin(name)
let plugin
await this.config.runHook('plugins:preinstall', {
plugin: p,
})
if (p.type === 'npm') {
cli.action.start(`Installing plugin ${chalk.cyan(this.plugins.friendlyName(p.name))}`)
plugin = await this.plugins.install(p.name, {tag: p.tag, force: flags.force})
} else {
cli.action.start(`Installing plugin ${chalk.cyan(p.url)}`)
plugin = await this.plugins.install(p.url, {force: flags.force})
}
cli.action.stop(`installed v${plugin.version}`)
}
}
/* eslint-enable no-await-in-loop */
async parsePlugin(input: string): Promise<{name: string; tag: string; type: 'npm'} | {url: string; type: 'repo'}> {
if (input.includes('@') && input.includes('/')) {
input = input.slice(1)
const [name, tag = 'latest'] = input.split('@')
return {name: '@' + name, tag, type: 'npm'}
}
if (input.includes('/')) {
if (input.includes(':')) return {url: input, type: 'repo'}
return {url: `https://github.com/${input}`, type: 'repo'}
}
const [splitName, tag = 'latest'] = input.split('@')
const name = await this.plugins.maybeUnfriendlyName(splitName)
return {name, tag, type: 'npm'}
}
}