Skip to content

Commit

Permalink
BREAKING CHANGE: add new update features (#368)
Browse files Browse the repository at this point in the history
* feat: add --version to update command

* feat: add --interactive

* chore: add back necessary deps

* chore: move dep to devDependencies

* feat!: rename flags

BREAKING CHANGE: rename --from-local to --local

* chore: update examples

* feat!: remove --local flag

BREAKING CHANGE: remove --local flag

* refactor: Updater

* fix: handle non-existent version index

* chore: code review

* chore: update test

* fix: skip preupdate hook if using --hard

* fix: update root after hard update

* fix: works with sf

* fix: replace --hard with --force

* chore: update examples

* chore: bump to 3.0.0
  • Loading branch information
mdonnalley authored Feb 11, 2022
1 parent 0f30505 commit 091c176
Show file tree
Hide file tree
Showing 10 changed files with 514 additions and 367 deletions.
3 changes: 1 addition & 2 deletions bin/dev
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ process.env.NODE_ENV = 'development'
require('ts-node').register({project})

// In dev mode, always show stack traces
// Waiting for https://github.com/oclif/core/pull/147
// oclif.settings.debug = true;
oclif.settings.debug = true;

// Start the CLI
oclif.run().then(oclif.flush).catch(oclif.Errors.handle)
14 changes: 8 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
{
"name": "@oclif/plugin-update",
"version": "2.2.0",
"version": "3.0.0",
"author": "Salesforce",
"bugs": "https://github.com/oclif/plugin-update/issues",
"dependencies": {
"@oclif/color": "^1.0.0",
"@oclif/core": "^1.2.0",
"@types/semver": "^7.3.4",
"@oclif/core": "^1.3.0",
"cross-spawn": "^7.0.3",
"debug": "^4.3.1",
"filesize": "^6.1.0",
"fs-extra": "^9.0.1",
"http-call": "^5.3.0",
"lodash": "^4.17.21",
"inquirer": "^8.2.0",
"lodash.throttle": "^4.1.1",
"log-chopper": "^1.0.2",
"semver": "^7.3.5",
"tar-fs": "^2.1.1"
Expand All @@ -25,9 +25,11 @@
"@types/execa": "^0.9.0",
"@types/fs-extra": "^8.0.1",
"@types/glob": "^7.1.3",
"@types/lodash": "^4.14.168",
"@types/inquirer": "^8.2.0",
"@types/lodash.throttle": "^4.1.6",
"@types/mocha": "^9",
"@types/node": "^14.14.31",
"@types/semver": "^7.3.4",
"@types/supports-color": "^7.2.0",
"@types/write-json-file": "^3.2.1",
"chai": "^4.3.4",
Expand All @@ -37,7 +39,7 @@
"globby": "^11.0.2",
"mocha": "^9",
"nock": "^13.2.1",
"oclif": "^2.3.0",
"oclif": "^2.4.2",
"qqjs": "^0.3.11",
"sinon": "^12.0.1",
"ts-node": "^9.1.1",
Expand Down
89 changes: 75 additions & 14 deletions src/commands/update.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,91 @@
import {Command, Flags, Config, CliUx} from '@oclif/core'
import {Command, Flags, CliUx} from '@oclif/core'
import {prompt, Separator} from 'inquirer'
import * as path from 'path'
import UpdateCli from '../update'

async function getPinToVersion(): Promise<string> {
return CliUx.ux.prompt('Enter a version to update to')
}
import {sort} from 'semver'
import {Updater} from '../update'

export default class UpdateCommand extends Command {
static description = 'update the <%= config.bin %> CLI'

static args = [{name: 'channel', optional: true}]

static examples = [
{
description: 'Update to the stable channel:',
command: '<%= config.bin %> <%= command.id %> stable',
},
{
description: 'Update to a specific version:',
command: '<%= config.bin %> <%= command.id %> --version 1.0.0',
},
{
description: 'Interactively select version:',
command: '<%= config.bin %> <%= command.id %> --interactive',
},
{
description: 'See available versions:',
command: '<%= config.bin %> <%= command.id %> --available',
},
]

static flags = {
autoupdate: Flags.boolean({hidden: true}),
'from-local': Flags.boolean({description: 'interactively choose an already installed version'}),
available: Flags.boolean({
char: 'a',
description: 'Install a specific version.',
}),
version: Flags.string({
char: 'v',
description: 'Install a specific version.',
exclusive: ['interactive'],
}),
interactive: Flags.boolean({
char: 'i',
description: 'Interactively select version to install. This is ignored if a channel is provided.',
exclusive: ['version'],
}),
force: Flags.boolean({
description: 'Force a re-download of the requested version.',
}),
}

private channel!: string
async run(): Promise<void> {
const {args, flags} = await this.parse(UpdateCommand)
const updater = new Updater(this.config)
if (flags.available) {
const index = await updater.fetchVersionIndex()
const allVersions = sort(Object.keys(index)).reverse()
const localVersions = await updater.findLocalVersions()

const table = allVersions.map(version => {
const location = localVersions.find(l => path.basename(l).startsWith(version)) || index[version]
return {version, location}
})

private readonly clientRoot = this.config.scopedEnvVar('OCLIF_CLIENT_HOME') || path.join(this.config.dataDir, 'client')
CliUx.ux.table(table, {version: {}, location: {}})
return
}

private readonly clientBin = path.join(this.clientRoot, 'bin', this.config.windows ? `${this.config.bin}.cmd` : this.config.bin)
if (args.channel && flags.version) {
this.error('You cannot specifiy both a version and a channel.')
}

async run(): Promise<void> {
const {args, flags} = await this.parse(UpdateCommand)
const updateCli = new UpdateCli({channel: args.channel, autoUpdate: flags.autoupdate, fromLocal: flags['from-local'], config: this.config as Config, exit: this.exit, getPinToVersion: getPinToVersion})
return updateCli.runUpdate()
return updater.runUpdate({
channel: args.channel,
autoUpdate: flags.autoupdate,
force: flags.force,
version: flags.interactive ? await this.promptForVersion(updater) : flags.version,
})
}

private async promptForVersion(updater: Updater): Promise<string> {
const choices = sort(Object.keys(await updater.fetchVersionIndex())).reverse()
const {version} = await prompt<{version: string}>({
name: 'version',
message: 'Select a version to update to',
type: 'list',
choices: [...choices, new Separator()],
})
return version
}
}
2 changes: 1 addition & 1 deletion src/hooks/init.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {CliUx, Interfaces} from '@oclif/core'
import * as spawn from 'cross-spawn'
import spawn from 'cross-spawn'
import * as fs from 'fs-extra'
import * as path from 'path'

Expand Down
2 changes: 1 addition & 1 deletion src/tar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const ignore = (_: any, header: any) => {
}
}

export async function extract(stream: NodeJS.ReadableStream, basename: string, output: string, sha?: string) {
export async function extract(stream: NodeJS.ReadableStream, basename: string, output: string, sha?: string): Promise<void> {
const getTmp = () => `${output}.partial.${Math.random().toString().split('.')[1].slice(0, 5)}`
let tmp = getTmp()
if (fs.pathExistsSync(tmp)) tmp = getTmp()
Expand Down
Loading

0 comments on commit 091c176

Please sign in to comment.