Skip to content

Instantly share code, notes, and snippets.

@jdx
Last active August 14, 2023 22:58
Show Gist options
  • Save jdx/ebb80d8e172d4e4b5ac53a19279395fe to your computer and use it in GitHub Desktop.
Save jdx/ebb80d8e172d4e4b5ac53a19279395fe to your computer and use it in GitHub Desktop.
# this is an example "usage" definition
# it defines a subset of the tool "rtx". What syntax it uses for CLI arguments
# as well as how it interacts with env vars and config files
# usage can be thought of as "swagger for CLIs"
# The purpose is that having a language-agnostic definition for CLIs we can
# build tools like generic autocompletion (so you don't need to learn how to write complex bash/zsh completions)
# It would also allow us to build documentation tools (browser or CLI), scaffold out CLIs, and build
# parsing/validation libraries to make CLI development faster.
# CLI parsing starts here. This is close, but probably not identical to docopt.
# Components like "[GLOBAL_OPTIONS]" will be replaced with everything under that key
# as potential options.
USAGE = {options="[GLOBAL_OPTIONS]", subcommand="<COMMAND>"}
# this can be thought of as equivalent to this docopt syntax:
# [-v --verbose -h --help -V --verbose]
GLOBAL_OPTIONS = [
"-v, --verbose Verbose mode",
"-h, --help Display help",
"-V, --version Display version",
]
[COMMAND]
install = {options="[INSTALL_OPTIONS]", args="<TOOL_VERSION>..."}
plugins = {options="[PLUGINS_OPTIONS]", subcommand="[PLUGINS_COMMAND]"}
[PLUGINS_COMMAND]
install = {options="[PLUGINS_INSTALL_OPTIONS]", args="<PLUGIN_NAME>..."}
INSTALL_OPTIONS = [
"[GLOBAL_OPTIONS]", # in this CLI, the global options can appear anywhere
"-f, --force Force install",
"-p, --path=PATH Install path",
"-j, --jobs=JOBS Number of jobs [default: 4]",
# the above can also be represented structurally instead of using docopt
{short="j", long="jobs", has_value="JOBS", description="Number of jobs", default="4"}
]
# defines properties about the value of --jobs=JOBS
[JOBS]
env = "RTX_JOBS" # if $RTX_JOBS is set, use that
config_file = "settings.jobs" # if .rtx.toml defines settings.jobs, use that
validate_regex = "^[1-9][0-9]*$" # ensure it's a number
[PLUGIN_NAME]
# this will be executed with the following to gather autocomplete options
# USAGE_ARGV="rtx plugins install py"
# USAGE_ARG_IDX="3" - the cursor position of the argument
# USAGE_CHAR_IDX="2" - the cursor position of the character within the argument
external = "rtx plugins list --all"
# defines a hierarchy of config files to parse
# these will be parsed and merged so effectively
# lower ones take priority
_CONFIG_FILE = [
"$HOME/.rtx/config.toml", # supports env vars
"findup:.rtx.toml", # gathers all ".rtx.toml" files in parent directories in order
]
# TODO: how could env var, or config settings be represented when they are _not_
# backed by a flag?
[_ENV]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment