Skip to content
This repository has been archived by the owner on Jan 29, 2023. It is now read-only.

Commit

Permalink
forked oclif plugin generator and modified it to create sfdx cli plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
Alli committed Apr 4, 2018
1 parent 679b03b commit ea6013a
Show file tree
Hide file tree
Showing 24 changed files with 592 additions and 330 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -6,3 +6,5 @@
/lib
/node_modules
/tmp
.oclif.manifest.json
yarn.lock
Binary file added .images/vscodeScreenshot.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
485 changes: 233 additions & 252 deletions README.md

Large diffs are not rendered by default.

16 changes: 9 additions & 7 deletions package.json
@@ -1,10 +1,10 @@
{
"name": "oclif",
"description": "oclif: create your own CLI",
"version": "1.7.13",
"author": "Jeff Dickey @jdxcode",
"name": "@salesforce/plugin-generator",
"description": "create your own sfdx plugin",
"version": "0.0.5",
"author": "ALM - CI",
"bin": "./bin/run",
"bugs": "https://github.com/oclif/oclif/issues",
"bugs": "",
"dependencies": {
"@oclif/command": "^1.4.6",
"@oclif/config": "^1.3.61",
Expand Down Expand Up @@ -52,9 +52,10 @@
".oclif.manifest.json",
"/bin",
"/lib",
"/templates"
"/templates",
"/messages"
],
"homepage": "https://github.com/oclif/oclif",
"homepage": "",
"keywords": [
"oclif"
],
Expand All @@ -75,6 +76,7 @@
"lint": "nps lint",
"postpublish": "rm .oclif.manifest.json",
"posttest": "yarn run lint",
"prepack": "oclif-dev manifest",
"prepublishOnly": "yarn run build && oclif-dev manifest",
"version": "oclif-dev readme && oclif-dev manifest && git add README.md",
"test": "nps test"
Expand Down
4 changes: 4 additions & 0 deletions sfdx-ci.yaml
@@ -0,0 +1,4 @@
jobs:
- name: publish
skipTests: true
- name: promote
4 changes: 2 additions & 2 deletions src/command_base.ts
Expand Up @@ -7,11 +7,11 @@ export default abstract class CommandBase extends Command {

env.register(
require.resolve(`./generators/${type}`),
`oclif:${type}`
`sfdx:${type}`
)

await new Promise((resolve, reject) => {
env.run(`oclif:${type}`, generatorOptions, (err: Error, results: any) => {
env.run(`sfdx:${type}`, generatorOptions, (err: Error, results: any) => {
if (err) reject(err)
else resolve(results)
})
Expand Down
1 change: 1 addition & 0 deletions src/commands/command.ts
Expand Up @@ -9,6 +9,7 @@ export interface Options {
}

export default abstract class AppCommand extends Base {
static hidden = true
static description = 'add a command to an existing CLI or plugin'

static flags = {
Expand Down
1 change: 1 addition & 0 deletions src/commands/multi.ts
@@ -1,6 +1,7 @@
import AppCommand from '../app_command'

export default class extends AppCommand {
static hidden = true
static description = 'generate a new multi-command CLI'
type = 'multi'
}
1 change: 1 addition & 0 deletions src/commands/plugin.ts
@@ -1,6 +1,7 @@
import AppCommand from '../app_command'

export default class extends AppCommand {
static hidden = true
static description = 'create a new CLI plugin'
type = 'plugin'
}
28 changes: 28 additions & 0 deletions src/commands/plugins/generate.ts
@@ -0,0 +1,28 @@
import Base from '../../command_base'
import {flags} from '@oclif/command'

export default class Generate extends Base {
static flags = {
defaults: flags.boolean({description: 'use defaults for every setting'}),
force: flags.boolean({description: 'overwrite existing files'}),
}

static args = [
{name: 'path', required: false}
]

static description = 'create a new sfdx-cli plugin'
type = 'sfdx-plugin'

async run() {
const {flags, args} = this.parse(Generate)

await super.generate('app', {
type: this.type,
path: args.path,
defaults: flags.defaults,
force: flags.force,
options: []
})
}
}
1 change: 1 addition & 0 deletions src/commands/single.ts
@@ -1,6 +1,7 @@
import AppCommand from '../app_command'

export default class extends AppCommand {
static hidden = true
static description = 'generate a new single-command CLI'
type = 'single'
}
106 changes: 94 additions & 12 deletions src/generators/app.ts
Expand Up @@ -43,7 +43,7 @@ class App extends Generator {
yarn: boolean
}
args!: {[k: string]: string}
type: 'single' | 'multi' | 'plugin' | 'base'
type: 'single' | 'multi' | 'plugin' | 'base' | 'sfdx-plugin'
path: string
pjson: any
githubUser: string | undefined
Expand Down Expand Up @@ -102,6 +102,9 @@ class App extends Generator {
case 'multi':
msg = 'Time to build a multi-command CLI with oclif!'
break
case 'sfdx-plugin':
msg = 'Time to build an sfdx-cli plugin!'
break
default:
msg = `Time to build a oclif ${this.type}!`
}
Expand Down Expand Up @@ -223,6 +226,7 @@ class App extends Generator {
{name: 'semantic-release (automated version management)', value: 'semantic-release', checked: this.options['semantic-release']}
],
filter: ((arr: string[]) => _.keyBy(arr)) as any,
when: this.type !== 'sfdx-plugin'
},
// {
// type: 'string',
Expand All @@ -234,7 +238,8 @@ class App extends Generator {
]) as any
}
debug(this.answers)
this.options = this.answers.options
const sfdxPluginOptions = {typescript: true, mocha: true, 'semantic-release': false}
this.options = this.type === 'sfdx-plugin' ? sfdxPluginOptions : this.answers.options
this.ts = this.options.typescript
this.tslint = this.options.tslint
this.yarn = this.options.yarn
Expand Down Expand Up @@ -268,15 +273,32 @@ class App extends Generator {
this.pjson.scripts.build = 'rm -rf lib && tsc'
this.pjson.scripts.prepublishOnly = `${npm} run build`
}
if (['plugin', 'multi'].includes(this.type)) {
if (['sfdx-plugin', 'plugin', 'multi'].includes(this.type)) {
this.pjson.scripts.prepublishOnly = nps.series(this.pjson.scripts.prepublishOnly, 'oclif-dev manifest')
if (this.semantic_release) this.pjson.scripts.prepublishOnly = nps.series(this.pjson.scripts.prepublishOnly, 'oclif-dev readme')
this.pjson.scripts.version = nps.series('oclif-dev readme', 'git add README.md')
this.pjson.scripts.clean = 'rm -f .oclif.manifest.json'
this.pjson.scripts.postpublish = this.pjson.scripts.preversion = `${npm} run clean`
this.pjson.files.push('.oclif.manifest.json')
if (this.type === 'sfdx-plugin') {
this.pjson.files.push('/messages')
this.pjson.scripts.prepare = this.pjson.scripts.prepublishOnly
}
}

let keywords
switch (this.type) {
case 'sfdx-plugin':
keywords = 'sfdx-plugin'
break
case 'plugin':
keywords = 'oclif-plugin'
break
default:
keywords = 'oclif'
}
this.pjson.keywords = defaults.keywords || [this.type === 'plugin' ? 'oclif-plugin' : 'oclif']

this.pjson.keywords = defaults.keywords || [keywords]
this.pjson.homepage = defaults.homepage || `https://github.com/${this.pjson.repository}`
this.pjson.bugs = defaults.bugs || `https://github.com/${this.pjson.repository}/issues`

Expand All @@ -288,7 +310,7 @@ class App extends Generator {
} else if (this.type === 'plugin') {
this.pjson.oclif.bin = 'oclif-example'
}
if (this.type !== 'plugin') {
if (this.type !== 'plugin' && this.type !== 'sfdx-plugin') {
this.pjson.main = defaults.main || (this.ts ? 'lib/index.js' : 'src/index.js')
if (this.ts) {
this.pjson.types = defaults.types || 'lib/index.d.ts'
Expand All @@ -302,6 +324,7 @@ class App extends Generator {
switch (this.type) {
case 'multi':
case 'plugin':
case 'sfdx-plugin':
this.pjson.oclif = {
commands: `./${this.ts ? 'lib' : 'src'}/commands`,
// hooks: {init: `./${this.ts ? 'lib' : 'src'}/hooks/init`},
Expand All @@ -310,7 +333,7 @@ class App extends Generator {
break
default:
}
if (this.type === 'plugin' && !this.pjson.oclif.devPlugins) {
if ((this.type === 'plugin' || this.type === 'sfdx-plugin') && !this.pjson.oclif.devPlugins) {
this.pjson.oclif.devPlugins = [
'@oclif/plugin-help',
]
Expand All @@ -331,7 +354,11 @@ class App extends Generator {
}
this.fs.copyTpl(this.templatePath('tsconfig.json'), this.destinationPath('tsconfig.json'), this)
if (this.mocha) {
this.fs.copyTpl(this.templatePath('test/tsconfig.json'), this.destinationPath('test/tsconfig.json'), this)
if (this.type === 'sfdx-plugin') {
this.fs.copyTpl(this.templatePath('sfdxPlugin/test/tsconfig.json'), this.destinationPath('test/tsconfig.json'), this)
} else {
this.fs.copyTpl(this.templatePath('test/tsconfig.json'), this.destinationPath('test/tsconfig.json'), this)
}
}
}
if (this.mocha && !this.fs.exists('test')) {
Expand All @@ -343,14 +370,15 @@ class App extends Generator {
}
if (_.isEmpty(this.pjson.oclif)) delete this.pjson.oclif
this.pjson.files = _.uniq((this.pjson.files || []).sort())

this.fs.writeJSON(this.destinationPath('./package.json'), sortPjson(this.pjson))
this.fs.copyTpl(this.templatePath('editorconfig'), this.destinationPath('.editorconfig'), this)
this.fs.copyTpl(this.templatePath('scripts/greenkeeper'), this.destinationPath('.circleci/greenkeeper'), this)
// if (this.semantic_release) {
// this.fs.copyTpl(this.templatePath('scripts/release'), this.destinationPath('.circleci/release'), this)
// }
// this.fs.copyTpl(this.templatePath('scripts/setup_git'), this.destinationPath('.circleci/setup_git'), this)
this.fs.copyTpl(this.templatePath('README.md.ejs'), this.destinationPath('README.md'), this)

this.fs.copyTpl(this.templatePath('circle.yml.ejs'), this.destinationPath('.circleci/config.yml'), this)
this.fs.copyTpl(this.templatePath('appveyor.yml.ejs'), this.destinationPath('appveyor.yml'), this)
if (this.pjson.license === 'MIT' && (this.pjson.repository.startsWith('oclif') || this.pjson.repository.startsWith('heroku'))) {
Expand All @@ -362,9 +390,12 @@ class App extends Generator {
this.fs.copyTpl(this.templatePath('gitattributes'), this.destinationPath('.gitattributes'), this)

this.fs.write(this.destinationPath('.gitignore'), this._gitignore())
this.fs.copyTpl(this.templatePath('eslintrc'), this.destinationPath('.eslintrc'), this)
const eslintignore = this._eslintignore()
if (eslintignore.trim()) this.fs.write(this.destinationPath('.eslintignore'), this._eslintignore())
if (this.type !== 'sfdx-plugin') {
this.fs.copyTpl(this.templatePath('README.md.ejs'), this.destinationPath('README.md'), this)
this.fs.copyTpl(this.templatePath('eslintrc'), this.destinationPath('.eslintrc'), this)
const eslintignore = this._eslintignore()
if (eslintignore.trim()) this.fs.write(this.destinationPath('.eslintignore'), this._eslintignore())
}

switch (this.type) {
case 'single':
Expand All @@ -373,6 +404,9 @@ class App extends Generator {
case 'plugin':
this._writePlugin()
break
case 'sfdx-plugin':
this._writeSfdxPlugin()
break
case 'multi':
this._writeMulti()
break
Expand Down Expand Up @@ -404,6 +438,21 @@ class App extends Generator {
'globby',
)
break
case 'sfdx-plugin':
dependencies.push(
'@oclif/command',
'@oclif/config',
'@oclif/errors',
'@salesforce/command',
)
devDependencies.push(
'@oclif/dev-cli',
'@oclif/plugin-help',
'globby',
'@salesforce/dev-config',
'sinon',
)
break
case 'multi':
dependencies.push(
'@oclif/config',
Expand Down Expand Up @@ -456,7 +505,7 @@ class App extends Generator {
install(devDependencies, {...yarnOpts, ...dev, ignoreScripts: true}),
install(dependencies, yarnOpts),
]).then(() => {
if (['plugin', 'multi'].includes(this.type)) {
if (['sfdx-plugin', 'plugin', 'multi'].includes(this.type)) {
this.spawnCommandSync(path.join('.', 'node_modules/.bin/oclif-dev'), ['readme'])
}
console.log(`\nCreated ${this.pjson.name} in ${this.destinationRoot()}`)
Expand Down Expand Up @@ -518,6 +567,39 @@ class App extends Generator {
}
}

private _writeSfdxPlugin() {
const sfdxExampleCommand = 'org'
const topic = 'hello'
const bin = this._bin
const cmd = `${bin} ${sfdxExampleCommand}`
const opts = {...this as any, _, bin, cmd}
this.fs.copyTpl(this.templatePath('plugin/bin/run'), this.destinationPath('bin/run'), opts)
this.fs.copyTpl(this.templatePath('bin/run.cmd'), this.destinationPath('bin/run.cmd'), opts)
this.fs.copyTpl(this.templatePath('sfdxPlugin/README.md.ejs'), this.destinationPath('README.md'), this)
this.fs.copy(this.templatePath('.images/vscodeScreenshot.png'), this.destinationPath('.images/vscodeScreenshot.png'), this)
if (!fs.existsSync('src/commands')) {
this.fs.copyTpl(this.templatePath(`src/sfdxCommand.${this._ext}.ejs`), this.destinationPath(`src/commands/${topic}/${sfdxExampleCommand}.${this._ext}`), {
...opts,
pluginName: this.pjson.name,
commandName: sfdxExampleCommand,
topicName: topic
})
}
this.fs.copyTpl(this.templatePath('sfdxPlugin/src/index.ts'), this.destinationPath('src/index.ts'), opts)
if (this.mocha && !fs.existsSync('test')) {
this.fs.copyTpl(this.templatePath(`sfdxPlugin/test/command.test.${this._ext}.ejs`), this.destinationPath(`test/commands/${topic}/${sfdxExampleCommand}.test.${this._ext}`),
{...opts, name: sfdxExampleCommand, topic})
}

if (!fs.existsSync('messages/messages.json')) {
this.fs.copyTpl(this.templatePath('messages/messages.json'), this.destinationPath(`messages/${sfdxExampleCommand}.json`), this)
}

if (!fs.existsSync('.vscode/launch.json')) {
this.fs.copyTpl(this.templatePath('.vscode/launch.json'), this.destinationPath(`.vscode/launch.json`), this)
}
}

private _writeSingle() {
const bin = this._bin
const opts = {...this as any, _, bin, cmd: bin, name: this.pjson.name}
Expand Down
Binary file added templates/.images/vscodeScreenshot.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions templates/.vscode/launch.json
@@ -0,0 +1,16 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "attach",
"name": "Attach to Remote",
"address": "127.0.0.1",
"port": 9229,
"localRoot": "${workspaceFolder}"
}
]
}
4 changes: 4 additions & 0 deletions templates/messages/messages.json
@@ -0,0 +1,4 @@
{
"commandDescription": "Prints a greeting and your org id(s)!",
"nameFlagDescription": "name to print"
}

0 comments on commit ea6013a

Please sign in to comment.