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

Add usage instructions for spec runner to compiler #10046

Conversation

straight-shoota
Copy link
Member

@straight-shoota straight-shoota commented Dec 7, 2020

Currently, crystal spec --help only shows compile time options. The runtime options are missing and only show up once you have compiled a spec runner.

This separation has technical reasons but results in aweful user experience. crystal spec presents itself as an holistic interface for running specs and transparently delegates runtime options to the executable. You can pass runtime options directly to crystal spec, but they don't show up in the usage overview. So many of the options are hidden to the user. You only discover them if you are aware of running crystal spec -- --help.

This is the old (separate) output:

$ crystal spec --help
Usage: crystal spec [options] [files]

Options:
    -d, --debug                      Add full symbolic debug info
    --no-debug                       Skip any symbolic debug info
    -D FLAG, --define FLAG           Define a compile-time flag
    --error-trace                    Show full error trace
    --release                        Compile in release mode
    -s, --stats                      Enable statistics output
    -p, --progress                   Enable progress output
    -t, --time                       Enable execution time output
    -h, --help                       Show this message
    --no-color                       Disable colored output
    --warnings all|none              Which warnings detect. (default: all)
    --error-on-warnings              Treat warnings as errors.
    --exclude-warnings <path>        Exclude warnings from path (default: lib)
$ crystal run spec.cr -- --help
crystal spec runner
    -e , --example STRING            run examples whose full nested names include STRING
    -l , --line LINE                 run examples whose line matches LINE
    -p, --profile                    Print the 10 slowest specs
    --fail-fast                      abort the run on first failure
    --location file:line             run example at line 'line' in file 'file', multiple allowed
    --tag TAG                        run examples with the specified TAG, or exclude examples by adding ~ before the TAG.
    --order MODE                     run examples in random order by passing MODE as 'random' or to a specific seed by passing MODE as the seed value
    --junit_output OUTPUT_PATH       generate JUnit XML output within the given OUTPUT_PATH
    -h, --help                       show this help
    -v, --verbose                    verbose output
    --tap                            Generate TAP output (Test Anything Protocol)
    --no-color                       Disable colored output

With this patch the usage instructions for the spec runner are included in the usage instractions for the compiler spec command.

The actual OptionParser from stdlib is used for that to avoid maintaining different instructions and have them slip out of sync. There would only be a discrepancy when the compiled stdlib version has different options than the one the compiler was built with. But that's acceptable.
The only option to avoid that would be to compile or somehow extract the information from Spec module from stdlib source. This could be more feasible if a textual representation like docopt was used instead of OptionParser builing it at runtime.

In order to not include large parts of the Spec module in the compiler, the option parser configuration has been extracted to src/spec/cli.cr in a way that it does not rely on any other spec feature. The only intricacy is setting up the formatters. I've introduced Spec.configure_formatter for this which has a blank implementation in cli.cr and the real one in spec.cr overrides it for actual use.

New output of crystal spec --help:

Usage: crystal spec [options] [files]

Options:
    -d, --debug                      Add full symbolic debug info
    --no-debug                       Skip any symbolic debug info
    -D FLAG, --define FLAG           Define a compile-time flag
    --error-trace                    Show full error trace
    --release                        Compile in release mode
    -s, --stats                      Enable statistics output
    -p, --progress                   Enable progress output
    -t, --time                       Enable execution time output
    -h, --help                       Show this message
    --no-color                       Disable colored output
    --warnings all|none              Which warnings detect. (default: all)
    --error-on-warnings              Treat warnings as errors.
    --exclude-warnings <path>        Exclude warnings from path (default: lib)
    -h, --help                       Show this message

Runtime options (passed to spec runner):
    -e , --example STRING            run examples whose full nested names include STRING
    -l , --line LINE                 run examples whose line matches LINE
    -p, --profile                    Print the 10 slowest specs
    --fail-fast                      abort the run on first failure
    --location file:line             run example at line 'line' in file 'file', multiple allowed
    --tag TAG                        run examples with the specified TAG, or exclude examples by adding ~ before the TAG.
    --order MODE                     run examples in random order by passing MODE as 'random' or to a specific seed by passing MODE as the seed value
    --junit_output OUTPUT_PATH       generate JUnit XML output within the given OUTPUT_PATH
    -h, --help                       show this help
    -v, --verbose                    verbose output
    --tap                            Generate TAP output (Test Anything Protocol)
    --no-color                       Disable colored output

@straight-shoota straight-shoota force-pushed the feature/compiler-spec-options branch from 989e15d to efd4a3c Compare December 7, 2020 00:09
src/spec/cli.cr Outdated Show resolved Hide resolved
@Fryguy
Copy link
Contributor

Fryguy commented Jan 12, 2021

This is awesome! I had a very similar refactoring locally (which included a lot more than just the CLI), so I'm very happy to see this.

class Crystal::Command
private def spec
compiler = new_compiler
link_flags = [] of String
OptionParser.parse(options) do |opts|
opts.banner = "Usage: crystal spec [options] [files]\n\nOptions:"
opts.banner = "Usage: crystal spec [options] [files] [-- runtime_options]\n\nOptions:"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The runtime_options can be passed before the file, there is no need to use -- to split them. Wouldn't that be the preferred way to advertise them?

In that line of thought I would call the "Spec runner additional options" or somehing like that.
I find it confusing that they are presented as "Runtime options"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the -- can be removed. I'd still leave it as [options] [files] [runtime_options] even though they can be mixed. Don't think there's a better way to do this and this makes at least sense from a structural PoV.

Naming is particularly hard with this one. I'm not convinced Spec runner additional options improves it, though. I would have more questions about that than Runtime options which is really just a factual description. Those are the options evaluated at runtime by the spec runner, the others are compiler options.

@straight-shoota
Copy link
Member Author

straight-shoota commented Mar 13, 2021

I would love to see this in 1.0 as it's a really nice and cheap enhancement for developer convenience.

Copy link
Member

@sdogruyol sdogruyol left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow thank you @straight-shoota, this is great developer UX 💯 I'd also love to see this land in 1.0 if possible 🤔

@straight-shoota straight-shoota added this to the 1.1.0 milestone Mar 23, 2021
@straight-shoota straight-shoota merged commit e5667c0 into crystal-lang:master Mar 30, 2021
@straight-shoota straight-shoota deleted the feature/compiler-spec-options branch March 30, 2021 09:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants