Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: use npm for plugin operations #776

Merged
merged 53 commits into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
ba6a18c
feat: add npm and pnpm options
mdonnalley Jan 18, 2024
ea2163f
Merge branch 'main' into mdonnalley/revamp
mdonnalley Jan 18, 2024
94f0668
feat!: use npm for installs
mdonnalley Jan 23, 2024
1e80a62
chore: bump to v5 prerelease
mdonnalley Jan 23, 2024
3953b9c
Merge branch 'main' into mdonnalley/revamp
mdonnalley Jan 23, 2024
737b967
fix: remove yarn.lock
mdonnalley Jan 24, 2024
d87fcbf
test: skip sf integration tests
mdonnalley Jan 24, 2024
6c3cb6f
fix: force rm yarn.lock
mdonnalley Jan 25, 2024
6ebb1fc
fix: use fork for npm show
mdonnalley Jan 25, 2024
b155136
feat: remove all yarn functionality
mdonnalley Jan 25, 2024
d7c09cb
chore: clean up
mdonnalley Jan 25, 2024
b1ea1f1
test: debug failing windows tests
mdonnalley Jan 25, 2024
3cc66c8
feat: add --npm-log-level flag
mdonnalley Jan 25, 2024
fd4f30f
chore: clean up
mdonnalley Jan 25, 2024
85b2da0
test: debug failing windows tests
mdonnalley Jan 25, 2024
002675b
test: compilation errors
mdonnalley Jan 25, 2024
b2a4d14
fix: use CLIError
mdonnalley Jan 25, 2024
9b736f6
test: debug failing windows tests
mdonnalley Jan 25, 2024
503a9d3
test: debug failing windows tests
mdonnalley Jan 25, 2024
6d23bb9
test: debug failing windows tests
mdonnalley Jan 25, 2024
0e6c372
chore: remove unused dep
mdonnalley Jan 25, 2024
daac083
chore: clean up
mdonnalley Jan 25, 2024
7e3f0a8
fix: add suggestion for failed install
mdonnalley Jan 25, 2024
dd8f69c
fix: npm-run-path is actually needed
mdonnalley Jan 25, 2024
b4da5fd
test: debug failing windows tests
mdonnalley Jan 25, 2024
409db00
test: debug failing windows tests
mdonnalley Jan 25, 2024
9331d65
test: extend timeout
mdonnalley Jan 25, 2024
be382e7
test: renable sf integration tests
mdonnalley Jan 26, 2024
d1c9d74
feat: simplify logging options
mdonnalley Jan 26, 2024
b4ef3d3
fix: clean up yarn.lock and node_modules if they exist
mdonnalley Jan 30, 2024
d044775
Merge branch 'main' into mdonnalley/revamp
mdonnalley Jan 31, 2024
57dda03
perf: spawn new process for removing node_modules
mdonnalley Jan 31, 2024
a739a4f
chore(release): 5.0.0-beta.1 [skip ci]
svc-cli-bot Feb 1, 2024
82ee43c
Merge branch 'main' into mdonnalley/revamp
mdonnalley Feb 22, 2024
95f6cac
chore(release): 5.0.0-beta.2 [skip ci]
svc-cli-bot Feb 22, 2024
eab8e5b
Merge branch 'main' into mdonnalley/revamp
mdonnalley Mar 7, 2024
6581914
chore(release): 5.0.0-beta.3 [skip ci]
svc-cli-bot Mar 7, 2024
b7eca7a
chore: merge main conflicts
iowillhoit Mar 14, 2024
7c33ba1
chore(release): 5.0.0-beta.4 [skip ci]
svc-cli-bot Mar 14, 2024
a127059
fix: reinstall plugin from url if applicable
mdonnalley Mar 21, 2024
d9a67ae
feat: better logging
mdonnalley Mar 21, 2024
7167090
fix: uninstall mis-scoped plugin
mdonnalley Mar 21, 2024
6fdb181
fix: warn about missing expected files after github install
mdonnalley Mar 21, 2024
c07eccf
fix: add type
mdonnalley Mar 21, 2024
b799b38
feat: improve ux when no output from npm
mdonnalley Mar 21, 2024
2c722b4
chore: merge main conflicts
iowillhoit Mar 22, 2024
fa30d5e
chore(release): 5.0.0-beta.5 [skip ci]
svc-cli-bot Mar 22, 2024
a53853b
fix: display name when uninstalling wiht no args
mdonnalley Mar 22, 2024
ac2c394
test: set timeout on install test
mdonnalley Mar 22, 2024
566af61
fix: ensure dir exists before checking for name
mdonnalley Mar 22, 2024
034a067
Merge branch 'main' into mdonnalley/revamp
iowillhoit Mar 25, 2024
183be3f
chore(release): 5.0.0-beta.6 [skip ci]
svc-cli-bot Mar 25, 2024
12808a5
Merge branch 'main' into mdonnalley/revamp
mdonnalley Mar 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@ For removing plugins that are no longer needed (either because they're sunset or
- [`mycli plugins`](#mycli-plugins)
- [`mycli plugins:inspect PLUGIN...`](#mycli-pluginsinspect-plugin)
- [`mycli plugins:install PLUGIN...`](#mycli-pluginsinstall-plugin)
- [`mycli plugins:link PLUGIN`](#mycli-pluginslink-plugin)
- [`mycli plugins link PATH`](#mycli-plugins-link-path)
- [`mycli plugins reset`](#mycli-plugins-reset)
- [`mycli plugins:uninstall PLUGIN...`](#mycli-pluginsuninstall-plugin)
- [`mycli plugins uninstall [PLUGIN]`](#mycli-plugins-uninstall-plugin)
- [`mycli plugins update`](#mycli-plugins-update)

## `mycli plugins`
Expand All @@ -117,7 +117,7 @@ EXAMPLES
$ mycli plugins
```

_See code: [src/commands/plugins/index.ts](https://github.com/oclif/plugin-plugins/blob/4.3.5/src/commands/plugins/index.ts)_
_See code: [src/commands/plugins/index.ts](https://github.com/oclif/plugin-plugins/blob/4.3.6-beta.0/src/commands/plugins/index.ts)_

## `mycli plugins:inspect PLUGIN...`

Expand All @@ -144,7 +144,7 @@ EXAMPLES
$ mycli plugins inspect myplugin
```

_See code: [src/commands/plugins/inspect.ts](https://github.com/oclif/plugin-plugins/blob/4.3.5/src/commands/plugins/inspect.ts)_
_See code: [src/commands/plugins/inspect.ts](https://github.com/oclif/plugin-plugins/blob/4.3.6-beta.0/src/commands/plugins/inspect.ts)_

## `mycli plugins:install PLUGIN...`

Expand All @@ -158,10 +158,10 @@ ARGUMENTS
PLUGIN Plugin to install.

FLAGS
-f, --force Run yarn install with force flag.
-f, --force Force npm to fetch remote resources even if a local copy exists on disk.
-h, --help Show CLI help.
-s, --silent Silences yarn output.
-v, --verbose Show verbose yarn output.
-s, --silent Silences npm output.
-v, --verbose Show verbose npm output.

GLOBAL FLAGS
--json Format output as json.
Expand All @@ -188,15 +188,15 @@ EXAMPLES
$ mycli plugins install someuser/someplugin
```

_See code: [src/commands/plugins/install.ts](https://github.com/oclif/plugin-plugins/blob/4.3.5/src/commands/plugins/install.ts)_
_See code: [src/commands/plugins/install.ts](https://github.com/oclif/plugin-plugins/blob/4.3.6-beta.0/src/commands/plugins/install.ts)_

## `mycli plugins:link PLUGIN`
## `mycli plugins link PATH`

Links a plugin into the CLI for development.

```
USAGE
$ mycli plugins link PLUGIN
$ mycli plugins link PATH [-h] [--install] [-v]

ARGUMENTS
PATH [default: .] path to plugin
Expand All @@ -218,7 +218,7 @@ EXAMPLES
$ mycli plugins link myplugin
```

_See code: [src/commands/plugins/link.ts](https://github.com/oclif/plugin-plugins/blob/4.3.5/src/commands/plugins/link.ts)_
_See code: [src/commands/plugins/link.ts](https://github.com/oclif/plugin-plugins/blob/4.3.6-beta.0/src/commands/plugins/link.ts)_

## `mycli plugins reset`

Expand All @@ -233,15 +233,15 @@ FLAGS
--reinstall Reinstall all plugins after uninstalling.
```

_See code: [src/commands/plugins/reset.ts](https://github.com/oclif/plugin-plugins/blob/4.3.5/src/commands/plugins/reset.ts)_
_See code: [src/commands/plugins/reset.ts](https://github.com/oclif/plugin-plugins/blob/4.3.6-beta.0/src/commands/plugins/reset.ts)_

## `mycli plugins:uninstall PLUGIN...`
## `mycli plugins uninstall [PLUGIN]`

Removes a plugin from the CLI.

```
USAGE
$ mycli plugins uninstall PLUGIN...
$ mycli plugins uninstall [PLUGIN] [-h] [-v]

ARGUMENTS
PLUGIN plugin to uninstall
Expand All @@ -261,7 +261,7 @@ EXAMPLES
$ mycli plugins uninstall myplugin
```

_See code: [src/commands/plugins/uninstall.ts](https://github.com/oclif/plugin-plugins/blob/4.3.5/src/commands/plugins/uninstall.ts)_
_See code: [src/commands/plugins/uninstall.ts](https://github.com/oclif/plugin-plugins/blob/4.3.6-beta.0/src/commands/plugins/uninstall.ts)_

## `mycli plugins update`

Expand All @@ -279,6 +279,6 @@ DESCRIPTION
Update installed plugins.
```

_See code: [src/commands/plugins/update.ts](https://github.com/oclif/plugin-plugins/blob/4.3.5/src/commands/plugins/update.ts)_
_See code: [src/commands/plugins/update.ts](https://github.com/oclif/plugin-plugins/blob/4.3.6-beta.0/src/commands/plugins/update.ts)_

<!-- commandsstop -->
17 changes: 8 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
{
"name": "@oclif/plugin-plugins",
"description": "plugins plugin for oclif",
"version": "4.3.5",
"version": "5.0.0-beta.4",
"author": "Salesforce",
"bugs": "https://github.com/oclif/plugin-plugins/issues",
"dependencies": {
"@oclif/core": "^3.23.0",
"chalk": "^5.3.0",
"debug": "^4.3.4",
"npm": "10.2.4",
"npm-run-path": "^4.0.1",
"npm-package-arg": "^11.0.1",
"npm-run-path": "^5.2.0",
"semver": "^7.6.0",
"shelljs": "^0.8.5",
"validate-npm-package-name": "^5.0.0",
"yarn": "^1.22.21"
"validate-npm-package-name": "^5.0.0"
},
"devDependencies": {
"@commitlint/config-conventional": "^18",
Expand All @@ -23,6 +22,7 @@
"@types/debug": "^4.1.12",
"@types/mocha": "^10.0.6",
"@types/node": "^18",
"@types/npm-package-arg": "^6.1.4",
"@types/semver": "^7.5.8",
"@types/shelljs": "^0.8.15",
"@types/sinon": "^17",
Expand Down Expand Up @@ -50,8 +50,7 @@
"files": [
"oclif.manifest.json",
"/lib",
"npm-shrinkwrap.json",
"oclif.lock"
"npm-shrinkwrap.json"
],
"homepage": "https://github.com/oclif/plugin-plugins",
"keywords": [
Expand All @@ -77,12 +76,12 @@
"repository": "oclif/plugin-plugins",
"scripts": {
"build": "shx rm -rf lib && tsc",
"clean": "shx rm -f oclif.manifest.json npm-shrinkwrap.json oclif.lock",
"clean": "shx rm -f oclif.manifest.json npm-shrinkwrap.json",
"compile": "tsc",
"lint": "eslint . --ext .ts",
"postpack": "yarn run clean",
"posttest": "yarn lint",
"prepack": "yarn build && oclif manifest && oclif readme && npm shrinkwrap && oclif lock",
"prepack": "yarn build && oclif manifest && oclif readme && npm shrinkwrap",
"prepare": "husky && yarn build",
"pretest": "yarn build --noEmit && tsc -p test --noEmit",
"test:integration:install": "mocha \"test/**/install.integration.ts\"",
Expand Down
6 changes: 5 additions & 1 deletion src/commands/plugins/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@ export default class PluginsIndex extends Command {
core: Flags.boolean({description: 'Show core plugins.'}),
}

plugins = new Plugins(this.config)
plugins!: Plugins

async run(): Promise<PluginsJson> {
const {flags} = await this.parse(PluginsIndex)
this.plugins = new Plugins({
config: this.config,
})

let plugins = this.config.getPluginsList()
sortBy(plugins, (p) => this.plugins.friendlyName(p.name))
if (!flags.core) {
Expand Down
7 changes: 5 additions & 2 deletions src/commands/plugins/inspect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export default class PluginsInspect extends Command {

static usage = 'plugins:inspect PLUGIN...'

plugins = new Plugins(this.config)
plugins!: Plugins

async findDep(plugin: Plugin, dependency: string): Promise<{pkgPath: null | string; version: null | string}> {
const dependencyPath = join(...dependency.split('/'))
Expand Down Expand Up @@ -140,7 +140,10 @@ export default class PluginsInspect extends Command {
/* eslint-disable no-await-in-loop */
async run(): Promise<PluginWithDeps[]> {
const {argv, flags} = await this.parse(PluginsInspect)
if (flags.verbose) this.plugins.verbose = true
this.plugins = new Plugins({
config: this.config,
verbose: flags.verbose,
})
const aliases = this.config.pjson.oclif.aliases ?? {}
const plugins: PluginWithDeps[] = []
for (let name of argv as string[]) {
Expand Down
42 changes: 22 additions & 20 deletions src/commands/plugins/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import chalk from 'chalk'
import validate from 'validate-npm-package-name'

import Plugins from '../../plugins.js'
import {YarnMessagesCache} from '../../util.js'

export default class PluginsInstall extends Command {
static aliases = ['plugins:add']
Expand Down Expand Up @@ -32,7 +31,7 @@ e.g. If you have a core plugin that has a 'hello' command, installing a user-ins
static flags = {
force: Flags.boolean({
char: 'f',
description: 'Run yarn install with force flag.',
description: 'Force npm to fetch remote resources even if a local copy exists on disk.',
}),
help: Flags.help({char: 'h'}),
jit: Flags.boolean({
Expand All @@ -46,7 +45,7 @@ e.g. If you have a core plugin that has a 'hello' command, installing a user-ins
const jitPluginsConfig = ctx.config.pjson.oclif.jitPlugins ?? {}
if (Object.keys(jitPluginsConfig).length === 0) return input

const plugins = new Plugins(ctx.config)
const plugins = new Plugins({config: ctx.config})

const nonJitPlugins = await Promise.all(
requestedPlugins.map(async (plugin) => {
Expand All @@ -65,12 +64,13 @@ e.g. If you have a core plugin that has a 'hello' command, installing a user-ins
}),
silent: Flags.boolean({
char: 's',
description: 'Silences yarn output.',
default: true,
description: 'Silences npm output.',
exclusive: ['verbose'],
}),
verbose: Flags.boolean({
char: 'v',
description: 'Show verbose yarn output.',
description: 'Show verbose npm output.',
exclusive: ['silent'],
}),
}
Expand All @@ -80,11 +80,13 @@ e.g. If you have a core plugin that has a 'hello' command, installing a user-ins
static usage = 'plugins:install PLUGIN...'

flags!: Interfaces.InferredFlags<typeof PluginsInstall.flags>
plugins = new Plugins(this.config)

// In this case we want these operations to happen
// sequentially so the `no-await-in-loop` rule is ignored
async parsePlugin(input: string): Promise<{name: string; tag: string; type: 'npm'} | {type: 'repo'; url: string}> {
async parsePlugin(
plugins: Plugins,
input: string,
): Promise<{name: string; tag: string; type: 'npm'} | {type: 'repo'; url: string}> {
// git ssh url
if (input.startsWith('git+ssh://') || input.endsWith('.git')) {
return {type: 'repo', url: input}
Expand All @@ -93,7 +95,7 @@ e.g. If you have a core plugin that has a 'hello' command, installing a user-ins
const getNameAndTag = async (input: string): Promise<{name: string; tag: string}> => {
const regexAtSymbolNotAtBeginning = /(?<!^)@/
const [splitName, tag = 'latest'] = input.split(regexAtSymbolNotAtBeginning)
const name = splitName.startsWith('@') ? splitName : await this.plugins.maybeUnfriendlyName(splitName)
const name = splitName.startsWith('@') ? splitName : await plugins.maybeUnfriendlyName(splitName)
validateNpmPkgName(name)

if (this.flags.jit) {
Expand Down Expand Up @@ -135,39 +137,39 @@ e.g. If you have a core plugin that has a 'hello' command, installing a user-ins
async run(): Promise<void> {
const {argv, flags} = await this.parse(PluginsInstall)
this.flags = flags
if (flags.verbose && !flags.silent) this.plugins.verbose = true
if (flags.silent && !flags.verbose) this.plugins.silent = true

const plugins = new Plugins({
config: this.config,
verbose: this.flags.verbose,
})
const aliases = this.config.pjson.oclif.aliases || {}
for (let name of argv as string[]) {
if (aliases[name] === null) this.error(`${name} is blocked`)
name = aliases[name] || name
const p = await this.parsePlugin(name)
const p = await this.parsePlugin(plugins, name)
let plugin
await this.config.runHook('plugins:preinstall', {
plugin: p,
})
try {
if (p.type === 'npm') {
ux.action.start(`Installing plugin ${chalk.cyan(this.plugins.friendlyName(p.name) + '@' + p.tag)}`)
plugin = await this.plugins.install(p.name, {
ux.action.start(
`${this.config.name}: Installing plugin ${chalk.cyan(plugins.friendlyName(p.name) + '@' + p.tag)}`,
)
plugin = await plugins.install(p.name, {
force: flags.force,
tag: p.tag,
})
} else {
ux.action.start(`Installing plugin ${chalk.cyan(p.url)}`)
plugin = await this.plugins.install(p.url, {force: flags.force})
ux.action.start(`${this.config.name}: Installing plugin ${chalk.cyan(p.url)}`)
plugin = await plugins.install(p.url, {force: flags.force})
}
} catch (error) {
ux.action.stop(chalk.bold.red('failed'))
YarnMessagesCache.getInstance().flush(plugin)
throw error
}

ux.action.stop(`installed v${plugin.version}`)

YarnMessagesCache.getInstance().flush(plugin)

this.log(chalk.green(`\nSuccessfully installed ${plugin.name} v${plugin.version}`))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean to remove this log message?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. The spinner now shows the success (or failure) message

@salesforce/cli: Installing plugin @oclif/plugin-version@latest... installed v2.0.14

}
}
}
Expand Down
18 changes: 8 additions & 10 deletions src/commands/plugins/link.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {Args, Command, Flags, ux} from '@oclif/core'
import chalk from 'chalk'

import Plugins from '../../plugins.js'
import {YarnMessagesCache} from '../../util.js'

export default class PluginsLink extends Command {
static args = {
Expand All @@ -27,17 +26,16 @@ e.g. If you have a user-installed or core plugin that has a 'hello' command, ins
verbose: Flags.boolean({char: 'v'}),
}

static usage = 'plugins:link PLUGIN'

plugins = new Plugins(this.config)

async run(): Promise<void> {
const {args, flags} = await this.parse(PluginsLink)
this.plugins.verbose = flags.verbose
ux.action.start(`Linking plugin ${chalk.cyan(args.path)}`)
await this.plugins.link(args.path, {install: flags.install})
ux.action.stop()

YarnMessagesCache.getInstance().flush()
const plugins = new Plugins({
config: this.config,
verbose: flags.verbose,
})

ux.action.start(`${this.config.name}: Linking plugin ${chalk.cyan(args.path)}`)
await plugins.link(args.path, {install: flags.install})
ux.action.stop()
}
}
4 changes: 3 additions & 1 deletion src/commands/plugins/reset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ export default class Reset extends Command {

async run(): Promise<void> {
const {flags} = await this.parse(Reset)
const plugins = new Plugins(this.config)
const plugins = new Plugins({
config: this.config,
})
const userPlugins = await plugins.list()

this.log(`Found ${userPlugins.length} plugin${userPlugins.length === 0 ? '' : 's'}:`)
Expand Down
Loading
Loading