Skip to content

Commit

Permalink
feat: support JIT plugins (#1009)
Browse files Browse the repository at this point in the history
* feat: support JIT plugins

* feat: support versioned jit plugins

* chore: bump core
  • Loading branch information
mdonnalley committed Jan 19, 2023
1 parent a4c80b0 commit b713b9d
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 7 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"bugs": "https://github.com/oclif/oclif/issues",
"dependencies": {
"@oclif/core": "^2.0.2-beta.6",
"@oclif/core": "^2.0.2-beta.10",
"@oclif/plugin-help": "^5.1.19",
"@oclif/plugin-not-found": "^2.3.7",
"@oclif/plugin-warn-if-update-available": "^2.0.14",
Expand All @@ -22,6 +22,7 @@
"lodash": "^4.17.21",
"normalize-package-data": "^3.0.3",
"semver": "^7.3.8",
"shelljs": "^0.8.5",
"tslib": "^2.3.1",
"yeoman-environment": "^3.11.1",
"yeoman-generator": "^5.6.1",
Expand Down Expand Up @@ -56,7 +57,6 @@
"mocha": "^9.2.2",
"npm-run-path": "^4.0.1",
"nps": "^5.10.0",
"shelljs": "^0.8.5",
"shx": "^0.3.4",
"tmp": "^0.2.1",
"ts-node": "^10.7.0",
Expand Down Expand Up @@ -141,4 +141,4 @@
"registry": "https://registry.npmjs.org"
},
"types": "lib/index.d.ts"
}
}
91 changes: 89 additions & 2 deletions src/commands/manifest.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
import {Args, Command, Plugin} from '@oclif/core'
import {Args, Command, Plugin, ux, Flags, Interfaces} from '@oclif/core'
import * as fs from 'fs-extra'
import * as path from 'path'
import * as os from 'os'
import * as semver from 'semver'
import {exec, ShellString, ExecOptions} from 'shelljs'

async function fileExists(filePath: string): Promise<boolean> {
try {
await fs.access(filePath)
return true
} catch {
return false
}
}

export default class Manifest extends Command {
static description = 'generates plugin manifest json'
Expand All @@ -9,13 +21,58 @@ export default class Manifest extends Command {
path: Args.string({description: 'path to plugin', default: '.'}),
}

static flags = {
jit: Flags.boolean({
allowNo: true,
summary: 'append commands from JIT plugins in manifest',
default: true,
}),
}

async run(): Promise<void> {
const {flags} = await this.parse(Manifest)
try {
fs.unlinkSync('oclif.manifest.json')
} catch {}

const {args} = await this.parse(Manifest)
const root = path.resolve(args.path)

const packageJson = fs.readJSONSync('package.json') as { oclif: { jitPlugins: Record<string, string> } }

let jitPluginManifests: Interfaces.Manifest[] = []

if (flags.jit && packageJson.oclif.jitPlugins) {
this.debug('jitPlugins: %s', packageJson.oclif.jitPlugins)
const tmpDir = os.tmpdir()
const promises = Object.entries(packageJson.oclif.jitPlugins).map(async ([jitPlugin, version]) => {
const pluginDir = jitPlugin.replace('/', '-').replace('@', '')
const repo = this.executeCommand(`npm view ${jitPlugin} repository --json`)
const stdout = JSON.parse(repo.stdout)

const repoUrl = stdout.url.replace(`${stdout.type}+`, '')

const fullPath = path.join(tmpDir, pluginDir)
if (await fileExists(fullPath)) await fs.remove(fullPath)

const versions = JSON.parse(this.executeCommand(`npm view ${jitPlugin} versions --json`).stdout)
const maxSatisfying = semver.maxSatisfying(versions, version)

this.cloneRepo(repoUrl, fullPath, maxSatisfying)

this.executeCommand('yarn', {cwd: fullPath})
this.executeCommand('yarn build', {cwd: fullPath})
const plugin = new Plugin({root: fullPath, type: 'jit', ignoreManifest: true, errorOnManifestCreate: true})
await plugin.load()

return plugin.manifest
})

ux.action.start('Generating JIT plugin manifests')
jitPluginManifests = await Promise.all(promises)
ux.action.stop()
}

let plugin = new Plugin({root, type: 'core', ignoreManifest: true, errorOnManifestCreate: true})
if (!plugin) throw new Error('plugin not found')
await plugin.load()
Expand All @@ -32,7 +89,37 @@ export default class Manifest extends Command {

const dotfile = plugin.pjson.files.find((f: string) => f.endsWith('.oclif.manifest.json'))
const file = path.join(plugin.root, `${dotfile ? '.' : ''}oclif.manifest.json`)
fs.writeFileSync(file, JSON.stringify(plugin.manifest))

for (const manifest of jitPluginManifests) {
plugin.manifest.commands = {...plugin.manifest.commands, ...manifest.commands}
}

fs.writeFileSync(file, JSON.stringify(plugin.manifest, null, 2))

this.log(`wrote manifest to ${file}`)
}

private cloneRepo(repoUrl: string, fullPath: string, tag: string | semver.SemVer | null): void {
try {
this.executeCommand(`git clone --branch ${tag} ${repoUrl} ${fullPath} --depth 1`)
} catch {
try {
this.executeCommand(`git clone --branch v${tag} ${repoUrl} ${fullPath} --depth 1`)
} catch {
throw new Error(`Unable to clone repo ${repoUrl} with tag ${tag}`)
}
}
}

private executeCommand(command: string, options?: ExecOptions): ShellString {
const debugString = options?.cwd ? `executing command: ${command} in ${options.cwd}` : `executing command: ${command}`
this.debug(debugString)
const result = exec(command, {...options, silent: true, async: false})
if (result.code !== 0) {
this.error(result.stderr)
}

this.debug(result.stdout)
return result
}
}
38 changes: 36 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,40 @@
widest-line "^3.1.0"
wrap-ansi "^7.0.0"

"@oclif/core@^2.0.2-beta.10":
version "2.0.2-beta.10"
resolved "https://registry.yarnpkg.com/@oclif/core/-/core-2.0.2-beta.10.tgz#5b459a91d653b8d5aa234e4324a4cc483747abd2"
integrity sha512-FgJ5XHE6MjE7DOyQAcOZPD5Xs5cNOzP91zAQBkut8xhOkZA1NRQjv+7BczJqOTerXccohhTlu09pd7OAyDuitw==
dependencies:
"@types/cli-progress" "^3.11.0"
ansi-escapes "^4.3.2"
ansi-styles "^4.3.0"
cardinal "^2.1.1"
chalk "^4.1.2"
clean-stack "^3.0.1"
cli-progress "^3.10.0"
debug "^4.3.4"
ejs "^3.1.6"
fs-extra "^9.1.0"
get-package-type "^0.1.0"
globby "^11.1.0"
hyperlinker "^1.0.0"
indent-string "^4.0.0"
is-wsl "^2.2.0"
js-yaml "^3.14.1"
natural-orderby "^2.0.3"
object-treeify "^1.1.33"
password-prompt "^1.1.2"
semver "^7.3.7"
string-width "^4.2.3"
strip-ansi "^6.0.1"
supports-color "^8.1.1"
supports-hyperlinks "^2.2.0"
tslib "^2.4.1"
widest-line "^3.1.0"
wordwrap "^1.0.0"
wrap-ansi "^7.0.0"

"@oclif/core@^2.0.2-beta.6":
version "2.0.2-beta.6"
resolved "https://registry.yarnpkg.com/@oclif/core/-/core-2.0.2-beta.6.tgz#d794d53886683f37ab712092ff88741981b2c02f"
Expand Down Expand Up @@ -978,7 +1012,7 @@

"@types/shelljs@^0.8.11":
version "0.8.11"
resolved "https://registry.npmjs.org/@types/shelljs/-/shelljs-0.8.11.tgz#17a5696c825974e96828e96e89585d685646fcb8"
resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.8.11.tgz#17a5696c825974e96828e96e89585d685646fcb8"
integrity sha512-x9yaMvEh5BEaZKeVQC4vp3l+QoFj3BXcd4aYfuKSzIIyihjdVARAadYy3SMNIz0WCCdS2vB9JL/U6GQk5PaxQw==
dependencies:
"@types/glob" "*"
Expand Down Expand Up @@ -5595,7 +5629,7 @@ shell-quote@^1.7.3:

shelljs@^0.8.3, shelljs@^0.8.5:
version "0.8.5"
resolved "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c"
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c"
integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==
dependencies:
glob "^7.0.0"
Expand Down

0 comments on commit b713b9d

Please sign in to comment.