Skip to content

Commit

Permalink
Merge pull request #234 from oclif/mdonnalley/reorg
Browse files Browse the repository at this point in the history
feat: reorganize
  • Loading branch information
mdonnalley authored Mar 29, 2024
2 parents 88920bb + 6e1406e commit ee60e44
Show file tree
Hide file tree
Showing 30 changed files with 1,286 additions and 2,188 deletions.
1 change: 1 addition & 0 deletions docs/aliases.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: Aliases
description: Define aliases for commands, flags, and bins
---

## Command Aliases
Expand Down
1 change: 1 addition & 0 deletions docs/base_class.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: Custom Base Class
description: Create an extendable Command class
---

Use inheritance to share functionality between common commands. Here is an example of a command base class that has some common shared flags.
Expand Down
43 changes: 40 additions & 3 deletions docs/command_discovery_strategies.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export const COMMANDS = {

The `explicit` strategy is useful to those who can't rely on file paths because they've bundled their code (see [Bundling](#bundling)) but it can also be used if you simply prefer to be more explicit about your commands instead of relying on oclif "magically" finding commands from the file system.

It can also be leveraged to create or modify commands at runtime (e.g. internationalize messages at runtime or add flags to a command based on an API spec - see `oclif + dynamic commands` section below).
It can also be leveraged to create or modify commands at runtime (e.g. internationalize messages at runtime or add flags to a command based on an API spec - see [dynamic commands](#dynamic-commands) section below).

#### Hooks

Expand Down Expand Up @@ -123,10 +123,47 @@ That configuration is essentially telling oclif to look for an `INIT_HOOK` expor

#### Bundling

**We do not support bundling** given the endless number of tools + configurations that could be used. But if you choose to use a bundler, like `esbuild` there are a couple hard requirements - you must have a package.json in your root directory and a `bin/run` or `bin/run.js` bin script. _This means that you will not be able to successfully bundle your entire CLI (src code, package.json, node_modules, etc) into a single file._
**We do not support bundling** given the endless number of tools + configurations that could be used. But if you choose to use a bundler, like `esbuild`, there are a couple hard requirements - you must have a package.json in your root directory and a `bin/run` or `bin/run.js` bin script. _This means that you will not be able to successfully bundle your entire CLI (src code, package.json, node_modules, etc) into a single file._

If you want to use a bundler, you can see this [example repo](https://github.com/oclif/plugin-test-esbuild/).
If you still want to use a bundler, you can reference this [example repo](https://github.com/oclif/plugin-test-esbuild/).

#### Dynamic Commands

You can also use the `explicit` strategy if you want to manipulate or create commands at runtime. Please note that such usage of the `explicit` strategy **cannot** be used with an `oclif.manifest.json`, which will have significant performance implications for your CLI in production.

Example:
```typescript
// src/index.ts
import {Command, Flags} from '@oclif/core'

import Hello from './commands/hello'
import HelloWorld from './commands/hello/world'

const dynamicCommands: Record<string, Command.Class> = {}
if (process.env.DYNAMIC_COMMAND) {
dynamicCommands[process.env.DYNAMIC_COMMAND] = class extends Command {
static flags = {
flag1: Flags.boolean({description: 'flag1 description'}),
}

async run(): Promise<void> {
const {flags} = await this.parse(this.constructor as Command.Class)
this.log('hello from', this.id, flags)
}
}
}

export const COMMANDS = {
hello: Hello,
'hello:world': HelloWorld,
...dynamicCommands,
}
```

```
❯ DYNAMIC_COMMAND=foo:bar:baz bin/run.js foo bar baz --flag1
hello from foo:bar:baz { flag1: true }
```

### `single` Strategy

Expand Down
82 changes: 2 additions & 80 deletions docs/config.md
Original file line number Diff line number Diff line change
@@ -1,86 +1,8 @@
---
title: Configuration
title: Config
---

## Configuring oclif

You can configure the behavior of oclif inside your CLI or plugin's package.json. All of the configuration options should be placed under the `oclif` section. For example:

```json
{
"name": "my-cli",
"version": "1.2.3",
"dependencies": {
"@oclif/core": "^3"
},
"oclif": {
"bin": "mycli",
"dirname": "mycli",
"commands": "./dist/commands",
"topicSeparator": " "
}
}
```

Here's a list of all the options that you can configure.

| Property | Description |
|--------------------------|------------------------------------------------------------------------------------------------------------------------------------------|
| `additionalHelpFlags` | Array of flags that should trigger help output in addition to `--help` |
| `additionalVersionFlags` | Array of flags that should trigger version output in addition to `--version` |
| `aliases` | Aliases for the plugin. This is used to support legacy plugins that have been renamed |
| `bin` | CLI bin name (e.g. `sf`, `heroku`, `git`, etc...) |
| `binAliases` | An array of strings that will all execute the CLI's bin. See [Aliases](./aliases.md#bin-aliases) for more |
| `dirname` | Directory name to use when determining CLI's config, cache, and data directories. |
| `commands` | Where oclif can find command classes. See [Command Discovery Strategies](./command_discovery_strategies.md) for more |
| `description` | Description of your plugin or CLI to show in help |
| `devPlugins` | List of plugins that will only be loaded in development. See [Plugins](./plugins.md) for more |
| `exitCodes` | Configured exit codes. See [Exit Codes](#exit-codes) section below |
| `flexibleTaxonomy` | Set to true to enable [flexible taxonomy](./flexible_taxonomy.md) |
| `helpClass` | Location of compiled [custom help class](./help_classes.md) |
| `helpOptions` | Settings for configuring behavior of help output. See [Help Options](#help-options) section below |
| `hooks` | Register your plugin or CLI's hooks. See [hooks](./hooks.md) for more |
| `jitPlugins` | Register plugins that can be installed just in time. See [Just-in-Time Plugin Installation](./jit_plugins.md) for more |
| `macos` | Settings for building macos installer. See [Releasing](./releasing.md) for more |
| `nsisCustomization` | A path to a .nsis file that's used to customize the installer for Windows. See [nsis-custom](./nsis-installer_customization.md) for more |
| `plugins` | List of plugins that should be loaded. See [Plugins](./plugins.md) for more |
| `state` | Set the state of your CLI or plugin to be shown in help (e.g. `beta` will show `This CLI is in beta`) |
| `theme` | Path to theme file to include with your CLI. See [Themes](./themes.md) for more |
| `topicSeparator` | The separator to use between topics - only colons (`":"`) and spaces (`" "`) are supported |
| `topics` | Define your CLI's topics. See [Topics](./topics.md) for more |
| `windows` | Settings for building windows installer. See [Releasing](./releasing.md) for more |

### Exit Codes

You can configure the desired exit codes for the following errors:
- `default` - default exit code for any error.
- `failedFlagParsing` - exit code when oclif fails to parse a flag's value.
- `failedFlagValidation` - exit code when a flag fails it's own validation.
- `invalidArgsSpec` - exit code when a command defines an invalid `args` configuration.
- `nonExistentFlag` - exit code when user provides a non-existent flag.
- `requiredArgs` - exit code when user fails to provide a required arg.
- `unexpectedArgs` - exit code when user provides unexpected args to a command.

### Help Options

You can configure the behavior of the help output with the following:
- `docopts` - Use docopts as the usage. Defaults to true.
- `flagSortOrder` - Order in which to sort flags in help output. Can be `alphabetical` (default) or `none` (flags will appear in the order they were defined).
- `hideAliasesFromRoot` - If true, hide command aliases from the root help output. Defaults to false.
- `hideCommandSummaryInDescription` - By default, the command summary is show at the top of the help and as the first line in the command description. Repeating the summary in the command description improves readability especially for long command help output. If there is no `command.summary`, the first line of the description is treated as the summary. Some CLIs, especially with very simple commands, may not want the duplication.
- `maxWidth` - Maximum column width of the help output.
- `sections` - Only show the help for the specified sections. Defaults to all sections.
- `sendToStderr` - By default, the help output is sent to stdout. If this is true, it will be sent to stderr.
- `showFlagNameInTitle` - By default, titles show flag values as `<value>`. Some CLI developers may prefer titles to show the flag name as the value. i.e. `--myflag=myflag` instead of `--myflag=<value>`. An individual flag can set this using `flag.helpValue=flag.name`.
- `showFlagOptionsInTitle` - By default, option values on flags are shown in the flag's description. This is because long options list ruin the formatting of help. If a CLI knows all commands will not do this, it can be turned off at a help level using this property. An individual flag can set this using `flag.helpValue=options.join('|')`.
- `stripAnsi` - Strip ansi characters from help out to remove all formatting.
- `usageHeader` - Override the header for the `USAGE` section.

If you want to further customize help, you can implement a [Custom Help Class](./help_classes.md).

## The `Config` Class

Inside a command, `this.config` provides useful properties you can use in your command. Here are a list of its methods and properties:
Inside a command, `this.config` provides access to the `Config` class, which contains useful properties and methods you can use in your command. Here are a list of its methods and properties:

- **name** - name of CLI
- **version** - Version of the CLI.
Expand Down
78 changes: 78 additions & 0 deletions docs/configuring_your_cli.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
title: Configuring Your CLI
description: All about configuring oclif
---

You can configure the behavior of oclif inside your CLI or plugin's package.json. All of the configuration options should be placed under the `oclif` section. For example:

```json
{
"name": "my-cli",
"version": "1.2.3",
"dependencies": {
"@oclif/core": "^3"
},
"oclif": {
"bin": "mycli",
"dirname": "mycli",
"commands": "./dist/commands",
"topicSeparator": " "
}
}
```

Here's a list of all the options that you can configure.

| Property | Description |
|--------------------------|------------------------------------------------------------------------------------------------------------------------------------------|
| `additionalHelpFlags` | Array of flags that should trigger help output in addition to `--help` |
| `additionalVersionFlags` | Array of flags that should trigger version output in addition to `--version` |
| `aliases` | Aliases for the plugin. This is used to support legacy plugins that have been renamed |
| `bin` | CLI bin name (e.g. `sf`, `heroku`, `git`, etc...) |
| `binAliases` | An array of strings that will all execute the CLI's bin. See [Aliases](./aliases.md#bin-aliases) for more |
| `dirname` | Directory name to use when determining CLI's config, cache, and data directories. |
| `commands` | Where oclif can find command classes. See [Command Discovery Strategies](./command_discovery_strategies.md) for more |
| `description` | Description of your plugin or CLI to show in help |
| `devPlugins` | List of plugins that will only be loaded in development. See [Plugins](./plugins.md) for more |
| `exitCodes` | Configured exit codes. See [Exit Codes](#exit-codes) section below |
| `flexibleTaxonomy` | Set to true to enable [flexible taxonomy](./flexible_taxonomy.md) |
| `helpClass` | Location of compiled [custom help class](./help_classes.md) |
| `helpOptions` | Settings for configuring behavior of help output. See [Help Options](#help-options) section below |
| `hooks` | Register your plugin or CLI's hooks. See [hooks](./hooks.md) for more |
| `jitPlugins` | Register plugins that can be installed just in time. See [Just-in-Time Plugin Installation](./jit_plugins.md) for more |
| `macos` | Settings for building macos installer. See [Releasing](./releasing.md) for more |
| `nsisCustomization` | A path to a .nsis file that's used to customize the installer for Windows. See [nsis-custom](./nsis-installer_customization.md) for more |
| `plugins` | List of plugins that should be loaded. See [Plugins](./plugins.md) for more |
| `state` | Set the state of your CLI or plugin to be shown in help (e.g. `beta` will show `This CLI is in beta`) |
| `theme` | Path to theme file to include with your CLI. See [Themes](./themes.md) for more |
| `topicSeparator` | The separator to use between topics - only colons (`":"`) and spaces (`" "`) are supported |
| `topics` | Define your CLI's topics. See [Topics](./topics.md) for more |
| `windows` | Settings for building windows installer. See [Releasing](./releasing.md) for more |

### Exit Codes

You can configure the desired exit codes for the following errors:
- `default` - default exit code for any error.
- `failedFlagParsing` - exit code when oclif fails to parse a flag's value.
- `failedFlagValidation` - exit code when a flag fails it's own validation.
- `invalidArgsSpec` - exit code when a command defines an invalid `args` configuration.
- `nonExistentFlag` - exit code when user provides a non-existent flag.
- `requiredArgs` - exit code when user fails to provide a required arg.
- `unexpectedArgs` - exit code when user provides unexpected args to a command.

### Help Options

You can configure the behavior of the help output with the following:
- `docopts` - Use docopts as the usage. Defaults to true.
- `flagSortOrder` - Order in which to sort flags in help output. Can be `alphabetical` (default) or `none` (flags will appear in the order they were defined).
- `hideAliasesFromRoot` - If true, hide command aliases from the root help output. Defaults to false.
- `hideCommandSummaryInDescription` - By default, the command summary is show at the top of the help and as the first line in the command description. Repeating the summary in the command description improves readability especially for long command help output. If there is no `command.summary`, the first line of the description is treated as the summary. Some CLIs, especially with very simple commands, may not want the duplication.
- `maxWidth` - Maximum column width of the help output.
- `sections` - Only show the help for the specified sections. Defaults to all sections.
- `sendToStderr` - By default, the help output is sent to stdout. If this is true, it will be sent to stderr.
- `showFlagNameInTitle` - By default, titles show flag values as `<value>`. Some CLI developers may prefer titles to show the flag name as the value. i.e. `--myflag=myflag` instead of `--myflag=<value>`. An individual flag can set this using `flag.helpValue=flag.name`.
- `showFlagOptionsInTitle` - By default, option values on flags are shown in the flag's description. This is because long options list ruin the formatting of help. If a CLI knows all commands will not do this, it can be turned off at a help level using this property. An individual flag can set this using `flag.helpValue=options.join('|')`.
- `stripAnsi` - Strip ansi characters from help out to remove all formatting.
- `usageHeader` - Override the header for the `USAGE` section.

If you want to further customize help, you can implement a [Custom Help Class](./help_classes.md).
1 change: 1 addition & 0 deletions docs/debugging.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: Debugging
description: How to access debug logs
---

Use the [debug](https://github.com/visionmedia/debug) for debugging. The CLI uses this module for all of its debugging. If you set the environment variable `DEBUG=*` it will print all the debug output to the screen.
Expand Down
1 change: 1 addition & 0 deletions docs/error_handling.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: Error Handling
description: Customize error handling
---

oclif handles intentionally - and unintentionally - thrown errors in two places. First in the `Command.catch` method and then, finally, in the `bin/run.js` `catch` handler where the Error is printed and the CLI exits. This error flow makes it possible for you to control and respond to errors that occur in your CLI as you see fit.
Expand Down
1 change: 1 addition & 0 deletions docs/esm.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: ESM
description: Using ESM in oclif
---

Version 3.0.0 of `@oclif/core` officially supports ESM plugin development and CJS/ESM interoperability, meaning that you can have a root plugin written with CJS and your plugins written in ESM or vice versa.
Expand Down
Loading

0 comments on commit ee60e44

Please sign in to comment.