oclif 4.9.2 → 4.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/lib/commands/generate.js +63 -73
  2. package/lib/commands/init.js +5 -5
  3. package/oclif.manifest.json +1 -1
  4. package/package.json +3 -3
  5. package/templates/cli/commonjs/.mocharc.json.ejs +11 -0
  6. package/templates/cli/commonjs/bin/dev.cmd.ejs +3 -0
  7. package/templates/cli/commonjs/bin/dev.js.ejs +6 -0
  8. package/templates/cli/commonjs/bin/run.cmd.ejs +3 -0
  9. package/templates/cli/commonjs/bin/run.js.ejs +7 -0
  10. package/templates/cli/commonjs/tsconfig.json.ejs +11 -0
  11. package/templates/cli/esm/.mocharc.json.ejs +15 -0
  12. package/templates/cli/esm/bin/dev.cmd.ejs +3 -0
  13. package/templates/cli/esm/bin/dev.js.ejs +6 -0
  14. package/templates/cli/esm/bin/run.cmd.ejs +3 -0
  15. package/templates/cli/esm/bin/run.js.ejs +5 -0
  16. package/templates/cli/esm/tsconfig.json.ejs +15 -0
  17. package/templates/cli/shared/.eslintignore.ejs +1 -0
  18. package/templates/cli/shared/.eslintrc.json.ejs +3 -0
  19. package/templates/cli/shared/.github/workflows/onPushToMain.yml.ejs +56 -0
  20. package/templates/cli/shared/.github/workflows/onRelease.yml.ejs +18 -0
  21. package/templates/cli/shared/.github/workflows/test.yml.ejs +23 -0
  22. package/templates/cli/shared/.gitignore.ejs +27 -0
  23. package/templates/cli/shared/.prettierrc.json.ejs +1 -0
  24. package/templates/cli/shared/.vscode/launch.json.ejs +20 -0
  25. package/templates/cli/shared/README.md.ejs +396 -0
  26. package/templates/cli/shared/package.json.ejs +73 -0
  27. package/templates/cli/shared/src/commands/hello/index.ts.ejs +25 -0
  28. package/templates/cli/shared/src/commands/hello/world.ts.ejs +19 -0
  29. package/templates/cli/shared/src/index.ts.ejs +1 -0
  30. package/templates/cli/shared/test/commands/hello/index.test.ts.ejs +10 -0
  31. package/templates/cli/shared/test/commands/hello/world.test.ts.ejs +10 -0
  32. package/templates/cli/shared/test/tsconfig.json.ejs +9 -0
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  /* eslint-disable unicorn/no-await-expression-member */
7
7
  const core_1 = require("@oclif/core");
8
8
  const chalk_1 = __importDefault(require("chalk"));
9
+ const node_fs_1 = require("node:fs");
9
10
  const promises_1 = require("node:fs/promises");
10
11
  const node_path_1 = require("node:path");
11
12
  const validate_npm_package_name_1 = __importDefault(require("validate-npm-package-name"));
@@ -46,17 +47,6 @@ function determineDefaultAuthor(user, defaultValue) {
46
47
  return `@${login}`;
47
48
  return defaultValue;
48
49
  }
49
- async function clone(repo, location) {
50
- try {
51
- await (0, generator_1.exec)(`git clone https://github.com/oclif/${repo}.git "${location}" --depth=1`);
52
- }
53
- catch (error) {
54
- const err = error instanceof Error
55
- ? new core_1.Errors.CLIError(error)
56
- : new core_1.Errors.CLIError('An error occurred while cloning the template repo');
57
- throw err;
58
- }
59
- }
60
50
  const FLAGGABLE_PROMPTS = {
61
51
  author: {
62
52
  message: 'Author',
@@ -137,41 +127,39 @@ class Generate extends generator_1.GeneratorCommand {
137
127
  async run() {
138
128
  const location = this.flags['output-dir'] ? (0, node_path_1.join)(this.flags['output-dir'], this.args.name) : (0, node_path_1.resolve)(this.args.name);
139
129
  this.log(`Generating ${this.args.name} in ${chalk_1.default.green(location)}`);
130
+ if ((0, node_fs_1.existsSync)(location)) {
131
+ throw new core_1.Errors.CLIError(`The directory ${location} already exists.`);
132
+ }
140
133
  const moduleType = await this.getFlagOrPrompt({
141
134
  defaultValue: 'ESM',
142
135
  name: 'module-type',
143
136
  type: 'select',
144
137
  });
145
- const template = moduleType === 'ESM' ? 'hello-world-esm' : 'hello-world';
146
- await clone(template, location);
147
- await (0, promises_1.rm)((0, node_path_1.join)(location, '.git'), { force: true, recursive: true });
148
- // We just cloned the template repo so we're sure it has a package.json
149
- const packageJSON = (await (0, generator_1.readPJSON)(location));
150
138
  const githubUser = await fetchGithubUser();
151
139
  const name = await this.getFlagOrPrompt({ defaultValue: this.args.name, name: 'name', type: 'input' });
152
140
  const bin = await this.getFlagOrPrompt({ defaultValue: name, name: 'bin', type: 'input' });
153
141
  const description = await this.getFlagOrPrompt({
154
- defaultValue: packageJSON.description,
142
+ defaultValue: 'A new CLI generated with oclif',
155
143
  name: 'description',
156
144
  type: 'input',
157
145
  });
158
146
  const author = await this.getFlagOrPrompt({
159
- defaultValue: determineDefaultAuthor(githubUser, packageJSON.author),
147
+ defaultValue: determineDefaultAuthor(githubUser, 'Your Name Here'),
160
148
  name: 'author',
161
149
  type: 'input',
162
150
  });
163
151
  const license = await this.getFlagOrPrompt({
164
- defaultValue: packageJSON.license,
152
+ defaultValue: 'MIT',
165
153
  name: 'license',
166
154
  type: 'input',
167
155
  });
168
156
  const owner = await this.getFlagOrPrompt({
169
- defaultValue: githubUser?.login ?? location.split(node_path_1.sep).at(-2) ?? packageJSON.author,
157
+ defaultValue: githubUser?.login ?? location.split(node_path_1.sep).at(-2) ?? 'Your Name Here',
170
158
  name: 'owner',
171
159
  type: 'input',
172
160
  });
173
161
  const repository = await this.getFlagOrPrompt({
174
- defaultValue: (name ?? packageJSON.repository ?? packageJSON.name).split('/').at(-1) ?? name,
162
+ defaultValue: name.split('/').at(-1) ?? name,
175
163
  name: 'repository',
176
164
  type: 'input',
177
165
  });
@@ -180,58 +168,53 @@ class Generate extends generator_1.GeneratorCommand {
180
168
  name: 'package-manager',
181
169
  type: 'select',
182
170
  });
183
- const updatedPackageJSON = {
184
- ...packageJSON,
185
- author,
186
- bin: { [bin]: './bin/run.js' },
187
- bugs: `https://github.com/${owner}/${repository}/issues`,
188
- description,
189
- homepage: `https://github.com/${owner}/${repository}`,
190
- license,
191
- name,
192
- oclif: {
193
- ...packageJSON.oclif,
194
- bin,
195
- dirname: bin,
196
- },
197
- repository: `${owner}/${repository}`,
198
- version: '0.0.0',
199
- };
200
- if (packageManager !== 'yarn') {
201
- const scripts = (updatedPackageJSON.scripts || {});
202
- updatedPackageJSON.scripts = Object.fromEntries(Object.entries(scripts).map(([k, v]) => [k, v.replace('yarn', `${packageManager} run`)]));
203
- }
204
- const { default: sortPackageJson } = await import('sort-package-json');
205
- await (0, promises_1.writeFile)((0, node_path_1.join)(location, 'package.json'), JSON.stringify(sortPackageJson(updatedPackageJSON), null, 2));
206
- await (0, promises_1.rm)((0, node_path_1.join)(location, 'LICENSE'));
207
- await (0, promises_1.rm)((0, node_path_1.join)(location, '.github', 'workflows', 'automerge.yml'));
208
- const existing = (await (0, promises_1.readFile)((0, node_path_1.join)(location, '.gitignore'), 'utf8')).split('\n');
209
- const updated = (0, util_1.uniq)((0, util_1.compact)([
210
- '*-debug.log',
211
- '*-error.log',
212
- 'node_modules',
213
- '/tmp',
214
- '/dist',
215
- '/lib',
216
- ...(packageManager === 'yarn'
217
- ? [
218
- '/package-lock.json',
219
- '.pnp.*',
220
- '.yarn/*',
221
- '!.yarn/patches',
222
- '!.yarn/plugins',
223
- '!.yarn/releases',
224
- '!.yarn/sdks',
225
- '!.yarn/versions',
226
- ]
227
- : ['/yarn.lock']),
228
- ...existing,
229
- ]))
230
- .sort()
231
- .join('\n') + '\n';
232
- await (0, promises_1.writeFile)((0, node_path_1.join)(location, '.gitignore'), updated);
233
- if (packageManager !== 'yarn') {
234
- await (0, promises_1.rm)((0, node_path_1.join)(location, 'yarn.lock'));
171
+ const [sharedFiles, moduleSpecificFiles] = await Promise.all(['shared', moduleType.toLowerCase()].map((f) => (0, node_path_1.join)(this.templatesDir, 'cli', f)).map(findEjsFiles(location)));
172
+ await Promise.all([...sharedFiles, ...moduleSpecificFiles].map(async (file) => {
173
+ switch (file.name) {
174
+ case 'package.json.ejs': {
175
+ const data = {
176
+ author,
177
+ bin,
178
+ description,
179
+ license,
180
+ moduleType,
181
+ name,
182
+ owner,
183
+ pkgManagerScript: packageManager === 'yarn' ? 'yarn' : `${packageManager} run`,
184
+ repository,
185
+ };
186
+ await this.template(file.src, file.destination, data);
187
+ break;
188
+ }
189
+ case '.gitignore.ejs': {
190
+ await this.template(file.src, file.destination, { packageManager });
191
+ break;
192
+ }
193
+ case 'README.md.ejs': {
194
+ await this.template(file.src, file.destination, { description, name, repository });
195
+ break;
196
+ }
197
+ case 'onPushToMain.yml.ejs':
198
+ case 'onRelease.yml.ejs':
199
+ case 'test.yml.ejs': {
200
+ await this.template(file.src, file.destination, {
201
+ exec: packageManager === 'yarn' ? packageManager : `${packageManager} exec`,
202
+ install: packageManager === 'yarn' ? packageManager : `${packageManager} install`,
203
+ packageManager,
204
+ run: packageManager === 'yarn' ? packageManager : `${packageManager} run`,
205
+ });
206
+ break;
207
+ }
208
+ default: {
209
+ await this.template(file.src, file.destination);
210
+ }
211
+ }
212
+ }));
213
+ if (process.platform !== 'win32') {
214
+ await Promise.all([
215
+ (0, generator_1.exec)(`chmod +x ${(0, node_path_1.join)(location, 'bin', 'run.js')}`),
216
+ (0, generator_1.exec)(`chmod +x ${(0, node_path_1.join)(location, 'bin', 'dev.js')}`),
217
+ ]);
235
218
  }
236
219
  await (0, generator_1.exec)(`${packageManager} install`, { cwd: location, silent: false });
237
220
  await (0, generator_1.exec)(`${packageManager} run build`, { cwd: location, silent: false });
@@ -248,3 +231,10 @@ class Generate extends generator_1.GeneratorCommand {
248
231
  }
249
232
  }
250
233
  exports.default = Generate;
234
+ const findEjsFiles = (location) => async (dir) => (await (0, promises_1.readdir)(dir, { recursive: true, withFileTypes: true }))
235
+ .filter((f) => f.isFile() && f.name.endsWith('.ejs'))
236
+ .map((f) => ({
237
+ destination: (0, node_path_1.join)(f.path.replace(dir, location), f.name.replace('.ejs', '')),
238
+ name: f.name,
239
+ src: (0, node_path_1.join)(f.path, f.name),
240
+ }));
@@ -114,12 +114,12 @@ class Generate extends generator_1.GeneratorCommand {
114
114
  });
115
115
  this.log(`Using module type ${chalk_1.default.green(moduleType)}`);
116
116
  this.log(`Using package manager ${chalk_1.default.green(packageManager)}`);
117
- const templateOptions = { moduleType };
118
117
  const projectBinPath = (0, node_path_1.join)(location, 'bin');
119
- await this.template((0, node_path_1.join)(this.templatesDir, 'src', 'init', 'dev.cmd.ejs'), (0, node_path_1.join)(projectBinPath, 'dev.cmd'), templateOptions);
120
- await this.template((0, node_path_1.join)(this.templatesDir, 'src', 'init', 'dev.js.ejs'), (0, node_path_1.join)(projectBinPath, 'dev.js'), templateOptions);
121
- await this.template((0, node_path_1.join)(this.templatesDir, 'src', 'init', 'run.cmd.ejs'), (0, node_path_1.join)(projectBinPath, 'run.cmd'), templateOptions);
122
- await this.template((0, node_path_1.join)(this.templatesDir, 'src', 'init', 'run.js.ejs'), (0, node_path_1.join)(projectBinPath, 'run.js'), templateOptions);
118
+ const templateBinPath = (0, node_path_1.join)(this.templatesDir, 'cli', moduleType.toLowerCase(), 'bin');
119
+ await this.template((0, node_path_1.join)(templateBinPath, 'dev.cmd.ejs'), (0, node_path_1.join)(projectBinPath, 'dev.cmd'));
120
+ await this.template((0, node_path_1.join)(templateBinPath, 'dev.js.ejs'), (0, node_path_1.join)(projectBinPath, 'dev.js'));
121
+ await this.template((0, node_path_1.join)(templateBinPath, 'run.cmd.ejs'), (0, node_path_1.join)(projectBinPath, 'run.cmd'));
122
+ await this.template((0, node_path_1.join)(templateBinPath, 'run.js.ejs'), (0, node_path_1.join)(projectBinPath, 'run.js'));
123
123
  if (process.platform !== 'win32') {
124
124
  await (0, generator_1.exec)(`chmod +x "${(0, node_path_1.join)(projectBinPath, 'run.js')}"`);
125
125
  await (0, generator_1.exec)(`chmod +x "${(0, node_path_1.join)(projectBinPath, 'dev.js')}"`);
@@ -1074,5 +1074,5 @@
1074
1074
  ]
1075
1075
  }
1076
1076
  },
1077
- "version": "4.9.2"
1077
+ "version": "4.10.0"
1078
1078
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "oclif",
3
3
  "description": "oclif: create your own CLI",
4
- "version": "4.9.2",
4
+ "version": "4.10.0",
5
5
  "author": "Salesforce",
6
6
  "bin": {
7
7
  "oclif": "bin/run.js"
@@ -12,7 +12,7 @@
12
12
  "@aws-sdk/client-s3": "^3.565.0",
13
13
  "@inquirer/confirm": "^3.1.6",
14
14
  "@inquirer/input": "^2.1.1",
15
- "@inquirer/select": "^2.2.1",
15
+ "@inquirer/select": "^2.3.2",
16
16
  "@oclif/core": "^3.26.4",
17
17
  "@oclif/plugin-help": "^6.0.21",
18
18
  "@oclif/plugin-not-found": "^3.0.14",
@@ -55,7 +55,7 @@
55
55
  "eslint-config-oclif": "^5.1.1",
56
56
  "eslint-config-oclif-typescript": "^3.1.5",
57
57
  "eslint-config-prettier": "^9.0.0",
58
- "eslint-plugin-perfectionist": "^2.6.0",
58
+ "eslint-plugin-perfectionist": "^2.10.0",
59
59
  "husky": "^9",
60
60
  "lint-staged": "^15",
61
61
  "lodash.clonedeep": "^4.5.0",
@@ -0,0 +1,11 @@
1
+ {
2
+ "require": [
3
+ "ts-node/register"
4
+ ],
5
+ "watch-extensions": [
6
+ "ts"
7
+ ],
8
+ "recursive": true,
9
+ "reporter": "spec",
10
+ "timeout": 60000
11
+ }
@@ -0,0 +1,3 @@
1
+ @echo off
2
+
3
+ node "%~dp0\dev" %*
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node_modules/.bin/ts-node
2
+ // eslint-disable-next-line node/shebang, unicorn/prefer-top-level-await
3
+ ;(async () => {
4
+ const oclif = await import('@oclif/core')
5
+ await oclif.execute({development: true, dir: __dirname})
6
+ })()
@@ -0,0 +1,3 @@
1
+ @echo off
2
+
3
+ node "%~dp0\run" %*
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+
3
+ // eslint-disable-next-line unicorn/prefer-top-level-await
4
+ (async () => {
5
+ const oclif = await import('@oclif/core')
6
+ await oclif.execute({dir: __dirname})
7
+ })()
@@ -0,0 +1,11 @@
1
+ {
2
+ "compilerOptions": {
3
+ "declaration": true,
4
+ "module": "commonjs",
5
+ "outDir": "dist",
6
+ "rootDir": "src",
7
+ "strict": true,
8
+ "target": "es2022"
9
+ },
10
+ "include": ["src/**/*"]
11
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "require": [
3
+ "ts-node/register"
4
+ ],
5
+ "watch-extensions": [
6
+ "ts"
7
+ ],
8
+ "recursive": true,
9
+ "reporter": "spec",
10
+ "timeout": 60000,
11
+ "node-option": [
12
+ "loader=ts-node/esm",
13
+ "experimental-specifier-resolution=node"
14
+ ]
15
+ }
@@ -0,0 +1,3 @@
1
+ @echo off
2
+
3
+ node --loader ts-node/esm --no-warnings=ExperimentalWarning "%~dp0\dev" %*
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env -S node --loader ts-node/esm --no-warnings=ExperimentalWarning
2
+
3
+ // eslint-disable-next-line n/shebang
4
+ import {execute} from '@oclif/core'
5
+
6
+ await execute({development: true, dir: import.meta.url})
@@ -0,0 +1,3 @@
1
+ @echo off
2
+
3
+ node "%~dp0\run" %*
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {execute} from '@oclif/core'
4
+
5
+ await execute({dir: import.meta.url})
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "declaration": true,
4
+ "module": "Node16",
5
+ "outDir": "dist",
6
+ "rootDir": "src",
7
+ "strict": true,
8
+ "target": "es2022",
9
+ "moduleResolution": "node16"
10
+ },
11
+ "include": ["./src/**/*"],
12
+ "ts-node": {
13
+ "esm": true
14
+ }
15
+ }
@@ -0,0 +1 @@
1
+ /dist
@@ -0,0 +1,3 @@
1
+ {
2
+ "extends": ["oclif", "oclif-typescript", "prettier"]
3
+ }
@@ -0,0 +1,56 @@
1
+ # test
2
+ name: version, tag and github release
3
+
4
+ on:
5
+ push:
6
+ branches: [main]
7
+
8
+ jobs:
9
+ release:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ - uses: actions/setup-node@v4
14
+ - name: Check if version already exists
15
+ id: version-check
16
+ run: |
17
+ package_version=$(node -p "require('./package.json').version")
18
+ exists=$(gh api repos/${{ github.repository }}/releases/tags/v$package_version >/dev/null 2>&1 && echo "true" || echo "")
19
+
20
+ if [ -n "$exists" ];
21
+ then
22
+ echo "Version v$package_version already exists"
23
+ echo "::warning file=package.json,line=1::Version v$package_version already exists - no release will be created. If you want to create a new release, please update the version in package.json and push again."
24
+ echo "skipped=true" >> $GITHUB_OUTPUT
25
+ else
26
+ echo "Version v$package_version does not exist. Creating release..."
27
+ echo "skipped=false" >> $GITHUB_OUTPUT
28
+ echo "tag=v$package_version" >> $GITHUB_OUTPUT
29
+ fi
30
+ env:
31
+ GH_TOKEN: ${{ secrets.GH_TOKEN }}
32
+ - name: Setup git
33
+ if: ${{ steps.version-check.outputs.skipped == 'false' }}
34
+ run: |
35
+ git config --global user.email ${{ secrets.GH_EMAIL }}
36
+ git config --global user.name ${{ secrets.GH_USERNAME }}
37
+ - name: Generate oclif README
38
+ if: ${{ steps.version-check.outputs.skipped == 'false' }}
39
+ id: oclif-readme
40
+ run: |
41
+ <%- install %>
42
+ <%- exec %> oclif readme
43
+ if [ -n "$(git status --porcelain)" ]; then
44
+ git add .
45
+ git commit -am "chore: update README.md"
46
+ git push -u origin ${{ github.ref_name }}
47
+ fi
48
+ - name: Create Github Release
49
+ uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5
50
+ if: ${{ steps.version-check.outputs.skipped == 'false' }}
51
+ with:
52
+ name: ${{ steps.version-check.outputs.tag }}
53
+ tag: ${{ steps.version-check.outputs.tag }}
54
+ commit: ${{ github.ref_name }}
55
+ token: ${{ secrets.GH_TOKEN }}
56
+ skipIfReleaseExists: true
@@ -0,0 +1,18 @@
1
+ name: publish
2
+
3
+ on:
4
+ release:
5
+ types: [released]
6
+
7
+ jobs:
8
+ publish:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ - uses: actions/setup-node@v4
13
+ with:
14
+ node-version: latest
15
+ - run: <%- install %>
16
+ - uses: JS-DevTools/npm-publish@19c28f1ef146469e409470805ea4279d47c3d35c
17
+ with:
18
+ token: ${{ secrets.NPM_TOKEN }}
@@ -0,0 +1,23 @@
1
+ name: tests
2
+ on:
3
+ push:
4
+ branches-ignore: [main]
5
+ workflow_dispatch:
6
+
7
+ jobs:
8
+ unit-tests:
9
+ strategy:
10
+ matrix:
11
+ os: ['ubuntu-latest', 'windows-latest']
12
+ node_version: [lts/-1, lts/*, latest]
13
+ fail-fast: false
14
+ runs-on: ${{ matrix.os }}
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: actions/setup-node@v4
18
+ with:
19
+ node-version: ${{ matrix.node_version }}
20
+ cache: <%- packageManager %>
21
+ - run: <%- install %>
22
+ - run: <%- run %> build
23
+ - run: <%- run %> test
@@ -0,0 +1,27 @@
1
+ *-debug.log
2
+ *-error.log
3
+ **/.DS_Store
4
+ /.idea
5
+ /dist
6
+ /tmp
7
+ /node_modules
8
+ oclif.manifest.json
9
+ <% if (packageManager === 'yarn') { %>
10
+ package-lock.json
11
+ pnpm-lock.yaml
12
+ .pnp.*
13
+ .yarn/*
14
+ !.yarn/patches
15
+ !.yarn/plugins
16
+ !.yarn/releases
17
+ !.yarn/sdks
18
+ !.yarn/versions
19
+ <% } %>
20
+ <% if (packageManager === 'pnpm') { %>
21
+ yarn.lock
22
+ package-lock.json
23
+ <% } %>
24
+ <% if (packageManager === 'npm') { %>
25
+ yarn.lock
26
+ pnpm-lock.yaml
27
+ <% } %>
@@ -0,0 +1 @@
1
+ "@oclif/prettier-config"
@@ -0,0 +1,20 @@
1
+ {
2
+ "version": "0.2.0",
3
+ "configurations": [
4
+ {
5
+ "type": "node",
6
+ "request": "attach",
7
+ "name": "Attach",
8
+ "port": 9229,
9
+ "skipFiles": ["<node_internals>/**"]
10
+ },
11
+ {
12
+ "type": "node",
13
+ "request": "launch",
14
+ "name": "Execute Command",
15
+ "skipFiles": ["<node_internals>/**"],
16
+ "program": "${workspaceFolder}/bin/dev",
17
+ "args": ["hello", "world"]
18
+ }
19
+ ]
20
+ }
@@ -0,0 +1,396 @@
1
+ <%- name %>
2
+ =================
3
+
4
+ <%- description %>
5
+
6
+
7
+ [![oclif](https://img.shields.io/badge/cli-oclif-brightgreen.svg)](https://oclif.io)
8
+ [![Version](https://img.shields.io/npm/v/<%- name %>.svg)](https://npmjs.org/package/<%- name %>)
9
+ [![Downloads/week](https://img.shields.io/npm/dw/<%- name %>.svg)](https://npmjs.org/package/<%- name %>)
10
+
11
+
12
+ <!-- toc -->
13
+ * [Usage](#usage)
14
+ * [Commands](#commands)
15
+ <!-- tocstop -->
16
+ # Usage
17
+ <!-- usage -->
18
+ ```sh-session
19
+ $ npm install -g mycli123
20
+ $ mycli123 COMMAND
21
+ running command...
22
+ $ mycli123 (--version)
23
+ mycli123/0.0.0 darwin-arm64 node-v20.12.2
24
+ $ mycli123 --help [COMMAND]
25
+ USAGE
26
+ $ mycli123 COMMAND
27
+ ...
28
+ ```
29
+ <!-- usagestop -->
30
+ # Commands
31
+ <!-- commands -->
32
+ * [`mycli123 hello PERSON`](#mycli123-hello-person)
33
+ * [`mycli123 hello world`](#mycli123-hello-world)
34
+ * [`mycli123 help [COMMAND]`](#mycli123-help-command)
35
+ * [`mycli123 plugins`](#mycli123-plugins)
36
+ * [`mycli123 plugins add PLUGIN`](#mycli123-plugins-add-plugin)
37
+ * [`mycli123 plugins:inspect PLUGIN...`](#mycli123-pluginsinspect-plugin)
38
+ * [`mycli123 plugins install PLUGIN`](#mycli123-plugins-install-plugin)
39
+ * [`mycli123 plugins link PATH`](#mycli123-plugins-link-path)
40
+ * [`mycli123 plugins remove [PLUGIN]`](#mycli123-plugins-remove-plugin)
41
+ * [`mycli123 plugins reset`](#mycli123-plugins-reset)
42
+ * [`mycli123 plugins uninstall [PLUGIN]`](#mycli123-plugins-uninstall-plugin)
43
+ * [`mycli123 plugins unlink [PLUGIN]`](#mycli123-plugins-unlink-plugin)
44
+ * [`mycli123 plugins update`](#mycli123-plugins-update)
45
+
46
+ ## `mycli123 hello PERSON`
47
+
48
+ Say hello
49
+
50
+ ```
51
+ USAGE
52
+ $ mycli123 hello PERSON -f <value>
53
+
54
+ ARGUMENTS
55
+ PERSON Person to say hello to
56
+
57
+ FLAGS
58
+ -f, --from=<value> (required) Who is saying hello
59
+
60
+ DESCRIPTION
61
+ Say hello
62
+
63
+ EXAMPLES
64
+ $ mycli123 hello friend --from oclif
65
+ hello friend from oclif! (./src/commands/hello/index.ts)
66
+ ```
67
+
68
+ _See code: [src/commands/hello/index.ts](https://github.com/mdonnalley/mycli123/blob/v0.0.0/src/commands/hello/index.ts)_
69
+
70
+ ## `mycli123 hello world`
71
+
72
+ Say hello world
73
+
74
+ ```
75
+ USAGE
76
+ $ mycli123 hello world
77
+
78
+ DESCRIPTION
79
+ Say hello world
80
+
81
+ EXAMPLES
82
+ $ mycli123 hello world
83
+ hello world! (./src/commands/hello/world.ts)
84
+ ```
85
+
86
+ _See code: [src/commands/hello/world.ts](https://github.com/mdonnalley/mycli123/blob/v0.0.0/src/commands/hello/world.ts)_
87
+
88
+ ## `mycli123 help [COMMAND]`
89
+
90
+ Display help for mycli123.
91
+
92
+ ```
93
+ USAGE
94
+ $ mycli123 help [COMMAND...] [-n]
95
+
96
+ ARGUMENTS
97
+ COMMAND... Command to show help for.
98
+
99
+ FLAGS
100
+ -n, --nested-commands Include all nested commands in the output.
101
+
102
+ DESCRIPTION
103
+ Display help for mycli123.
104
+ ```
105
+
106
+ _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v6.0.21/src/commands/help.ts)_
107
+
108
+ ## `mycli123 plugins`
109
+
110
+ List installed plugins.
111
+
112
+ ```
113
+ USAGE
114
+ $ mycli123 plugins [--json] [--core]
115
+
116
+ FLAGS
117
+ --core Show core plugins.
118
+
119
+ GLOBAL FLAGS
120
+ --json Format output as json.
121
+
122
+ DESCRIPTION
123
+ List installed plugins.
124
+
125
+ EXAMPLES
126
+ $ mycli123 plugins
127
+ ```
128
+
129
+ _See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.16/src/commands/plugins/index.ts)_
130
+
131
+ ## `mycli123 plugins add PLUGIN`
132
+
133
+ Installs a plugin into mycli123.
134
+
135
+ ```
136
+ USAGE
137
+ $ mycli123 plugins add PLUGIN... [--json] [-f] [-h] [-s | -v]
138
+
139
+ ARGUMENTS
140
+ PLUGIN... Plugin to install.
141
+
142
+ FLAGS
143
+ -f, --force Force npm to fetch remote resources even if a local copy exists on disk.
144
+ -h, --help Show CLI help.
145
+ -s, --silent Silences npm output.
146
+ -v, --verbose Show verbose npm output.
147
+
148
+ GLOBAL FLAGS
149
+ --json Format output as json.
150
+
151
+ DESCRIPTION
152
+ Installs a plugin into mycli123.
153
+
154
+ Uses bundled npm executable to install plugins into /Users/mdonnalley/.local/share/mycli123
155
+
156
+ Installation of a user-installed plugin will override a core plugin.
157
+
158
+ Use the MYCLI123_NPM_LOG_LEVEL environment variable to set the npm loglevel.
159
+ Use the MYCLI123_NPM_REGISTRY environment variable to set the npm registry.
160
+
161
+ ALIASES
162
+ $ mycli123 plugins add
163
+
164
+ EXAMPLES
165
+ Install a plugin from npm registry.
166
+
167
+ $ mycli123 plugins add myplugin
168
+
169
+ Install a plugin from a github url.
170
+
171
+ $ mycli123 plugins add https://github.com/someuser/someplugin
172
+
173
+ Install a plugin from a github slug.
174
+
175
+ $ mycli123 plugins add someuser/someplugin
176
+ ```
177
+
178
+ ## `mycli123 plugins:inspect PLUGIN...`
179
+
180
+ Displays installation properties of a plugin.
181
+
182
+ ```
183
+ USAGE
184
+ $ mycli123 plugins inspect PLUGIN...
185
+
186
+ ARGUMENTS
187
+ PLUGIN... [default: .] Plugin to inspect.
188
+
189
+ FLAGS
190
+ -h, --help Show CLI help.
191
+ -v, --verbose
192
+
193
+ GLOBAL FLAGS
194
+ --json Format output as json.
195
+
196
+ DESCRIPTION
197
+ Displays installation properties of a plugin.
198
+
199
+ EXAMPLES
200
+ $ mycli123 plugins inspect myplugin
201
+ ```
202
+
203
+ _See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.16/src/commands/plugins/inspect.ts)_
204
+
205
+ ## `mycli123 plugins install PLUGIN`
206
+
207
+ Installs a plugin into mycli123.
208
+
209
+ ```
210
+ USAGE
211
+ $ mycli123 plugins install PLUGIN... [--json] [-f] [-h] [-s | -v]
212
+
213
+ ARGUMENTS
214
+ PLUGIN... Plugin to install.
215
+
216
+ FLAGS
217
+ -f, --force Force npm to fetch remote resources even if a local copy exists on disk.
218
+ -h, --help Show CLI help.
219
+ -s, --silent Silences npm output.
220
+ -v, --verbose Show verbose npm output.
221
+
222
+ GLOBAL FLAGS
223
+ --json Format output as json.
224
+
225
+ DESCRIPTION
226
+ Installs a plugin into mycli123.
227
+
228
+ Uses bundled npm executable to install plugins into /Users/mdonnalley/.local/share/mycli123
229
+
230
+ Installation of a user-installed plugin will override a core plugin.
231
+
232
+ Use the MYCLI123_NPM_LOG_LEVEL environment variable to set the npm loglevel.
233
+ Use the MYCLI123_NPM_REGISTRY environment variable to set the npm registry.
234
+
235
+ ALIASES
236
+ $ mycli123 plugins add
237
+
238
+ EXAMPLES
239
+ Install a plugin from npm registry.
240
+
241
+ $ mycli123 plugins install myplugin
242
+
243
+ Install a plugin from a github url.
244
+
245
+ $ mycli123 plugins install https://github.com/someuser/someplugin
246
+
247
+ Install a plugin from a github slug.
248
+
249
+ $ mycli123 plugins install someuser/someplugin
250
+ ```
251
+
252
+ _See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.16/src/commands/plugins/install.ts)_
253
+
254
+ ## `mycli123 plugins link PATH`
255
+
256
+ Links a plugin into the CLI for development.
257
+
258
+ ```
259
+ USAGE
260
+ $ mycli123 plugins link PATH [-h] [--install] [-v]
261
+
262
+ ARGUMENTS
263
+ PATH [default: .] path to plugin
264
+
265
+ FLAGS
266
+ -h, --help Show CLI help.
267
+ -v, --verbose
268
+ --[no-]install Install dependencies after linking the plugin.
269
+
270
+ DESCRIPTION
271
+ Links a plugin into the CLI for development.
272
+ Installation of a linked plugin will override a user-installed or core plugin.
273
+
274
+ e.g. If you have a user-installed or core plugin that has a 'hello' command, installing a linked plugin with a 'hello'
275
+ command will override the user-installed or core plugin implementation. This is useful for development work.
276
+
277
+
278
+ EXAMPLES
279
+ $ mycli123 plugins link myplugin
280
+ ```
281
+
282
+ _See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.16/src/commands/plugins/link.ts)_
283
+
284
+ ## `mycli123 plugins remove [PLUGIN]`
285
+
286
+ Removes a plugin from the CLI.
287
+
288
+ ```
289
+ USAGE
290
+ $ mycli123 plugins remove [PLUGIN...] [-h] [-v]
291
+
292
+ ARGUMENTS
293
+ PLUGIN... plugin to uninstall
294
+
295
+ FLAGS
296
+ -h, --help Show CLI help.
297
+ -v, --verbose
298
+
299
+ DESCRIPTION
300
+ Removes a plugin from the CLI.
301
+
302
+ ALIASES
303
+ $ mycli123 plugins unlink
304
+ $ mycli123 plugins remove
305
+
306
+ EXAMPLES
307
+ $ mycli123 plugins remove myplugin
308
+ ```
309
+
310
+ ## `mycli123 plugins reset`
311
+
312
+ Remove all user-installed and linked plugins.
313
+
314
+ ```
315
+ USAGE
316
+ $ mycli123 plugins reset [--hard] [--reinstall]
317
+
318
+ FLAGS
319
+ --hard Delete node_modules and package manager related files in addition to uninstalling plugins.
320
+ --reinstall Reinstall all plugins after uninstalling.
321
+ ```
322
+
323
+ _See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.16/src/commands/plugins/reset.ts)_
324
+
325
+ ## `mycli123 plugins uninstall [PLUGIN]`
326
+
327
+ Removes a plugin from the CLI.
328
+
329
+ ```
330
+ USAGE
331
+ $ mycli123 plugins uninstall [PLUGIN...] [-h] [-v]
332
+
333
+ ARGUMENTS
334
+ PLUGIN... plugin to uninstall
335
+
336
+ FLAGS
337
+ -h, --help Show CLI help.
338
+ -v, --verbose
339
+
340
+ DESCRIPTION
341
+ Removes a plugin from the CLI.
342
+
343
+ ALIASES
344
+ $ mycli123 plugins unlink
345
+ $ mycli123 plugins remove
346
+
347
+ EXAMPLES
348
+ $ mycli123 plugins uninstall myplugin
349
+ ```
350
+
351
+ _See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.16/src/commands/plugins/uninstall.ts)_
352
+
353
+ ## `mycli123 plugins unlink [PLUGIN]`
354
+
355
+ Removes a plugin from the CLI.
356
+
357
+ ```
358
+ USAGE
359
+ $ mycli123 plugins unlink [PLUGIN...] [-h] [-v]
360
+
361
+ ARGUMENTS
362
+ PLUGIN... plugin to uninstall
363
+
364
+ FLAGS
365
+ -h, --help Show CLI help.
366
+ -v, --verbose
367
+
368
+ DESCRIPTION
369
+ Removes a plugin from the CLI.
370
+
371
+ ALIASES
372
+ $ mycli123 plugins unlink
373
+ $ mycli123 plugins remove
374
+
375
+ EXAMPLES
376
+ $ mycli123 plugins unlink myplugin
377
+ ```
378
+
379
+ ## `mycli123 plugins update`
380
+
381
+ Update installed plugins.
382
+
383
+ ```
384
+ USAGE
385
+ $ mycli123 plugins update [-h] [-v]
386
+
387
+ FLAGS
388
+ -h, --help Show CLI help.
389
+ -v, --verbose
390
+
391
+ DESCRIPTION
392
+ Update installed plugins.
393
+ ```
394
+
395
+ _See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.16/src/commands/plugins/update.ts)_
396
+ <!-- commandsstop -->
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "<%- name %>",
3
+ "description": "<%- description %>",
4
+ "version": "0.0.0",
5
+ "author": "<%- author %>",
6
+ "bin": {
7
+ "<%- bin %>": "./bin/run.js"
8
+ },
9
+ "bugs": "https://github.com/<%- owner %>/<%- repository %>/issues",
10
+ "dependencies": {
11
+ "@oclif/core": "^3",
12
+ "@oclif/plugin-help": "^6",
13
+ "@oclif/plugin-plugins": "^5"
14
+ },
15
+ "devDependencies": {
16
+ "@oclif/prettier-config": "^0.2.1",
17
+ "@oclif/test": "^3",
18
+ "@types/chai": "^4",
19
+ "@types/mocha": "^10",
20
+ "@types/node": "^18",
21
+ "chai": "^4",
22
+ "eslint": "^8",
23
+ "eslint-config-oclif": "^5",
24
+ "eslint-config-oclif-typescript": "^3",
25
+ "eslint-config-prettier": "^9",
26
+ "mocha": "^10",
27
+ "oclif": "^4",
28
+ "shx": "^0.3.3",
29
+ "ts-node": "^10",
30
+ "typescript": "^5"
31
+ },
32
+ "engines": {
33
+ "node": ">=18.0.0"
34
+ },
35
+ "files": [
36
+ "/bin",
37
+ "/dist",
38
+ "/oclif.manifest.json"
39
+ ],
40
+ "homepage": "https://github.com/<%- owner %>/<%- repository %>",
41
+ "keywords": [
42
+ "oclif"
43
+ ],
44
+ "license": "<%- license %>",
45
+ "main": "dist/index.js",
46
+ <% if (moduleType == 'ESM') { %>"type": "module",<% } %>
47
+ "oclif": {
48
+ "bin": "<%- bin %>",
49
+ "dirname": "<%- bin %>",
50
+ "commands": "./dist/commands",
51
+ "plugins": [
52
+ "@oclif/plugin-help",
53
+ "@oclif/plugin-plugins"
54
+ ],
55
+ "topicSeparator": " ",
56
+ "topics": {
57
+ "hello": {
58
+ "description": "Say hello to the world and others"
59
+ }
60
+ }
61
+ },
62
+ "repository": "<%- owner %>/<%- repository %>",
63
+ "scripts": {
64
+ "build": "shx rm -rf dist && tsc -b",
65
+ "lint": "eslint . --ext .ts",
66
+ "postpack": "shx rm -f oclif.manifest.json",
67
+ "posttest": "<%- pkgManagerScript %> lint",
68
+ "prepack": "oclif manifest && oclif readme",
69
+ "test": "mocha --forbid-only \"test/**/*.test.ts\"",
70
+ "version": "oclif readme && git add README.md"
71
+ },
72
+ "types": "dist/index.d.ts"
73
+ }
@@ -0,0 +1,25 @@
1
+ import {Args, Command, Flags} from '@oclif/core'
2
+
3
+ export default class Hello extends Command {
4
+ static args = {
5
+ person: Args.string({description: 'Person to say hello to', required: true}),
6
+ }
7
+
8
+ static description = 'Say hello'
9
+
10
+ static examples = [
11
+ `<%%= config.bin %> <%%= command.id %> friend --from oclif
12
+ hello friend from oclif! (./src/commands/hello/index.ts)
13
+ `,
14
+ ]
15
+
16
+ static flags = {
17
+ from: Flags.string({char: 'f', description: 'Who is saying hello', required: true}),
18
+ }
19
+
20
+ async run(): Promise<void> {
21
+ const {args, flags} = await this.parse(Hello)
22
+
23
+ this.log(`hello ${args.person} from ${flags.from}! (./src/commands/hello/index.ts)`)
24
+ }
25
+ }
@@ -0,0 +1,19 @@
1
+ import {Command} from '@oclif/core'
2
+
3
+ export default class World extends Command {
4
+ static args = {}
5
+
6
+ static description = 'Say hello world'
7
+
8
+ static examples = [
9
+ `<%%= config.bin %> <%%= command.id %>
10
+ hello world! (./src/commands/hello/world.ts)
11
+ `,
12
+ ]
13
+
14
+ static flags = {}
15
+
16
+ async run(): Promise<void> {
17
+ this.log('hello world! (./src/commands/hello/world.ts)')
18
+ }
19
+ }
@@ -0,0 +1 @@
1
+ export {run} from '@oclif/core'
@@ -0,0 +1,10 @@
1
+ import {expect, test} from '@oclif/test'
2
+
3
+ describe('hello', () => {
4
+ test
5
+ .stdout()
6
+ .command(['hello', 'friend', '--from=oclif'])
7
+ .it('runs hello cmd', ctx => {
8
+ expect(ctx.stdout).to.contain('hello friend from oclif!')
9
+ })
10
+ })
@@ -0,0 +1,10 @@
1
+ import {expect, test} from '@oclif/test'
2
+
3
+ describe('hello world', () => {
4
+ test
5
+ .stdout()
6
+ .command(['hello:world'])
7
+ .it('runs hello world cmd', ctx => {
8
+ expect(ctx.stdout).to.contain('hello world!')
9
+ })
10
+ })
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../tsconfig",
3
+ "compilerOptions": {
4
+ "noEmit": true
5
+ },
6
+ "references": [
7
+ {"path": ".."}
8
+ ]
9
+ }