Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: CLI Changes #580

Closed
Xophmeister opened this issue Jul 13, 2023 · 2 comments · Fixed by #583
Closed

RFC: CLI Changes #580

Xophmeister opened this issue Jul 13, 2023 · 2 comments · Fixed by #583
Assignees
Labels
question Further information is requested type: feature request

Comments

@Xophmeister
Copy link
Member

The current CLI is getting a little complex, as it has grown organically with implemented features, and could afford some "TLC" to make Topiary easier/more streamlined to invoke. As of writing, we have the following usage:

Usage: topiary [OPTIONS] <--language <LANGUAGE>|--input-files [<INPUT_FILES>...]>

Options:
  -l, --language <LANGUAGE>             Which language to parse and format [possible values: json, nickel, ocaml, ocaml-interface, toml]
  -f, --input-files [<INPUT_FILES>...]  Path to an input file or multiple input files. If omitted, or equal to "-", read from standard input. If multiple files are provided, `in_place` is assumed [default: -]
  -q, --query <QUERY>                   Which query file to use
  -o, --output-file <OUTPUT_FILE>       Path to an output file. If omitted, or equal to "-", write to standard output
  -i, --in-place                        Format the input files in place
  -v, --visualise[=<OUTPUT_FORMAT>]     Visualise the syntax tree, rather than format [possible values: json, dot]
  -s, --skip-idempotence                Do not check that formatting twice gives the same output
      --output-configuration            Output the full configuration to stderr before continuing
  -t, --tolerate-parsing-errors         Format as much as possible even if some of the input causes parsing errors
  -h, --help                            Print help
  -V, --version                         Print version

Here we see:

  • At least two modes of operation (formatting and visualisation), with [arguably] a handful of pseudo-modes (version, help and configuration output).
  • The --language argument is a legacy from when Topiary didn't support language detection or multiple files. It still makes sense for formatting stdin, but perhaps shouldn't feature so prominently.
  • In the past, the distinction was between --language, --query and --input-file, where an implicit prioritisation was in place. --query no longer features in this ordering -- it has been demoted, much like --language probably should be (see previous point) -- which, all the same, remains undocumented outside of the sourcecode.
  • With the shift to formatting multiple files, --in-place becomes a little redundant. There is also scope for filtering (see Language selection #561).
  • It's not clear what happens if you try to visualise multiple input files from this documentation, alone.

I propose the following:

  • Modes can be separated using subcommands, as is the style of the time. I don't think I'm going out on a limb to say that "formatting" is going to be the predominant mode; therefore, this can be the default if no subcommand is issued.
  • Topiary's default resource to act upon will be files -- plural -- which are updated in place. As such, these should be positional arguments, rather than specified through a flag. stdin-to-stdout is a special case, that can be assumed in the absence of any file arguments and the appropriate --language/--query argument. (For the niche case of non-in-place formatting, we'd just fallback to the stdin-to-stdout case and expect the user to employ IO redirection.)
  • Options can be grouped into two camps: global options and subcommand-specific options.

As such, we have (approximately) the following general form:

topiary [GLOBAL OPTIONS] [SUBCOMMAND] [SUBCOMMAND OPTIONS] [FILE...]

⚠️ Contingent upon what can be achieved with Clap (or similar).
❓ Should --language and --query be specifiable as a fallback, should language detection fail? My understanding is that the configuration file should preclude this problem, as that specifies the extension-to-language mapping; thus (AFAIK) language detection should be infallible.

Global Options

  • --tolerate-parsing-errors is the only global option that currently makes sense.

💡 There's no need for the global options to appear strictly before the subcommand, etc.

Formatting: fmt

This is the default subcommand, as such it can be omitted:

topiary \
  [GLOBAL OPTIONS] \
  [fmt] \
  [ --skip-idempotence ] \
  ( --language LANGUAGE | --query QUERY | FILE... )

Examples:

$ topiary *.ncl
$ find . -type f -name "*.ml" -exec topiary fmt --skip-idempotence {} \+
$ topiary --language bash </path/to/some.sh >/path/to/formatted.sh 

💡 File type filtering arguments could be implemented here, for example:

$ topiary --exclude "*.sh" **/*

❓ Could --language be overloaded in the FILE... case to act as a filter, or is this too magical?

Visualisation: vis

topiary \
  [GLOBAL OPTIONS] \
  vis \
  [ --format FORMAT ] \
  ( --language LANGUAGE | --query QUERY | FILE )
  • --format maps to the current --visualise, with DOT made the default (rather than JSON).
  • Only a single input can be formatted, which can be specified as a FILE, or via stdin (using the same rules as fmt).
  • The output is always written to stdout.

Example:

$ topiary vis output.json | dot -Tpdf > output.pdf

Configuration: cfg

💡 Current global options don't make sense here. A global option to specify a different configuration source would change that, for example.

topiary [GLOBAL OPTIONS] cfg

Output the current configuration to stdout (analogous to the current --output-configuration).

Version: version

💡 Global options don't make sense here.

topiary version

Output the Topiary version to stdout.

Help

Every subcommand and the bare invocation will have a --help. (Note that, on the bare invocation, topiary --help should show top-level help, rather than the help for the fmt subcommand.)

Subcommand Aliases

Subcommand Aliases
fmt ∅, format
vis visualise, visualize
cfg config
@Xophmeister Xophmeister self-assigned this Jul 13, 2023
@Xophmeister Xophmeister added the question Further information is requested label Jul 13, 2023
@Xophmeister
Copy link
Member Author

(n.b., I've omitted short-options for brevity/clarity; they'd also be included.)

@aspiwack
Copy link
Member

topiary version

I believe that most today expect that topiary --version outputs the version number, so let's try to have that too (in addition to topiary version if you think it's a good idea to have that).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested type: feature request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants