oclif 4.4.21 → 4.5.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.
package/README.md CHANGED
@@ -1,26 +1,26 @@
1
-
2
1
  <img src="https://user-images.githubusercontent.com/449385/38243295-e0a47d58-372e-11e8-9bc0-8c02a6f4d2ac.png" width="260" height="73">
3
2
 
4
-
5
- oclif: Node.JS Open CLI Framework
6
- =================================
3
+ # oclif: Node.JS Open CLI Framework
7
4
 
8
5
  [![Version](https://img.shields.io/npm/v/oclif.svg)](https://npmjs.org/package/oclif)
9
6
  [![Downloads/week](https://img.shields.io/npm/dw/@oclif/command.svg)](https://npmjs.org/package/@oclif/core)
10
7
  [![License](https://img.shields.io/npm/l/oclif.svg)](https://github.com/oclif/oclif/blob/main/package.json)
11
8
 
12
9
  <!-- toc -->
13
- * [🗒 Description](#-description)
14
- * [🚀 Getting Started Tutorial](#-getting-started-tutorial)
15
- * [ Features](#-features)
16
- * [📌 Requirements](#-requirements)
17
- * [📌 Migrating from V1](#-migrating-from-v1)
18
- * [🏗 Usage](#-usage)
19
- * [📚 Examples](#-examples)
20
- * [🔨 Commands](#-commands)
21
- * [🏭 Related Repositories](#-related-repositories)
22
- * [🦔 Learn More](#-learn-more)
23
- * [📣 Feedback](#-feedback)
10
+
11
+ - [oclif: Node.JS Open CLI Framework](#oclif-nodejs-open-cli-framework)
12
+ - [🗒 Description](#-description)
13
+ - [🚀 Getting Started Tutorial](#-getting-started-tutorial)
14
+ - [ Features](#-features)
15
+ - [📌 Requirements](#-requirements)
16
+ - [📌 Migrating from V1](#-migrating-from-v1)
17
+ - [🏗 Usage](#-usage)
18
+ - [📚 Examples](#-examples)
19
+ - [🔨 Commands](#-commands)
20
+ - [Command Topics](#command-topics)
21
+ - [🏭 Related Repositories](#-related-repositories)
22
+ - [🦔 Learn More](#-learn-more)
23
+ - [📣 Feedback](#-feedback)
24
24
  <!-- tocstop -->
25
25
 
26
26
  # 🗒 Description
@@ -35,17 +35,17 @@ The [Getting Started tutorial](http://oclif.io/docs/introduction) is a step-by-s
35
35
 
36
36
  # ✨ Features
37
37
 
38
- * **Flag/Argument parsing** - No CLI framework would be complete without a flag parser. We've built a custom one from years of experimentation that we feel consistently handles user input flexible enough for the user to be able to use the CLI in ways they expect, but without compromising strictness guarantees to the developer.
39
- * **Super Speed** - The overhead for running an oclif CLI command is almost nothing. [It requires very few dependencies](https://www.npmjs.com/package/@oclif/command?activeTab=dependencies) (only 35 dependencies in a minimal setup—including all transitive dependencies). Also, only the command to be executed will be required with node. So large CLIs with many commands will load equally as fast as a small one with a single command.
40
- * **CLI Generator** - Run a single command to scaffold out a fully functional CLI and get started quickly. See [Usage](#-usage) below.
41
- * **Testing Helpers** - We've put a lot of work into making commands easier to test and mock out stdout/stderr. The generator will automatically create [scaffolded tests](https://github.com/oclif/hello-world/blob/main/test/commands/hello.test.ts).
42
- * **Auto-documentation** - By default you can pass `--help` to the CLI to get help such as flag options and argument information. This information is also automatically placed in the README whenever the npm package of the CLI is published. See the [multi-command CLI example](https://github.com/oclif/example-multi-ts)
43
- * **Plugins** - Using [plugins](https://oclif.io/docs/plugins), users of the CLI can extend it with new functionality, a CLI can be split into modular components, and functionality can be shared amongst multiple CLIs. See [Building your own plugin](https://oclif.io/docs/plugins#building-your-own-plugin).
44
- * **Hooks** - Use lifecycle hooks to run functionality any time a CLI starts, or on custom triggers. Use this whenever custom functionality needs to be shared between various components of the CLI.
45
- * **TypeScript** - Everything in the core of oclif is written in TypeScript and the generator will build fully configured TypeScript CLIs. If you use plugins support, the CLI will automatically use `ts-node` to run the plugins enabling you to use TypeScript with minimal-to-no boilerplate needed for any oclif CLI.
46
- * **Auto-updating Installers** - oclif can package your CLI into [different installers](https://oclif.io/docs/releasing) that will not require the user to already have node installed on the machine. These can be made auto-updatable by using [plugin-update](https://github.com/oclif/plugin-update).
47
- * **Everything is Customizable** - Pretty much anything can be swapped out and replaced inside oclif if needed—including the arg/flag parser.
48
- * **Autocomplete** - Automatically include autocomplete for your CLI. This includes not only command names and flag names, but flag values as well. For example, it's possible to configure the Heroku CLI to have completions for Heroku app names:
38
+ - **Flag/Argument parsing** - No CLI framework would be complete without a flag parser. We've built a custom one from years of experimentation that we feel consistently handles user input flexible enough for the user to be able to use the CLI in ways they expect, but without compromising strictness guarantees to the developer.
39
+ - **Super Speed** - The overhead for running an oclif CLI command is almost nothing. [It requires very few dependencies](https://www.npmjs.com/package/@oclif/command?activeTab=dependencies) (only 35 dependencies in a minimal setup—including all transitive dependencies). Also, only the command to be executed will be required with node. So large CLIs with many commands will load equally as fast as a small one with a single command.
40
+ - **CLI Generator** - Run a single command to scaffold out a fully functional CLI and get started quickly. See [Usage](#-usage) below.
41
+ - **Testing Helpers** - We've put a lot of work into making commands easier to test and mock out stdout/stderr. The generator will automatically create [scaffolded tests](https://github.com/oclif/hello-world/blob/main/test/commands/hello.test.ts).
42
+ - **Auto-documentation** - By default you can pass `--help` to the CLI to get help such as flag options and argument information. This information is also automatically placed in the README whenever the npm package of the CLI is published. See the [multi-command CLI example](https://github.com/oclif/example-multi-ts)
43
+ - **Plugins** - Using [plugins](https://oclif.io/docs/plugins), users of the CLI can extend it with new functionality, a CLI can be split into modular components, and functionality can be shared amongst multiple CLIs. See [Building your own plugin](https://oclif.io/docs/plugins#building-your-own-plugin).
44
+ - **Hooks** - Use lifecycle hooks to run functionality any time a CLI starts, or on custom triggers. Use this whenever custom functionality needs to be shared between various components of the CLI.
45
+ - **TypeScript** - Everything in the core of oclif is written in TypeScript and the generator will build fully configured TypeScript CLIs. If you use plugins support, the CLI will automatically use `ts-node` to run the plugins enabling you to use TypeScript with minimal-to-no boilerplate needed for any oclif CLI.
46
+ - **Auto-updating Installers** - oclif can package your CLI into [different installers](https://oclif.io/docs/releasing) that will not require the user to already have node installed on the machine. These can be made auto-updatable by using [plugin-update](https://github.com/oclif/plugin-update).
47
+ - **Everything is Customizable** - Pretty much anything can be swapped out and replaced inside oclif if needed—including the arg/flag parser.
48
+ - **Autocomplete** - Automatically include autocomplete for your CLI. This includes not only command names and flag names, but flag values as well. For example, it's possible to configure the Heroku CLI to have completions for Heroku app names:
49
49
 
50
50
  ```
51
51
  $ heroku info --app=<tab><tab> # will complete with all the Heroku apps a user has in their account
@@ -69,6 +69,7 @@ If you have been using version 1 of the [`oclif` CLI](https://github.com/oclif/o
69
69
  ## New Commands
70
70
 
71
71
  Version 2 now includes all the commands from the [`oclif-dev` CLI](https://github.com/oclif/dev-cli). This means that you can now use a single CLI for all your oclif needs. These commands include:
72
+
72
73
  - `oclif manifest`
73
74
  - `oclif pack`
74
75
  - `oclif pack:deb`
@@ -80,7 +81,6 @@ Version 2 now includes all the commands from the [`oclif-dev` CLI](https://githu
80
81
  - `oclif upload:win` (formerly known as `oclif-dev publish:win`)
81
82
  - `oclif readme`
82
83
 
83
-
84
84
  # 🏗 Usage
85
85
 
86
86
  Creating a CLI:
@@ -105,330 +105,36 @@ hello world! (./src/commands/hello/world.ts)
105
105
 
106
106
  # 📚 Examples
107
107
 
108
- * [Hello-World](https://github.com/oclif/hello-world)
109
- * [Salesforce CLI](https://github.com/salesforcecli/cli)
110
- * [Heroku CLI](https://github.com/heroku/cli)
108
+ - [Hello-World](https://github.com/oclif/hello-world)
109
+ - [Salesforce CLI](https://github.com/salesforcecli/cli)
110
+ - [Heroku CLI](https://github.com/heroku/cli)
111
111
 
112
112
  # 🔨 Commands
113
113
 
114
114
  <!-- commands -->
115
- * [`oclif generate NAME`](#oclif-generate-name)
116
- * [`oclif generate command NAME`](#oclif-generate-command-name)
117
- * [`oclif generate hook NAME`](#oclif-generate-hook-name)
118
- * [`oclif help [COMMAND]`](#oclif-help-command)
119
- * [`oclif manifest [PATH]`](#oclif-manifest-path)
120
- * [`oclif pack deb`](#oclif-pack-deb)
121
- * [`oclif pack macos`](#oclif-pack-macos)
122
- * [`oclif pack tarballs`](#oclif-pack-tarballs)
123
- * [`oclif pack win`](#oclif-pack-win)
124
- * [`oclif promote`](#oclif-promote)
125
- * [`oclif readme`](#oclif-readme)
126
- * [`oclif upload deb`](#oclif-upload-deb)
127
- * [`oclif upload macos`](#oclif-upload-macos)
128
- * [`oclif upload tarballs`](#oclif-upload-tarballs)
129
- * [`oclif upload win`](#oclif-upload-win)
130
-
131
- ## `oclif generate NAME`
132
-
133
- generate a new CLI
134
-
135
- ```
136
- USAGE
137
- $ oclif generate [NAME]
138
-
139
- ARGUMENTS
140
- NAME directory name of new project
141
-
142
- DESCRIPTION
143
- generate a new CLI
144
-
145
- This will clone the template repo 'oclif/hello-world' and update package properties
146
- ```
147
-
148
- _See code: [src/commands/generate.ts](https://github.com/oclif/oclif/blob/v3.2.1/src/commands/generate.ts)_
149
-
150
- ## `oclif generate command NAME`
151
-
152
- add a command to an existing CLI or plugin
153
-
154
- ```
155
- USAGE
156
- $ oclif generate command [NAME] [--force]
157
-
158
- ARGUMENTS
159
- NAME name of command
160
-
161
- FLAGS
162
- --force overwrite existing files
163
-
164
- DESCRIPTION
165
- add a command to an existing CLI or plugin
166
- ```
167
-
168
- ## `oclif generate hook NAME`
169
-
170
- add a hook to an existing CLI or plugin
171
-
172
- ```
173
- USAGE
174
- $ oclif generate hook [NAME] [--force] [--event <value>]
175
-
176
- ARGUMENTS
177
- NAME name of hook (snake_case)
178
-
179
- FLAGS
180
- --event=<value> [default: init] event to run hook on
181
- --force overwrite existing files
182
-
183
- DESCRIPTION
184
- add a hook to an existing CLI or plugin
185
- ```
186
-
187
- ## `oclif help [COMMAND]`
188
-
189
- Display help for oclif.
190
-
191
- ```
192
- USAGE
193
- $ oclif help [COMMAND] [-n]
194
-
195
- ARGUMENTS
196
- COMMAND Command to show help for.
197
-
198
- FLAGS
199
- -n, --nested-commands Include all nested commands in the output.
200
-
201
- DESCRIPTION
202
- Display help for oclif.
203
- ```
204
-
205
- _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v5.1.12/src/commands/help.ts)_
206
-
207
- ## `oclif manifest [PATH]`
208
-
209
- generates plugin manifest json
210
-
211
- ```
212
- USAGE
213
- $ oclif manifest [PATH]
214
-
215
- ARGUMENTS
216
- PATH [default: .] path to plugin
217
-
218
- DESCRIPTION
219
- generates plugin manifest json
220
- ```
221
-
222
- _See code: [src/commands/manifest.ts](https://github.com/oclif/oclif/blob/v3.2.1/src/commands/manifest.ts)_
223
-
224
- ## `oclif pack deb`
225
-
226
- pack CLI into debian package
227
-
228
- ```
229
- USAGE
230
- $ oclif pack deb -r <value> [-t <value>]
231
-
232
- FLAGS
233
- -r, --root=<value> (required) [default: .] path to oclif CLI root
234
- -t, --tarball=<value> optionally specify a path to a tarball already generated by NPM
235
- -Z, --compression=<value> optionally override compression, see output of
236
- 'dpkg-deb --help' in the -Z description for valid options.
237
-
238
- DESCRIPTION
239
- pack CLI into debian package
240
- ```
241
-
242
- ## `oclif pack macos`
243
-
244
- pack CLI into macOS .pkg
245
-
246
- ```
247
- USAGE
248
- $ oclif pack macos -r <value> [-t <value>]
249
-
250
- FLAGS
251
- -r, --root=<value> (required) [default: .] path to oclif CLI root
252
- -t, --tarball=<value> optionally specify a path to a tarball already generated by NPM
253
-
254
- DESCRIPTION
255
- pack CLI into macOS .pkg
256
- ```
257
-
258
- ## `oclif pack tarballs`
259
-
260
- packages oclif CLI into tarballs
261
115
 
262
- ```
263
- USAGE
264
- $ oclif pack tarballs -r <value> [-t <value>] [--xz] [--parallel] [-l <value>]
265
-
266
- FLAGS
267
- -l, --tarball=<value> optionally specify a path to a tarball already generated by NPM
268
- -r, --root=<value> (required) [default: .] path to oclif CLI root
269
- -t, --targets=<value> comma-separated targets to pack (e.g.: linux-arm,win32-x64)
270
- --parallel build tarballs in parallel
271
- --[no-]xz also build xz
272
-
273
- DESCRIPTION
274
- packages oclif CLI into tarballs
275
-
276
- This can be used to create oclif CLIs that use the system node or that come preloaded with a node binary.
277
- ```
278
-
279
- ## `oclif pack win`
280
-
281
- create windows installer from oclif CLI
282
-
283
- ```
284
- USAGE
285
- $ oclif pack win -r <value> [-t <value>]
286
-
287
- FLAGS
288
- -r, --root=<value> (required) [default: .] path to oclif CLI root
289
- -t, --tarball=<value> optionally specify a path to a tarball already generated by NPM
290
-
291
- DESCRIPTION
292
- create windows installer from oclif CLI
293
-
294
- This command requires WINDOWS_SIGNING (prefixed with the name of your executable, e.g. OCLIF_WINDOWS_SIGNING_PASS) to
295
- be set in the environment
296
- ```
297
-
298
- ## `oclif promote`
299
-
300
- promote CLI builds to a S3 release channel
301
-
302
- ```
303
- USAGE
304
- $ oclif promote -r <value> --version <value> --sha <value> --channel <value> [-t <value>] [-d] [-m] [-w]
305
- [-a <value>] [--xz] [--indexes]
306
-
307
- FLAGS
308
- -a, --max-age=<value> [default: 86400] cache control max-age in seconds
309
- -d, --deb promote debian artifacts
310
- -m, --macos promote macOS pkg
311
- -r, --root=<value> (required) [default: .] path to the oclif CLI project root
312
- -t, --targets=<value> comma-separated targets to promote (e.g.: linux-arm,win32-x64)
313
- -w, --win promote Windows exe
314
- --channel=<value> (required) [default: stable] which channel to promote to
315
- --indexes append the promoted urls into the index files
316
- --sha=<value> (required) 7-digit short git commit SHA of the CLI to promote
317
- --version=<value> (required) semantic version of the CLI to promote
318
- --[no-]xz also upload xz
319
-
320
- DESCRIPTION
321
- promote CLI builds to a S3 release channel
322
- ```
323
-
324
- _See code: [src/commands/promote.ts](https://github.com/oclif/oclif/blob/v3.2.1/src/commands/promote.ts)_
325
-
326
- ## `oclif readme`
327
-
328
- adds commands to README.md in current directory
329
-
330
- ```
331
- USAGE
332
- $ oclif readme --dir <value> [--multi] [--aliases]
333
-
334
- FLAGS
335
- --[no-]aliases include aliases in the command list
336
- --dir=<value> (required) [default: docs] output directory for multi docs
337
- --multi create a different markdown page for each topic
338
-
339
- DESCRIPTION
340
- adds commands to README.md in current directory
341
-
342
- The readme must have any of the following tags inside of it for it to be replaced or else it will do nothing:
343
-
344
- # Usage
345
-
346
- <!-- usage -->
347
-
348
- # Commands
349
-
350
- <!-- commands -->
116
+ # Command Topics
351
117
 
352
- Customize the code URL prefix by setting oclif.repositoryPrefix in package.json.
353
- ```
354
-
355
- _See code: [src/commands/readme.ts](https://github.com/oclif/oclif/blob/v3.2.1/src/commands/readme.ts)_
356
-
357
- ## `oclif upload deb`
358
-
359
- upload deb package built with pack:deb
360
-
361
- ```
362
- USAGE
363
- $ oclif upload deb -r <value>
364
-
365
- FLAGS
366
- -r, --root=<value> (required) [default: .] path to oclif CLI root
367
-
368
- DESCRIPTION
369
- upload deb package built with pack:deb
370
- ```
371
-
372
- ## `oclif upload macos`
373
-
374
- upload macos installers built with pack:macos
375
-
376
- ```
377
- USAGE
378
- $ oclif upload macos -r <value>
379
-
380
- FLAGS
381
- -r, --root=<value> (required) [default: .] path to oclif CLI root
382
-
383
- DESCRIPTION
384
- upload macos installers built with pack:macos
385
- ```
386
-
387
- ## `oclif upload tarballs`
388
-
389
- upload an oclif CLI to S3
118
+ - [`oclif generate`](docs/generate.md) - generate a new CLI
119
+ - [`oclif help`](docs/help.md) - Display help for oclif.
120
+ - [`oclif manifest`](docs/manifest.md) - generates plugin manifest json
121
+ - [`oclif pack`](docs/pack.md) - package an oclif CLI into installable artifacts
122
+ - [`oclif promote`](docs/promote.md) - promote CLI builds to a S3 release channel
123
+ - [`oclif readme`](docs/readme.md) - adds commands to README.md in current directory
124
+ - [`oclif upload`](docs/upload.md) - upload installable CLI artifacts to AWS S3
390
125
 
391
- ```
392
- USAGE
393
- $ oclif upload tarballs -r <value> [-t <value>] [--xz]
394
-
395
- FLAGS
396
- -r, --root=<value> (required) [default: .] path to oclif CLI root
397
- -t, --targets=<value> comma-separated targets to upload (e.g.: linux-arm,win32-x64)
398
- --[no-]xz also upload xz
399
-
400
- DESCRIPTION
401
- upload an oclif CLI to S3
402
-
403
- "aws-sdk" will need to be installed as a devDependency to upload.
404
- ```
405
-
406
- ## `oclif upload win`
407
-
408
- upload windows installers built with pack:win
409
-
410
- ```
411
- USAGE
412
- $ oclif upload win -r <value>
413
-
414
- FLAGS
415
- -r, --root=<value> (required) [default: .] path to oclif CLI root
416
-
417
- DESCRIPTION
418
- upload windows installers built with pack:win
419
- ```
420
126
  <!-- commandsstop -->
421
127
 
422
128
  # 🏭 Related Repositories
423
129
 
424
- * [@oclif/core](https://github.com/oclif/core) - Base library for oclif. This can be used directly without the generator.
425
- * [@oclif/cli-ux](https://github.com/oclif/cli-ux) - Library for common CLI UI utilities.
426
- * [@oclif/test](https://github.com/oclif/test) - Test helper for oclif.
130
+ - [@oclif/core](https://github.com/oclif/core) - Base library for oclif. This can be used directly without the generator.
131
+ - [@oclif/cli-ux](https://github.com/oclif/cli-ux) - Library for common CLI UI utilities.
132
+ - [@oclif/test](https://github.com/oclif/test) - Test helper for oclif.
427
133
 
428
134
  # 🦔 Learn More
429
135
 
430
- * [Salesforce Release Announcement](https://engineering.salesforce.com/open-sourcing-oclif-the-cli-framework-that-powers-our-clis-21fbda99d33a)
431
- * [Heroku Release Announcement](https://blog.heroku.com/open-cli-framework)
136
+ - [Salesforce Release Announcement](https://engineering.salesforce.com/open-sourcing-oclif-the-cli-framework-that-powers-our-clis-21fbda99d33a)
137
+ - [Heroku Release Announcement](https://blog.heroku.com/open-cli-framework)
432
138
 
433
139
  # 📣 Feedback
434
140
 
@@ -230,7 +230,6 @@ the CLI should already exist in a directory named after the CLI that is the root
230
230
  '--scripts',
231
231
  scriptsDir,
232
232
  ];
233
- /* eslint-enable array-element-newline */
234
233
  if (macos.sign) {
235
234
  args.push('--sign', macos.sign);
236
235
  }
@@ -3,8 +3,10 @@ export default class Readme extends Command {
3
3
  static description: string;
4
4
  static flags: {
5
5
  aliases: Interfaces.BooleanFlag<boolean>;
6
- dir: Interfaces.OptionFlag<string, Interfaces.CustomOptions>;
7
6
  multi: Interfaces.BooleanFlag<boolean>;
7
+ 'nested-topics-depth': Interfaces.OptionFlag<number | undefined, Interfaces.CustomOptions>;
8
+ 'output-dir': Interfaces.OptionFlag<string, Interfaces.CustomOptions>;
9
+ 'plugin-directory': Interfaces.OptionFlag<string | undefined, Interfaces.CustomOptions>;
8
10
  'readme-path': Interfaces.OptionFlag<string, Interfaces.CustomOptions>;
9
11
  'repository-prefix': Interfaces.OptionFlag<string | undefined, Interfaces.CustomOptions>;
10
12
  version: Interfaces.OptionFlag<string | undefined, Interfaces.CustomOptions>;
@@ -14,7 +16,7 @@ export default class Readme extends Command {
14
16
  commandCode(config: Interfaces.Config, c: Command.Cached): string | undefined;
15
17
  commands(config: Interfaces.Config, commands: Command.Cached[]): string;
16
18
  createTopicFile(file: string, config: Interfaces.Config, topic: Interfaces.Topic, commands: Command.Cached[]): void;
17
- multiCommands(config: Interfaces.Config, commands: Command.Cached[], dir: string): string;
19
+ multiCommands(config: Interfaces.Config, commands: Command.Cached[], dir: string, nestedTopicsDepth: number | undefined): string;
18
20
  renderCommand(config: Interfaces.Config, c: Command.Cached): string;
19
21
  replaceTag(readme: string, tag: string, body: string): string;
20
22
  run(): Promise<void>;
@@ -46,13 +46,37 @@ The readme must have any of the following tags inside of it for it to be replace
46
46
  Customize the code URL prefix by setting oclif.repositoryPrefix in package.json.
47
47
  `;
48
48
  static flags = {
49
- aliases: core_1.Flags.boolean({ allowNo: true, default: true, description: 'include aliases in the command list' }),
50
- dir: core_1.Flags.string({ default: 'docs', description: 'output directory for multi docs', required: true }),
51
- multi: core_1.Flags.boolean({ description: 'create a different markdown page for each topic' }),
52
- 'readme-path': core_1.Flags.string({ default: 'README.md', description: 'Path to the README file.', required: true }),
53
- 'repository-prefix': core_1.Flags.string({ description: 'a template string used to build links to the source code' }),
49
+ aliases: core_1.Flags.boolean({
50
+ allowNo: true,
51
+ default: true,
52
+ description: 'Include aliases in the command list.',
53
+ }),
54
+ multi: core_1.Flags.boolean({
55
+ description: 'Create a different markdown page for each topic.',
56
+ }),
57
+ 'nested-topics-depth': core_1.Flags.integer({
58
+ dependsOn: ['multi'],
59
+ description: 'Max nested topics depth for multi markdown page generation. Use with --multi enabled.',
60
+ }),
61
+ 'output-dir': core_1.Flags.string({
62
+ aliases: ['dir'],
63
+ default: 'docs',
64
+ description: 'Output directory for multi docs.',
65
+ required: true,
66
+ }),
67
+ 'plugin-directory': core_1.Flags.string({
68
+ description: 'Plugin directory to generate README for. Defaults to the current directory.',
69
+ }),
70
+ 'readme-path': core_1.Flags.string({
71
+ default: 'README.md',
72
+ description: 'Path to the README file.',
73
+ required: true,
74
+ }),
75
+ 'repository-prefix': core_1.Flags.string({
76
+ description: 'A template string used to build links to the source code.',
77
+ }),
54
78
  version: core_1.Flags.string({
55
- description: 'version to use in readme links. defaults to the version in package.json',
79
+ description: 'Version to use in readme links. Defaults to the version in package.json.',
56
80
  }),
57
81
  };
58
82
  flags;
@@ -90,7 +114,7 @@ Customize the code URL prefix by setting oclif.repositoryPrefix in package.json.
90
114
  : `* [\`${config.bin}\`](#${slugify.slug(`${config.bin}`)})`;
91
115
  }),
92
116
  '',
93
- ...commands.map((c) => this.renderCommand(config, c)).map((s) => s.trim() + '\n'),
117
+ ...commands.map((c) => this.renderCommand(config, { ...c })).map((s) => s.trim() + '\n'),
94
118
  ]
95
119
  .join('\n')
96
120
  .trim();
@@ -107,11 +131,13 @@ Customize the code URL prefix by setting oclif.repositoryPrefix in package.json.
107
131
  ]
108
132
  .join('\n')
109
133
  .trim() + '\n';
110
- fs.outputFileSync(file, doc);
134
+ fs.outputFileSync(path.resolve(this.flags['plugin-directory'] ?? process.cwd(), file), doc);
111
135
  }
112
- multiCommands(config, commands, dir) {
136
+ multiCommands(config, commands, dir, nestedTopicsDepth) {
113
137
  let topics = config.topics;
114
- topics = topics.filter((t) => !t.hidden && !t.name.includes(':'));
138
+ topics = nestedTopicsDepth
139
+ ? topics.filter((t) => !t.hidden && (t.name.match(/:/g) || []).length < nestedTopicsDepth)
140
+ : topics.filter((t) => !t.hidden && !t.name.includes(':'));
115
141
  topics = topics.filter((t) => commands.find((c) => c.id.startsWith(t.name)));
116
142
  topics = (0, util_1.sortBy)(topics, (t) => t.name);
117
143
  topics = (0, util_1.uniqBy)(topics, (t) => t.name);
@@ -121,7 +147,7 @@ Customize the code URL prefix by setting oclif.repositoryPrefix in package.json.
121
147
  return ([
122
148
  '# Command Topics\n',
123
149
  ...topics.map((t) => (0, util_1.compact)([
124
- `* [\`${config.bin} ${t.name}\`](${dir}/${t.name.replaceAll(':', '/')}.md)`,
150
+ `* [\`${config.bin} ${t.name.replaceAll(':', config.topicSeparator)}\`](${dir}/${t.name.replaceAll(':', '/')}.md)`,
125
151
  (0, util_1.template)({ config })(t.description || '')
126
152
  .trim()
127
153
  .split('\n')[0],
@@ -169,18 +195,22 @@ Customize the code URL prefix by setting oclif.repositoryPrefix in package.json.
169
195
  async run() {
170
196
  const { flags } = await this.parse(Readme);
171
197
  this.flags = flags;
172
- const cwd = process.cwd();
173
- const readmePath = path.resolve(cwd, flags['readme-path']);
174
- const tsConfigPath = path.resolve(cwd, 'tsconfig.json');
198
+ this.flags['plugin-directory'] ??= process.cwd();
199
+ const readmePath = path.resolve(this.flags['plugin-directory'], flags['readme-path']);
200
+ const tsConfigPath = path.resolve(this.flags['plugin-directory'], 'tsconfig.json');
175
201
  const tsConfig = await fs.readJSON(tsConfigPath).catch(() => ({}));
176
202
  const outDir = tsConfig.compilerOptions?.outDir ?? 'lib';
177
203
  if (!(await fs.pathExists(outDir))) {
178
204
  this.warn(`No compiled source found at ${outDir}. Some commands may be missing.`);
179
205
  }
180
- const config = await core_1.Config.load({ devPlugins: false, root: cwd, userPlugins: false });
206
+ const config = await core_1.Config.load({
207
+ devPlugins: false,
208
+ root: this.flags['plugin-directory'],
209
+ userPlugins: false,
210
+ });
181
211
  try {
182
212
  // eslint-disable-next-line node/no-missing-require
183
- const p = require.resolve('@oclif/plugin-legacy', { paths: [cwd] });
213
+ const p = require.resolve('@oclif/plugin-legacy', { paths: [this.flags['plugin-directory']] });
184
214
  const plugin = new core_1.Plugin({ root: p, type: 'core' });
185
215
  await plugin.load();
186
216
  config.plugins.set(plugin.name, plugin);
@@ -197,7 +227,9 @@ Customize the code URL prefix by setting oclif.repositoryPrefix in package.json.
197
227
  commands = (0, util_1.uniqBy)(commands, (c) => c.id);
198
228
  commands = (0, util_1.sortBy)(commands, (c) => c.id);
199
229
  readme = this.replaceTag(readme, 'usage', this.usage(config));
200
- readme = this.replaceTag(readme, 'commands', this.flags.multi ? this.multiCommands(config, commands, this.flags.dir) : this.commands(config, commands));
230
+ readme = this.replaceTag(readme, 'commands', flags.multi
231
+ ? this.multiCommands(config, commands, flags['output-dir'], flags['nested-topics-depth'])
232
+ : this.commands(config, commands));
201
233
  readme = this.replaceTag(readme, 'toc', this.toc(config, readme));
202
234
  readme = readme.trimEnd();
203
235
  readme += '\n';
@@ -234,7 +266,13 @@ USAGE
234
266
  * fetches the path to a command
235
267
  */
236
268
  commandPath(plugin, c) {
237
- const commandsDir = plugin.pjson.oclif.commands;
269
+ const strategy = typeof plugin.pjson.oclif?.commands === 'string' ? 'pattern' : plugin.pjson.oclif?.commands?.strategy;
270
+ // if the strategy is explicit, we can't determine the path so return undefined
271
+ if (strategy === 'explicit')
272
+ return;
273
+ const commandsDir = typeof plugin.pjson.oclif?.commands === 'string'
274
+ ? plugin.pjson.oclif?.commands
275
+ : plugin.pjson.oclif?.commands?.target;
238
276
  if (!commandsDir)
239
277
  return;
240
278
  const hasTypescript = plugin.pjson.devDependencies?.typescript || plugin.pjson.dependencies?.typescript;
@@ -29,6 +29,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
29
29
  const node_child_process_1 = require("node:child_process");
30
30
  const fs = __importStar(require("node:fs"));
31
31
  const path = __importStar(require("node:path"));
32
+ const validate_npm_package_name_1 = __importDefault(require("validate-npm-package-name"));
32
33
  const yeoman_generator_1 = __importDefault(require("yeoman-generator"));
33
34
  const util_1 = require("../util");
34
35
  const debug = require('debug')('generator-oclif');
@@ -143,12 +144,14 @@ class CLI extends yeoman_generator_1.default {
143
144
  message: 'npm package name',
144
145
  name: 'name',
145
146
  type: 'input',
147
+ validate: (d) => (0, validate_npm_package_name_1.default)(d).validForNewPackages || 'Invalid package name',
146
148
  },
147
149
  {
148
150
  default: (answers) => answers.name,
149
151
  message: 'command bin name the CLI will export',
150
152
  name: 'bin',
151
153
  type: 'input',
154
+ validate: (d) => (0, util_1.validateBin)(d) || 'Invalid bin name',
152
155
  },
153
156
  {
154
157
  default: defaults.description,
package/lib/util.d.ts CHANGED
@@ -13,4 +13,5 @@ export declare const prettifyPaths: (input: unknown) => string;
13
13
  export declare const hash: (algo: string, fp: string | string[]) => Promise<string>;
14
14
  export declare function checkFor7Zip(): Promise<void>;
15
15
  export declare function isEmpty(obj: Record<string, unknown>): boolean;
16
+ export declare function validateBin(bin: string): boolean;
16
17
  export {};
package/lib/util.js CHANGED
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.isEmpty = exports.checkFor7Zip = exports.hash = exports.prettifyPaths = exports.sortVersionsObjectByKeysDesc = exports.template = exports.sortBy = exports.uniq = exports.compact = exports.uniqBy = exports.castArray = void 0;
26
+ exports.validateBin = exports.isEmpty = exports.checkFor7Zip = exports.hash = exports.prettifyPaths = exports.sortVersionsObjectByKeysDesc = exports.template = exports.sortBy = exports.uniq = exports.compact = exports.uniqBy = exports.castArray = void 0;
27
27
  const core_1 = require("@oclif/core");
28
28
  const node_child_process_1 = require("node:child_process");
29
29
  const crypto = __importStar(require("node:crypto"));
@@ -139,3 +139,7 @@ function isEmpty(obj) {
139
139
  return Object.keys(obj).length === 0;
140
140
  }
141
141
  exports.isEmpty = isEmpty;
142
+ function validateBin(bin) {
143
+ return /^[\w-]+$/.test(bin);
144
+ }
145
+ exports.validateBin = validateBin;
@@ -203,25 +203,45 @@
203
203
  "description": "adds commands to README.md in current directory\nThe readme must have any of the following tags inside of it for it to be replaced or else it will do nothing:\n# Usage\n<!-- usage -->\n# Commands\n<!-- commands -->\n# Table of contents\n<!-- toc -->\n\nCustomize the code URL prefix by setting oclif.repositoryPrefix in package.json.\n",
204
204
  "flags": {
205
205
  "aliases": {
206
- "description": "include aliases in the command list",
206
+ "description": "Include aliases in the command list.",
207
207
  "name": "aliases",
208
208
  "allowNo": true,
209
209
  "type": "boolean"
210
210
  },
211
- "dir": {
212
- "description": "output directory for multi docs",
213
- "name": "dir",
211
+ "multi": {
212
+ "description": "Create a different markdown page for each topic.",
213
+ "name": "multi",
214
+ "allowNo": false,
215
+ "type": "boolean"
216
+ },
217
+ "nested-topics-depth": {
218
+ "dependsOn": [
219
+ "multi"
220
+ ],
221
+ "description": "Max nested topics depth for multi markdown page generation. Use with --multi enabled.",
222
+ "name": "nested-topics-depth",
223
+ "hasDynamicHelp": false,
224
+ "multiple": false,
225
+ "type": "option"
226
+ },
227
+ "output-dir": {
228
+ "aliases": [
229
+ "dir"
230
+ ],
231
+ "description": "Output directory for multi docs.",
232
+ "name": "output-dir",
214
233
  "required": true,
215
234
  "default": "docs",
216
235
  "hasDynamicHelp": false,
217
236
  "multiple": false,
218
237
  "type": "option"
219
238
  },
220
- "multi": {
221
- "description": "create a different markdown page for each topic",
222
- "name": "multi",
223
- "allowNo": false,
224
- "type": "boolean"
239
+ "plugin-directory": {
240
+ "description": "Plugin directory to generate README for. Defaults to the current directory.",
241
+ "name": "plugin-directory",
242
+ "hasDynamicHelp": false,
243
+ "multiple": false,
244
+ "type": "option"
225
245
  },
226
246
  "readme-path": {
227
247
  "description": "Path to the README file.",
@@ -233,14 +253,14 @@
233
253
  "type": "option"
234
254
  },
235
255
  "repository-prefix": {
236
- "description": "a template string used to build links to the source code",
256
+ "description": "A template string used to build links to the source code.",
237
257
  "name": "repository-prefix",
238
258
  "hasDynamicHelp": false,
239
259
  "multiple": false,
240
260
  "type": "option"
241
261
  },
242
262
  "version": {
243
- "description": "version to use in readme links. defaults to the version in package.json",
263
+ "description": "Version to use in readme links. Defaults to the version in package.json.",
244
264
  "name": "version",
245
265
  "hasDynamicHelp": false,
246
266
  "multiple": false,
@@ -737,5 +757,5 @@
737
757
  ]
738
758
  }
739
759
  },
740
- "version": "4.4.21"
760
+ "version": "4.5.0"
741
761
  }
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.4.21",
4
+ "version": "4.5.0",
5
5
  "author": "Salesforce",
6
6
  "bin": {
7
7
  "oclif": "bin/run.js"
@@ -10,7 +10,7 @@
10
10
  "dependencies": {
11
11
  "@aws-sdk/client-cloudfront": "^3.525.0",
12
12
  "@aws-sdk/client-s3": "^3.515.0",
13
- "@oclif/core": "^3.19.2",
13
+ "@oclif/core": "^3.21.0",
14
14
  "@oclif/plugin-help": "^6.0.14",
15
15
  "@oclif/plugin-not-found": "^3.0.10",
16
16
  "@oclif/plugin-warn-if-update-available": "^3.0.12",
@@ -25,11 +25,12 @@
25
25
  "normalize-package-data": "^3.0.3",
26
26
  "semver": "^7.6.0",
27
27
  "sort-package-json": "^2.8.0",
28
+ "validate-npm-package-name": "^5.0.0",
28
29
  "yeoman-environment": "^3.15.1",
29
30
  "yeoman-generator": "^5.8.0"
30
31
  },
31
32
  "devDependencies": {
32
- "@commitlint/config-conventional": "^17.7.0",
33
+ "@commitlint/config-conventional": "^18",
33
34
  "@oclif/plugin-legacy": "^2.0.7",
34
35
  "@oclif/prettier-config": "^0.2.1",
35
36
  "@oclif/test": "^3.1.13",
@@ -43,19 +44,18 @@
43
44
  "@types/node": "^18",
44
45
  "@types/semver": "^7.5.7",
45
46
  "@types/shelljs": "^0.8.11",
47
+ "@types/validate-npm-package-name": "^4.0.2",
46
48
  "@types/yeoman-generator": "^5.2.11",
47
49
  "chai": "^4.4.1",
48
- "commitlint": "^17.7.2",
49
- "conventional-changelog-cli": "^2.2.2",
50
+ "commitlint": "^18",
50
51
  "eslint": "^8.57.0",
51
- "eslint-config-oclif": "^5.0.2",
52
+ "eslint-config-oclif": "^5.0.4",
52
53
  "eslint-config-oclif-typescript": "^3.0.48",
53
54
  "eslint-config-prettier": "^9.0.0",
54
55
  "eslint-plugin-perfectionist": "^2.1.0",
55
56
  "fancy-test": "^3.0.11",
56
- "globby": "^11.1.0",
57
- "husky": "^8.0.3",
58
- "lint-staged": "^14.0.1",
57
+ "husky": "^9",
58
+ "lint-staged": "^15",
59
59
  "lodash.clonedeep": "^4.5.0",
60
60
  "mocha": "^10.3.0",
61
61
  "nyc": "^15.1.0",
@@ -129,7 +129,7 @@
129
129
  "postpack": "shx rm oclif.manifest.json",
130
130
  "posttest": "yarn run lint",
131
131
  "prepack": "shx rm -rf lib && tsc && bin/run.js manifest .",
132
- "prepare": "husky install",
132
+ "prepare": "husky",
133
133
  "test:integration:cli": "mocha test/integration/cli.test.ts --timeout 600000",
134
134
  "test:integration:deb": "mocha test/integration/deb.test.ts --timeout 900000",
135
135
  "test:integration:macos": "mocha test/integration/macos.test.ts --timeout 900000",