diff --git a/docs/args.md b/docs/args.md index aff615fc..b944ae1f 100644 --- a/docs/args.md +++ b/docs/args.md @@ -29,25 +29,45 @@ Here are the options arguments can have: static args = { firstArg: Args.string( { - name: 'file', // name of arg to show in help and reference with args[name] - required: false, // make the arg required with `required: true` - description: 'output file', // help description - hidden: true, // hide this arg from help - parse: input => 'output', // instead of the user input, return a different value - default: 'world', // default value if no arg input - options: ['a', 'b'], // only allow input to be from a discrete set + name: 'file', // name of arg to show in help and reference with args[name] + required: false, // make the arg required with `required: true` + description: 'output file', // help description + hidden: true, // hide this arg from help + parse: async input => 'output', // instead of the user input, return a different value + default: 'world', // default value if no arg input. Can also be an async function. + defaultHelp: 'a dynamic value' // dynamic default value to show in help output (e.g. current working directory). Can be an async function that returns a string or undefined + options: ['a', 'b'], // only allow input to be from a discrete set + ignoreStdin: false, // set to true to ignore any value provided by stdin + noCacheDefault: false // if true, the value returned by defaultHelp will not be cached in the oclif.manifest.json. } ), } ``` Here are the types of args that `Args` exports: -- string -- integer -- boolean -- url -- file -- directory -- custom +- `string` +- `integer` +- `boolean` +- `url` +- `file` +- `directory` +- `custom` For variable length arguments, disable argument validation with `static strict = false` on the command. + +```typescript +import {Args, Command} from '@oclif/core' + +export class MyCLI extends Command { + static args = { + things: Args.string(), + } + + static strict = false + + async run() { + // If you're using strict=false you should use argv to access the provided args. + const {argv} = await this.parse(MyCLI) + this.log(`running my command with args: ${argv[0]}, ${argv[1]}`) + } +} diff --git a/docs/config.md b/docs/config.md index fb374dd7..4aa660fa 100644 --- a/docs/config.md +++ b/docs/config.md @@ -2,73 +2,140 @@ title: Configuration --- +## 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 ``. Some CLI developers may prefer titles to show the flag name as the value. i.e. `--myflag=myflag` instead of `--myflag=`. 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: -* **name** - name of CLI -* **version** - Version of the CLI. -* **pjson** - Parsed and [normalized](https://github.com/npm/normalize-package-data) CLI `package.json`. -* **bin** - CLI bin name -* **binAliases** - An array of strings that will all execute the CLI's bin. This is useful for backwards compatibility and for CLIs built with installers or tarballs. For npm-installed CLIs, change the `bin` property in `package.json` instead. See [Bin Aliases](https://oclif.io/docs/aliases) for more information. -* **nsisCustomization** - A path to a .nsis file that's used to customize the installer for Windows. See [nsis-custom](https://github.com/oclif/nsis-custom) for more information. -* **cacheDir** - CLI cache directory - * macOS: `~/Library/Caches/mycli` - * Unix: `~/.cache/mycli` - * Windows: `%LOCALAPPDATA%\mycli` - * Can be overridden with `XDG_CACHE_HOME` -* **configDir** - CLI config directory - * Unix: `~/.config/mycli` - * Windows: `%LOCALAPPDATA%\mycli` - * Can be overridden with `XDG_CONFIG_HOME` -* **dataDir** - CLI data directory - * Unix: `~/.data/mycli` - * Windows: `%LOCALAPPDATA%\mycli` - * Can be overridden with `XDG_DATA_HOME` -* **dirname** - dirname used with `cacheDir|configDir|dataDir`. Can be overridden in `package.json`. -* **errlog** - path to error log inside of `cacheDir` -* **home** - user home directory -* **platform** - operating system `darwin|linux|win32` -* **arch** - process architecture `x64|x86` -* **shell** - current shell in use -* **userAgent** - user-agent intended for http calls. example: `mycli/1.2.3 (darwin-x64) node-9.0.0` -* **windows** - boolean -* **topicSeparator** - the separator to use between topics - only colons (`":"`) and spaces (`" "`) are supported. -* **debug** - set to 1 if debug is enabled (with `${BIN}_DEBUG=1` or `DEBUG=$BIN`). In the future this may be used for multiple debug levels. -* **npmRegistry** - current npm registry to use with the [plugins](https://github.com/oclif/plugin-plugins) plugin -* **plugins** - loaded plugins -* **commands** - all commands in CLI -* **default** - default cli command -* **topics** - all topics in CLI -* **commandIDs** - string IDs of all commands -* **async runHook(event, opts)** - trigger a hook - - - - +- **name** - name of CLI +- **version** - Version of the CLI. +- **pjson** - Parsed CLI `package.json`. +- **bin** - CLI bin name +- **cacheDir** - CLI cache directory + - macOS: `~/Library/Caches/mycli` + - Unix: `~/.cache/mycli` + - Windows: `%LOCALAPPDATA%\mycli` + - Can be overridden with `XDG_CACHE_HOME` +- **configDir** - CLI config directory + - Unix: `~/.config/mycli` + - Windows: `%LOCALAPPDATA%\mycli` + - Can be overridden with `XDG_CONFIG_HOME` +- **dataDir** - CLI data directory + - Unix: `~/.data/mycli` + - Windows: `%LOCALAPPDATA%\mycli` + - Can be overridden with `XDG_DATA_HOME` +- **dirname** - dirname used with `cacheDir|configDir|dataDir`. Can be overridden in `package.json`. +- **errlog** - path to error log inside of `cacheDir` +- **home** - user home directory +- **platform** - operating system `darwin|linux|win32` +- **arch** - process architecture `x64|x86` +- **shell** - current shell in use +- **userAgent** - user-agent intended for http calls. example: `mycli/1.2.3 (darwin-x64) node-9.0.0` +- **windows** - boolean +- **npmRegistry** - current npm registry to use with the [plugins](https://github.com/oclif/plugin-plugins) plugin +- **plugins** - loaded plugins +- **commands** - all commands in CLI +- **default** - default cli command +- **topics** - all topics in CLI +- **commandIDs** - string IDs of all commands +- **async runHook(event, opts)** - trigger a hook +- **async runCommand(id, opts)** - Run a command +- **scopedEnvVar(key)** - Return the value of a scoped env var (e.g. `\_NPM_REGISTRY`) +- **scopedEnvVarKey(key)** - Return the name of a scoped env var (e.g. `\_NPM_REGISTRY`) +- **scopedEnvVarTrue(key)** - Return true/false value of scoped env var (e.g. `\_NPM_REGISTRY`) ## Custom User Configuration Often it's useful to have a custom configuration for your users. One way to implement this is to read a `config.json` file from the CLI's config directory: ```typescript -import {Command} from '@oclif/core' -import * as fs from 'fs-extra' -import * as path from 'path' +import { Command } from "@oclif/core"; +import * as fs from "fs-extra"; +import * as path from "path"; export class extends Command { async run() { - const userConfig = await fs.readJSON(path.join(this.config.configDir, 'config.json')) + const userConfig = await fs.readJSON( + path.join(this.config.configDir, "config.json") + ); - this.log('User config:') - console.dir(userConfig) + this.log("User config:"); + console.dir(userConfig); } } ``` diff --git a/docs/examples.md b/docs/examples.md index 0e0a4526..3e5dd1ab 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -4,4 +4,7 @@ title: Examples Here are some examples to get an idea of how to use oclif in various setups. -* [Hello World Example](https://github.com/oclif/hello-world) +* [Hello World Example (CommonJS)](https://github.com/oclif/hello-world) +* [Hello World Example (ESM)](https://github.com/oclif/hello-world-esm) +* [Using esbuild](https://github.com/oclif/plugin-test-esbuild) +* [Hook-only plugin](https://github.com/oclif/plugin-not-found) diff --git a/docs/flags.md b/docs/flags.md index ae8c6a47..9ca2b022 100644 --- a/docs/flags.md +++ b/docs/flags.md @@ -12,7 +12,7 @@ $ mycli --force --file=./myfile It would be declared like this: -```js +```typescript import {Command, Flags} from '@oclif/core' export class MyCLI extends Command { @@ -37,8 +37,10 @@ Here are the options flags can have: ```js static flags = { name: Flags.string({ + // The following can be set on both boolean and option flag (e.g. string, integer, url, custom, etc) types. char: 'n', // shorter flag version summary: 'brief summary', // help summary for flag + helpLabel: '--my-flags', // The flag label to show in help. Defaults to "[-] --" where - is only displayed if the char is defined. helpGroup: 'THE BEST FLAGS', // Put flag into THE BEST FLAGS group in help description: 'in-depth overview', // help description for flag hidden: false, // hide from help @@ -47,10 +49,13 @@ static flags = { options: ['a', 'b'], // only allow the value to be from a discrete set parse: async input => 'output', // instead of the user input, return a different value default: 'world', // default value if flag not passed (can be an async function that returns a string or undefined) - defaultHelp: 'a dynamic value' // dyanmic default value to show in help output (e.g. current working directory). Can be an async function that returns a string or undefined + defaultHelp: 'a dynamic value' // dynamic default value to show in help output (e.g. current working directory). Can be an async function that returns a string or undefined required: false, // make flag required aliases: ['username', 'u'], // aliases for the flag - can be short char or long flags + aliases: ['u', 'n'], // single character aliases for the flag + deprecated: false, // mark the flag as deprecated. deprecateAliases: false, // emit deprecation warning anytime a flag alias is provided + noCacheDefault: false, // if true, the value returned by defaultHelp will not be cached in the oclif.manifest.json. dependsOn: ['extra-flag'], // this flag requires another flag exclusive: ['extra-flag'], // this flag cannot be specified alongside this other flag exactlyOne: ['extra-flag', 'another-flag'], // exactly one of these flags must be provided @@ -69,18 +74,19 @@ static flags = { // Include flag-seven but only when flag-eight is equal to FooBar {name: 'flag-seven', when: async (flags) => flags['flag-eight'] === 'FooBar'} ]} - ] + ], + // The following properties cannot be set on boolean flags + helpValue: '', // The flag value to show in help. Defaults to "", + multipleNonGreedy: false, // Parse one value per flag to allow `-m val1 -m val2` but disallow `-m val1 val2`. Only respected if multiple is set to true + delimiter: ',' // Delimiter to separate the values for a multiple value flag. Only respected if multiple is set to true. Default behavior is to separate on spaces. + allowStdin: false, // Allow input value to be read from stdin if the provided value is `-`. Can also be set to `only` to allow flag to always read from stdin even if no value is provided. }), // flag with no value (-f, --force) force: Flags.boolean({ - char: 'f', // short character for flag - default: true, // default value if flag not passed (can be a function that returns a boolean) - env: 'MY_NAME', // default value to the value of an environment variable - // boolean flags may be reversed with `--no-` (in this case: `--no-force`). - // The flag will be set to false if reversed. This functionality - // is disabled by default, to enable it: - // allowNo: true + // Boolean flags take all the same properties described in the previous example + // in addition to: + allowNo: true // Support reversible boolean flag with `--no-` prefix (e.g. `--no-force`). This is disabled by default. }), } ``` @@ -89,7 +95,7 @@ static flags = { For larger CLIs, it can be useful to declare a custom flag that can be shared amongst multiple commands. Here is an example of a custom flag: -```js +```typescript // src/flags.ts import {Flags} from '@oclif/core' @@ -106,7 +112,7 @@ function getTeam(): Promise { export const team = Flags.custom({ char: 't', description: 'team to use', - default: () => getTeam(), + default: async () => getTeam(), }) // src/commands/mycommand.ts @@ -115,7 +121,9 @@ import {Command} from '@oclif/core' export class MyCLI extends Command { static flags = { - team: team(), + team: team({ + required: true, + }), } async run() { @@ -150,3 +158,5 @@ $ mycli -vffoo ``` The last one seems a little odd at first glance, but it's relatively standard in unix and makes commands like `tar -xvzfmytarball.tar.gz` possible. + +See our blog post [CLI Flags Explained](../blog/2019/02/20/cli-flags-explained) for a deeper dive into CLI flags. diff --git a/docs/generator_commands.md b/docs/generator_commands.md index 5a1e7f58..ec5b325e 100644 --- a/docs/generator_commands.md +++ b/docs/generator_commands.md @@ -8,56 +8,98 @@ title: Generator Commands ## `oclif generate NAME` -generate a new CLI +Generate a new CLI ``` USAGE - $ oclif generate [NAME] + $ oclif generate NAME [-y] [--author ] [--bin ] [--description ] [--license ] + [--module-type CommonJS|ESM] [--name ] [--owner ] [--package-manager npm|yarn] [--repository ] + [-d ] ARGUMENTS - NAME directory name of new project + NAME Directory name of new project. + +FLAGS + -d, --output-dir= Directory to build the CLI in. + -y, --yes Use defaults for all prompts. Individual flags will override defaults. + --author= Supply answer for prompt: Author + --bin= Supply answer for prompt: Command bin name the CLI will export + --description= Supply answer for prompt: Description + --license= Supply answer for prompt: License + --module-type=