Skip to content

Commit

Permalink
feat: allow installing from github urls
Browse files Browse the repository at this point in the history
  • Loading branch information
jdx committed Jun 1, 2018
1 parent e8a94ff commit 4ae4f3d
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 63 deletions.
24 changes: 12 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,40 @@
"bugs": "https://github.com/oclif/plugin-plugins/issues",
"dependencies": {
"@heroku-cli/color": "^1.1.5",
"@oclif/command": "^1.4.30",
"@oclif/command": "^1.4.32",
"chalk": "^2.4.1",
"cli-ux": "^4.4.0",
"cli-ux": "^4.6.0",
"debug": "^3.1.0",
"fs-extra": "^6.0.1",
"http-call": "^5.1.3",
"http-call": "^5.1.4",
"load-json-file": "^5.0.0",
"npm-run-path": "^2.0.2",
"semver": "^5.5.0",
"tslib": "^1.9.1",
"tslib": "^1.9.2",
"yarn": "^1.7.0"
},
"devDependencies": {
"@oclif/config": "^1.6.19",
"@oclif/dev-cli": "^1.13.22",
"@oclif/config": "^1.6.27",
"@oclif/dev-cli": "^1.13.29",
"@oclif/errors": "^1.1.2",
"@oclif/plugin-help": "^1.2.11",
"@oclif/test": "^1.0.6",
"@oclif/plugin-help": "^2.0.4",
"@oclif/test": "^1.0.9",
"@oclif/tslint": "^1.1.2",
"@types/chai": "^4.1.3",
"@types/fs-extra": "^5.0.2",
"@types/load-json-file": "^2.0.7",
"@types/mocha": "^5.2.0",
"@types/node": "^10.1.2",
"@types/node": "^10.3.0",
"@types/semver": "^5.5.0",
"@types/supports-color": "^5.3.0",
"chai": "^4.1.2",
"concurrently": "^3.5.1",
"fancy-test": "^1.0.8",
"fancy-test": "^1.1.4",
"globby": "^8.0.1",
"mocha": "^5.2.0",
"ts-node": "^6.0.4",
"ts-node": "^6.0.5",
"tslint": "^5.10.0",
"typescript": "^2.8.3"
"typescript": "^2.9.1"
},
"engines": {
"node": ">=8.0.0"
Expand Down
22 changes: 15 additions & 7 deletions src/commands/plugins/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,29 @@ export default class PluginsInstall extends Command {
const {flags, argv} = this.parse(PluginsInstall)
if (flags.verbose) this.plugins.verbose = true
for (let plugin of argv) {
let {name, tag} = parsePlugin(plugin)
cli.action.start(`Installing plugin ${chalk.cyan(this.plugins.friendlyName(name))}`)
await this.plugins.install(name, tag)
let p = parsePlugin(plugin)
if (p.type === 'npm') {
cli.action.start(`Installing plugin ${chalk.cyan(this.plugins.friendlyName(p.name))}`)
await this.plugins.install(p.name, p.tag)
} else {
cli.action.start(`Installing plugin ${chalk.cyan(p.url)}`)
await this.plugins.install(p.url)
}
cli.action.stop()
}
}
}

function parsePlugin(input: string): {name: string, tag: string} {
if (input.includes('/')) {
function parsePlugin(input: string): {name: string, tag: string, type: 'npm'} | {url: string, type: 'repo'} {
if (input.includes('@') && input.includes('/')) {
input = input.slice(1)
let [name, tag = 'latest'] = input.split('@')
return {name: '@' + name, tag}
return {name: '@' + name, tag, type: 'npm'}
} else if (input.includes('/')) {
if (input.includes(':')) return {url: input, type: 'repo'}
else return {url: `https://github.com/${input}`, type: 'repo'}
} else {
let [name, tag = 'latest'] = input.split('@')
return {name, tag}
return {name, tag, type: 'npm'}
}
}
38 changes: 27 additions & 11 deletions src/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,34 @@ export default class Plugins {

async install(name: string, tag = 'latest') {
try {
const range = semver.validRange(tag)
const unfriendly = this.unfriendlyName(name)
if (unfriendly && await this.npmHasPackage(unfriendly)) {
name = unfriendly
}
const yarnOpts = {cwd: this.config.dataDir, verbose: this.verbose}
await this.createPJSON()
await this.yarn.exec(['add', `${name}@${tag}`], {cwd: this.config.dataDir, verbose: this.verbose})
const plugin = await Config.load({devPlugins: false, userPlugins: false, root: path.join(this.config.dataDir, 'node_modules', name), name})
if (!plugin.valid && !this.config.plugins.find(p => p.name === '@oclif/plugin-legacy')) {
throw new Error('plugin is invalid')
if (name.includes(':')) {
// url
const url = name
await this.yarn.exec(['add', url], yarnOpts)
name = Object.entries((await this.pjson()).dependencies || {}).find(([, u]: any) => u === url)![0]
const plugin = await Config.load({devPlugins: false, userPlugins: false, root: path.join(this.config.dataDir, 'node_modules', name), name})
await this.refresh(plugin.root)
if (!plugin.valid && !this.config.plugins.find(p => p.name === '@oclif/plugin-legacy')) {
throw new Error('plugin is invalid')
}
await this.add({name, url, type: 'user'})
} else {
// npm
const range = semver.validRange(tag)
const unfriendly = this.unfriendlyName(name)
if (unfriendly && await this.npmHasPackage(unfriendly)) {
name = unfriendly
}
await this.yarn.exec(['add', `${name}@${tag}`], yarnOpts)
const plugin = await Config.load({devPlugins: false, userPlugins: false, root: path.join(this.config.dataDir, 'node_modules', name), name})
if (!plugin.valid && !this.config.plugins.find(p => p.name === '@oclif/plugin-legacy')) {
throw new Error('plugin is invalid')
}
await this.refresh(plugin.root)
await this.add({name, tag: range || tag, type: 'user'})
}
await this.refresh(plugin.root)
await this.add({name, tag: range || tag, type: 'user'})
} catch (err) {
await this.uninstall(name).catch(err => this.debug(err))
throw err
Expand Down Expand Up @@ -115,6 +130,7 @@ export default class Plugins {
const plugins = (await this.list()).filter((p): p is Config.PJSON.PluginTypes.User => p.type === 'user')
if (plugins.length === 0) return
cli.action.start(`${this.config.name}: Updating plugins`)
await this.yarn.exec(['upgrade'], {cwd: this.config.dataDir, verbose: this.verbose})
await this.yarn.exec(['add', ...plugins.map(p => `${p.name}@${p.tag}`)], {cwd: this.config.dataDir, verbose: this.verbose})
for (let p of plugins) {
await this.refresh(path.join(this.config.dataDir, 'node_modules', p.name))
Expand Down
14 changes: 14 additions & 0 deletions test/commands/plugins/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@ describe('command', () => {
.command(['plugins'], {reset: true})
.do(output => expect(output.stdout).to.equal('no plugins installed\n'))
.it('installs and uninstalls @oclif/example-plugin-ts')

test
.command(['plugins:install', 'jdxcode/oclif-debug'], {reset: true})
.stdout()
.command(['plugins'], {reset: true})
.do(output => expect(output.stdout).to.contain('oclif-debug'))
.stdout()
.command(['debug'], {reset: true})
.do(output => expect(output.stdout).to.contain('debug'))
.command(['plugins:uninstall', 'oclif-debug'])
.stdout()
.command(['plugins'], {reset: true})
.do(output => expect(output.stdout).to.equal('no plugins installed\n'))
.it('installs and uninstalls jdxcode/oclif-debug')
// test
// .command(['plugins:install', 'heroku-debug@beta'], {reset: true})
// .stdout()
Expand Down
Loading

0 comments on commit 4ae4f3d

Please sign in to comment.