├── .clippy.toml ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ └── feature_request.yml ├── PULL_REQUEST_TEMPLATE.md ├── renovate.json5 ├── settings.yml └── workflows │ ├── audit.yml │ ├── bench-baseline.yml │ ├── ci.yml │ ├── committed.yml │ ├── post-release.yml │ ├── pre-commit.yml │ ├── release-notes.py │ ├── rust-next.yml │ └── spelling.yml ├── .gitignore ├── .pre-commit-config.yaml ├── CHANGELOG.md ├── CITATION.cff ├── CONTRIBUTING.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── Makefile ├── README.md ├── assets └── clap.png ├── clap_bench ├── Cargo.toml ├── benches │ ├── complex.rs │ ├── empty.rs │ ├── ripgrep.rs │ ├── rustup.rs │ └── simple.rs └── src │ └── lib.rs ├── clap_builder ├── CONTRIBUTING.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md └── src │ ├── builder │ ├── action.rs │ ├── app_settings.rs │ ├── arg.rs │ ├── arg_group.rs │ ├── arg_predicate.rs │ ├── arg_settings.rs │ ├── command.rs │ ├── debug_asserts.rs │ ├── ext.rs │ ├── mod.rs │ ├── os_str.rs │ ├── possible_value.rs │ ├── range.rs │ ├── resettable.rs │ ├── str.rs │ ├── styled_str.rs │ ├── styling.rs │ ├── tests.rs │ ├── value_hint.rs │ └── value_parser.rs │ ├── derive.rs │ ├── error │ ├── context.rs │ ├── format.rs │ ├── kind.rs │ └── mod.rs │ ├── lib.rs │ ├── macros.rs │ ├── mkeymap.rs │ ├── output │ ├── fmt.rs │ ├── help.rs │ ├── help_template.rs │ ├── mod.rs │ ├── textwrap │ │ ├── core.rs │ │ ├── mod.rs │ │ ├── word_separators.rs │ │ └── wrap_algorithms.rs │ └── usage.rs │ ├── parser │ ├── arg_matcher.rs │ ├── error.rs │ ├── features │ │ ├── mod.rs │ │ └── suggestions.rs │ ├── matches │ │ ├── arg_matches.rs │ │ ├── matched_arg.rs │ │ ├── mod.rs │ │ └── value_source.rs │ ├── mod.rs │ ├── parser.rs │ └── validator.rs │ └── util │ ├── any_value.rs │ ├── color.rs │ ├── flat_map.rs │ ├── flat_set.rs │ ├── graph.rs │ ├── id.rs │ ├── mod.rs │ └── str_to_bool.rs ├── clap_complete ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── examples │ ├── completion-derive.rs │ ├── completion.rs │ ├── dynamic.rs │ └── exhaustive.rs ├── src │ ├── aot │ │ ├── generator │ │ │ ├── mod.rs │ │ │ └── utils.rs │ │ ├── mod.rs │ │ └── shells │ │ │ ├── bash.rs │ │ │ ├── elvish.rs │ │ │ ├── fish.rs │ │ │ ├── mod.rs │ │ │ ├── powershell.rs │ │ │ ├── shell.rs │ │ │ └── zsh.rs │ ├── engine │ │ ├── candidate.rs │ │ ├── complete.rs │ │ ├── custom.rs │ │ └── mod.rs │ ├── env │ │ ├── mod.rs │ │ └── shells.rs │ ├── lib.rs │ └── macros.rs └── tests │ ├── examples.rs │ ├── snapshots │ ├── aliases.bash │ ├── aliases.elvish │ ├── aliases.fish │ ├── aliases.ps1 │ ├── aliases.zsh │ ├── basic.bash │ ├── basic.elvish │ ├── basic.fish │ ├── basic.ps1 │ ├── basic.zsh │ ├── custom_bin_name.bash │ ├── custom_bin_name.elvish │ ├── custom_bin_name.fish │ ├── custom_bin_name.ps1 │ ├── custom_bin_name.zsh │ ├── feature_sample.bash │ ├── feature_sample.elvish │ ├── feature_sample.fish │ ├── feature_sample.ps1 │ ├── feature_sample.zsh │ ├── home │ │ ├── .gitignore │ │ ├── dynamic-env │ │ │ └── exhaustive │ │ │ │ ├── bash │ │ │ │ └── .bashrc │ │ │ │ ├── elvish │ │ │ │ └── elvish │ │ │ │ │ └── rc.elv │ │ │ │ ├── fish │ │ │ │ └── fish │ │ │ │ │ ├── completions │ │ │ │ │ └── exhaustive.fish │ │ │ │ │ └── config.fish │ │ │ │ └── zsh │ │ │ │ ├── .zshenv │ │ │ │ └── zsh │ │ │ │ └── _exhaustive │ │ └── static │ │ │ └── exhaustive │ │ │ ├── bash │ │ │ ├── .bashrc │ │ │ └── .inputrc │ │ │ ├── elvish │ │ │ └── elvish │ │ │ │ └── rc.elv │ │ │ ├── fish │ │ │ └── fish │ │ │ │ ├── completions │ │ │ │ └── exhaustive.fish │ │ │ │ └── config.fish │ │ │ ├── powershell │ │ │ └── powershell │ │ │ │ └── Microsoft.PowerShell_profile.ps1 │ │ │ └── zsh │ │ │ ├── .zshenv │ │ │ └── zsh │ │ │ └── _exhaustive │ ├── quoting.bash │ ├── quoting.elvish │ ├── quoting.fish │ ├── quoting.ps1 │ ├── quoting.zsh │ ├── register_dynamic.fish │ ├── register_minimal.bash │ ├── special_commands.bash │ ├── special_commands.elvish │ ├── special_commands.fish │ ├── special_commands.ps1 │ ├── special_commands.zsh │ ├── sub_subcommands.bash │ ├── sub_subcommands.elvish │ ├── sub_subcommands.fish │ ├── sub_subcommands.ps1 │ ├── sub_subcommands.zsh │ ├── subcommand_last.bash │ ├── subcommand_last.elvish │ ├── subcommand_last.fish │ ├── subcommand_last.ps1 │ ├── subcommand_last.zsh │ ├── two_multi_valued_arguments.bash │ ├── two_multi_valued_arguments.elvish │ ├── two_multi_valued_arguments.fish │ ├── two_multi_valued_arguments.ps1 │ ├── two_multi_valued_arguments.zsh │ ├── value_hint.bash │ ├── value_hint.elvish │ ├── value_hint.fish │ ├── value_hint.ps1 │ ├── value_hint.zsh │ ├── value_terminator.bash │ ├── value_terminator.elvish │ ├── value_terminator.fish │ ├── value_terminator.ps1 │ └── value_terminator.zsh │ └── testsuite │ ├── bash.rs │ ├── common.rs │ ├── elvish.rs │ ├── engine.rs │ ├── fish.rs │ ├── general.rs │ ├── main.rs │ ├── powershell.rs │ └── zsh.rs ├── clap_complete_nushell ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── examples │ ├── nushell_completion.rs │ ├── sub_subcommands.rs │ └── test.rs ├── src │ └── lib.rs └── tests │ ├── common.rs │ ├── completion.rs │ ├── nushell.rs │ └── snapshots │ ├── aliases.nu │ ├── basic.nu │ ├── feature_sample.nu │ ├── home │ └── static │ │ └── test │ │ └── nu │ │ └── .config │ │ └── nushell │ │ ├── completions │ │ └── test.nu │ │ └── config.nu │ ├── quoting.nu │ ├── special_commands.nu │ ├── sub_subcommands.nu │ └── value_hint.nu ├── clap_derive ├── CONTRIBUTING.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md └── src │ ├── attr.rs │ ├── derives │ ├── args.rs │ ├── into_app.rs │ ├── mod.rs │ ├── parser.rs │ ├── subcommand.rs │ └── value_enum.rs │ ├── dummies.rs │ ├── item.rs │ ├── lib.rs │ ├── macros.rs │ └── utils │ ├── doc_comments.rs │ ├── error.rs │ ├── mod.rs │ ├── spanned.rs │ └── ty.rs ├── clap_lex ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── src │ ├── ext.rs │ └── lib.rs └── tests │ └── testsuite │ ├── lexer.rs │ ├── main.rs │ ├── parsed.rs │ └── shorts.rs ├── clap_mangen ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── examples │ └── man.rs ├── src │ ├── lib.rs │ └── render.rs └── tests │ ├── snapshots │ ├── aliases.bash.roff │ ├── basic.bash.roff │ ├── feature_sample.bash.roff │ ├── help_headings.bash.roff │ ├── hidden_option.bash.roff │ ├── possible_values.bash.roff │ ├── quoting.bash.roff │ ├── special_commands.bash.roff │ ├── sub_subcommand_help.roff │ ├── sub_subcommands.bash.roff │ ├── value_env.bash.roff │ ├── value_hint.bash.roff │ └── value_name_without_arg.bash.roff │ └── testsuite │ ├── common.rs │ ├── main.rs │ └── roff.rs ├── committed.toml ├── deny.toml ├── examples ├── README.md ├── cargo-example-derive.md ├── cargo-example-derive.rs ├── cargo-example.md ├── cargo-example.rs ├── demo.md ├── demo.rs ├── derive_ref │ ├── augment_args.rs │ ├── augment_subcommands.rs │ ├── flatten_hand_args.rs │ ├── hand_subcommand.rs │ └── interop_tests.md ├── escaped-positional-derive.md ├── escaped-positional-derive.rs ├── escaped-positional.md ├── escaped-positional.rs ├── find.md ├── find.rs ├── git-derive.md ├── git-derive.rs ├── git.md ├── git.rs ├── multicall-busybox.md ├── multicall-busybox.rs ├── multicall-hostname.md ├── multicall-hostname.rs ├── pacman.md ├── pacman.rs ├── repl-derive.rs ├── repl.rs ├── tutorial_builder │ ├── 01_quick.md │ ├── 01_quick.rs │ ├── 02_app_settings.md │ ├── 02_app_settings.rs │ ├── 02_apps.md │ ├── 02_apps.rs │ ├── 02_crate.md │ ├── 02_crate.rs │ ├── 03_01_flag_bool.md │ ├── 03_01_flag_bool.rs │ ├── 03_01_flag_count.md │ ├── 03_01_flag_count.rs │ ├── 03_02_option.md │ ├── 03_02_option.rs │ ├── 03_02_option_mult.md │ ├── 03_02_option_mult.rs │ ├── 03_03_positional.md │ ├── 03_03_positional.rs │ ├── 03_03_positional_mult.md │ ├── 03_03_positional_mult.rs │ ├── 03_04_subcommands.md │ ├── 03_04_subcommands.rs │ ├── 03_05_default_values.md │ ├── 03_05_default_values.rs │ ├── 03_06_required.md │ ├── 03_06_required.rs │ ├── 04_01_enum.md │ ├── 04_01_enum.rs │ ├── 04_01_possible.md │ ├── 04_01_possible.rs │ ├── 04_02_parse.md │ ├── 04_02_parse.rs │ ├── 04_02_validate.md │ ├── 04_02_validate.rs │ ├── 04_03_relations.md │ ├── 04_03_relations.rs │ ├── 04_04_custom.md │ ├── 04_04_custom.rs │ └── 05_01_assert.rs ├── tutorial_derive │ ├── 01_quick.md │ ├── 01_quick.rs │ ├── 02_app_settings.md │ ├── 02_app_settings.rs │ ├── 02_apps.md │ ├── 02_apps.rs │ ├── 02_crate.md │ ├── 02_crate.rs │ ├── 03_01_flag_bool.md │ ├── 03_01_flag_bool.rs │ ├── 03_01_flag_count.md │ ├── 03_01_flag_count.rs │ ├── 03_02_option.md │ ├── 03_02_option.rs │ ├── 03_02_option_mult.md │ ├── 03_02_option_mult.rs │ ├── 03_03_positional.md │ ├── 03_03_positional.rs │ ├── 03_03_positional_mult.md │ ├── 03_03_positional_mult.rs │ ├── 03_04_subcommands.md │ ├── 03_04_subcommands.rs │ ├── 03_04_subcommands_alt.rs │ ├── 03_05_default_values.md │ ├── 03_05_default_values.rs │ ├── 03_06_optional.md │ ├── 03_06_optional.rs │ ├── 04_01_enum.md │ ├── 04_01_enum.rs │ ├── 04_02_parse.md │ ├── 04_02_parse.rs │ ├── 04_02_validate.md │ ├── 04_02_validate.rs │ ├── 04_03_relations.md │ ├── 04_03_relations.rs │ ├── 04_04_custom.md │ ├── 04_04_custom.rs │ └── 05_01_assert.rs ├── typed-derive.md └── typed-derive.rs ├── release.toml ├── src ├── _cookbook │ ├── cargo_example.rs │ ├── cargo_example_derive.rs │ ├── escaped_positional.rs │ ├── escaped_positional_derive.rs │ ├── find.rs │ ├── git.rs │ ├── git_derive.rs │ ├── mod.rs │ ├── multicall_busybox.rs │ ├── multicall_hostname.rs │ ├── pacman.rs │ ├── repl.rs │ ├── repl_derive.rs │ └── typed_derive.rs ├── _derive │ ├── _tutorial.rs │ └── mod.rs ├── _faq.rs ├── _features.rs ├── _tutorial.rs ├── bin │ └── stdio-fixture.rs └── lib.rs ├── tests ├── builder │ ├── action.rs │ ├── app_settings.rs │ ├── arg_aliases.rs │ ├── arg_aliases_short.rs │ ├── arg_matches.rs │ ├── borrowed.rs │ ├── cargo.rs │ ├── command.rs │ ├── conflicts.rs │ ├── default_missing_vals.rs │ ├── default_vals.rs │ ├── delimiters.rs │ ├── derive_order.rs │ ├── display_order.rs │ ├── double_require.rs │ ├── empty_values.rs │ ├── env.rs │ ├── error.rs │ ├── flag_subcommands.rs │ ├── flags.rs │ ├── global_args.rs │ ├── groups.rs │ ├── help.rs │ ├── help_env.rs │ ├── hidden_args.rs │ ├── ignore_errors.rs │ ├── indices.rs │ ├── main.rs │ ├── multiple_occurrences.rs │ ├── multiple_values.rs │ ├── occurrences.rs │ ├── opts.rs │ ├── positionals.rs │ ├── posix_compatible.rs │ ├── possible_values.rs │ ├── propagate_globals.rs │ ├── require.rs │ ├── subcommands.rs │ ├── template_help.rs │ ├── tests.rs │ ├── unicode.rs │ ├── unique_args.rs │ ├── utf16.rs │ ├── utf8.rs │ ├── utils.rs │ └── version.rs ├── derive │ ├── app_name.rs │ ├── arguments.rs │ ├── author_version_about.rs │ ├── basic.rs │ ├── boxed.rs │ ├── custom_string_parsers.rs │ ├── default_value.rs │ ├── deny_warnings.rs │ ├── doc_comments_help.rs │ ├── explicit_name_no_renaming.rs │ ├── flags.rs │ ├── flatten.rs │ ├── generic.rs │ ├── groups.rs │ ├── help.rs │ ├── issues.rs │ ├── macros.rs │ ├── main.rs │ ├── markdown.rs │ ├── naming.rs │ ├── nested_subcommands.rs │ ├── non_literal_attributes.rs │ ├── occurrences.rs │ ├── options.rs │ ├── privacy.rs │ ├── raw_bool_literal.rs │ ├── raw_idents.rs │ ├── rename_all_env.rs │ ├── skip.rs │ ├── snapshots │ │ ├── blocks.term.svg │ │ ├── headers.term.svg │ │ ├── html.term.svg │ │ ├── inline_styles.term.svg │ │ ├── links.term.svg │ │ ├── lists.term.svg │ │ └── paragraphs.term.svg │ ├── subcommands.rs │ ├── type_alias_regressions.rs │ ├── utf8.rs │ ├── utils.rs │ └── value_enum.rs ├── derive_ui.rs ├── derive_ui │ ├── bool_value_enum.rs │ ├── bool_value_enum.stderr │ ├── clap_empty_attr.rs │ ├── clap_empty_attr.stderr │ ├── default_value_t_invalid.rs │ ├── default_value_t_invalid.stderr │ ├── default_values_t_invalid.rs │ ├── default_values_t_invalid.stderr │ ├── enum_flatten.rs │ ├── enum_flatten.stderr │ ├── enum_variant_not_args.rs │ ├── enum_variant_not_args.stderr │ ├── external_subcommand_misuse.rs │ ├── external_subcommand_misuse.stderr │ ├── external_subcommand_wrong_type.rs │ ├── external_subcommand_wrong_type.stderr │ ├── flatten_and_methods.rs │ ├── flatten_and_methods.stderr │ ├── flatten_enum_in_struct.rs │ ├── flatten_enum_in_struct.stderr │ ├── flatten_struct_in_enum.rs │ ├── flatten_struct_in_enum.stderr │ ├── group_name_attribute.rs │ ├── group_name_attribute.stderr │ ├── multiple_external_subcommand.rs │ ├── multiple_external_subcommand.stderr │ ├── non_existent_attr.rs │ ├── non_existent_attr.stderr │ ├── rename_all_wrong_casing.rs │ ├── rename_all_wrong_casing.stderr │ ├── skip_flatten.rs │ ├── skip_flatten.stderr │ ├── skip_subcommand.rs │ ├── skip_subcommand.stderr │ ├── skip_with_other_options.rs │ ├── skip_with_other_options.stderr │ ├── skip_without_default.rs │ ├── skip_without_default.stderr │ ├── struct_subcommand.rs │ ├── struct_subcommand.stderr │ ├── subcommand_and_flatten.rs │ ├── subcommand_and_flatten.stderr │ ├── subcommand_and_methods.rs │ ├── subcommand_and_methods.stderr │ ├── subcommand_on_struct.rs │ ├── subcommand_on_struct.stderr │ ├── subcommand_opt_opt.rs │ ├── subcommand_opt_opt.stderr │ ├── subcommand_opt_vec.rs │ ├── subcommand_opt_vec.stderr │ ├── tuple_struct.rs │ ├── tuple_struct.stderr │ ├── value_enum_non_unit.rs │ ├── value_enum_non_unit.stderr │ ├── value_enum_on_struct.rs │ ├── value_enum_on_struct.stderr │ ├── value_parser_unsupported.rs │ └── value_parser_unsupported.stderr ├── examples.rs ├── macros.rs ├── ui.rs └── ui │ ├── V_flag_stdout.toml │ ├── arg_required_else_help_stderr.toml │ ├── error_stderr.toml │ ├── h_flag_stdout.toml │ ├── help_cmd_stdout.toml │ ├── help_flag_stdout.toml │ └── version_flag_stdout.toml └── typos.toml /.clippy.toml: -------------------------------------------------------------------------------- 1 | allow-print-in-tests = true 2 | allow-expect-in-tests = true 3 | allow-unwrap-in-tests = true 4 | allow-dbg-in-tests = true 5 | disallowed-methods = [ 6 | { path = "std::option::Option::map_or", reason = "prefer `map(..).unwrap_or(..)` for legibility" }, 7 | { path = "std::option::Option::map_or_else", reason = "prefer `map(..).unwrap_or_else(..)` for legibility" }, 8 | { path = "std::result::Result::map_or", reason = "prefer `map(..).unwrap_or(..)` for legibility" }, 9 | { path = "std::result::Result::map_or_else", reason = "prefer `map(..).unwrap_or_else(..)` for legibility" }, 10 | { path = "std::iter::Iterator::for_each", reason = "prefer `for` for side-effects" }, 11 | { path = "std::iter::Iterator::try_for_each", reason = "prefer `for` for side-effects" }, 12 | ] 13 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: clap-rs 2 | open_collective: clap 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | contact_links: 3 | - name: Ask a question 4 | about: For support or brainstorming 5 | url: https://github.com/clap-rs/clap/discussions/new 6 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /.github/workflows/audit.yml: -------------------------------------------------------------------------------- 1 | name: Security audit 2 | 3 | permissions: 4 | contents: read 5 | 6 | on: 7 | pull_request: 8 | paths: 9 | - '**/Cargo.toml' 10 | - '**/Cargo.lock' 11 | push: 12 | branches: 13 | - master 14 | 15 | env: 16 | RUST_BACKTRACE: 1 17 | CARGO_TERM_COLOR: always 18 | CLICOLOR: 1 19 | 20 | concurrency: 21 | group: "${{ github.workflow }}-${{ github.ref }}" 22 | cancel-in-progress: true 23 | 24 | jobs: 25 | security_audit: 26 | permissions: 27 | issues: write # to create issues (actions-rs/audit-check) 28 | checks: write # to create check (actions-rs/audit-check) 29 | runs-on: ubuntu-latest 30 | # Prevent sudden announcement of a new advisory from failing ci: 31 | continue-on-error: true 32 | steps: 33 | - name: Checkout repository 34 | uses: actions/checkout@v4 35 | - uses: actions-rs/audit-check@v1 36 | with: 37 | token: ${{ secrets.GITHUB_TOKEN }} 38 | 39 | cargo_deny: 40 | permissions: 41 | issues: write # to create issues (actions-rs/audit-check) 42 | checks: write # to create check (actions-rs/audit-check) 43 | runs-on: ubuntu-latest 44 | strategy: 45 | matrix: 46 | checks: 47 | - bans licenses sources 48 | steps: 49 | - uses: actions/checkout@v4 50 | - uses: EmbarkStudios/cargo-deny-action@v2 51 | with: 52 | command: check ${{ matrix.checks }} 53 | rust-version: stable 54 | -------------------------------------------------------------------------------- /.github/workflows/bench-baseline.yml: -------------------------------------------------------------------------------- 1 | name: Benchmark Baseline 2 | 3 | permissions: 4 | contents: read 5 | 6 | on: 7 | push: 8 | branches: master 9 | 10 | jobs: 11 | bench: 12 | name: Binary Size 13 | permissions: 14 | checks: write 15 | strategy: 16 | matrix: 17 | build: [linux] 18 | include: 19 | - build: linux 20 | os: buildjet-8vcpu-ubuntu-2204 21 | runs-on: "${{ matrix.os }}" 22 | steps: 23 | - name: Checkout repository 24 | uses: actions/checkout@v4 25 | - name: Install Rust 26 | uses: dtolnay/rust-toolchain@stable 27 | with: 28 | toolchain: stable 29 | - uses: Swatinem/rust-cache@v2 30 | - name: Install Bencher 31 | uses: bencherdev/bencher@main 32 | - name: Build 33 | run: "cargo build --package clap --example git-derive -F derive --release" 34 | env: 35 | CARGO_PROFILE_RELEASE_STRIP: true 36 | - name: Report 37 | run: | 38 | bencher run \ 39 | --project $(echo "${{ github.repository }}" | sed 's/\//-/g') \ 40 | --branch "${{ github.ref_name }}" \ 41 | --testbed "${{ matrix.os }}" \ 42 | --token '${{ secrets.BENCHER_API_TOKEN }}' \ 43 | --github-actions '${{ secrets.GITHUB_TOKEN }}' \ 44 | --adapter json \ 45 | --file-size target/release/examples/git-derive 46 | -------------------------------------------------------------------------------- /.github/workflows/committed.yml: -------------------------------------------------------------------------------- 1 | # Not run as part of pre-commit checks because they don't handle sending the correct commit 2 | # range to `committed` 3 | name: Lint Commits 4 | on: [pull_request] 5 | 6 | permissions: 7 | contents: read 8 | 9 | env: 10 | RUST_BACKTRACE: 1 11 | CARGO_TERM_COLOR: always 12 | CLICOLOR: 1 13 | 14 | concurrency: 15 | group: "${{ github.workflow }}-${{ github.ref }}" 16 | cancel-in-progress: true 17 | 18 | jobs: 19 | committed: 20 | name: Lint Commits 21 | runs-on: ubuntu-latest 22 | steps: 23 | - name: Checkout Actions Repository 24 | uses: actions/checkout@v4 25 | with: 26 | fetch-depth: 0 27 | - name: Lint Commits 28 | uses: crate-ci/committed@master 29 | -------------------------------------------------------------------------------- /.github/workflows/post-release.yml: -------------------------------------------------------------------------------- 1 | name: post-release 2 | on: 3 | push: 4 | tags: 5 | - "v*" 6 | permissions: 7 | contents: read 8 | 9 | jobs: 10 | create-release: 11 | permissions: 12 | contents: write # for actions/create-release to create a release 13 | name: create-release 14 | runs-on: ubuntu-latest 15 | outputs: 16 | upload_url: ${{ steps.release.outputs.upload_url }} 17 | release_version: ${{ env.RELEASE_VERSION }} 18 | steps: 19 | - name: Get the release version from the tag 20 | shell: bash 21 | if: env.RELEASE_VERSION == '' 22 | run: | 23 | # See: https://github.community/t5/GitHub-Actions/How-to-get-just-the-tag-name/m-p/32167/highlight/true#M1027 24 | echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV 25 | echo "version is: ${{ env.RELEASE_VERSION }}" 26 | - name: Checkout repository 27 | uses: actions/checkout@v4 28 | with: 29 | fetch-depth: 1 30 | - name: Generate Release Notes 31 | run: | 32 | ./.github/workflows/release-notes.py --tag ${{ env.RELEASE_VERSION }} --output notes-${{ env.RELEASE_VERSION }}.md 33 | cat notes-${{ env.RELEASE_VERSION }}.md 34 | - name: Create GitHub release 35 | id: release 36 | uses: actions/create-release@v1 37 | env: 38 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 39 | with: 40 | tag_name: ${{ env.RELEASE_VERSION }} 41 | release_name: ${{ env.RELEASE_VERSION }} 42 | body_path: notes-${{ env.RELEASE_VERSION }}.md 43 | -------------------------------------------------------------------------------- /.github/workflows/pre-commit.yml: -------------------------------------------------------------------------------- 1 | name: pre-commit 2 | 3 | permissions: {} # none 4 | 5 | on: 6 | pull_request: 7 | push: 8 | branches: [master] 9 | 10 | env: 11 | RUST_BACKTRACE: 1 12 | CARGO_TERM_COLOR: always 13 | CLICOLOR: 1 14 | 15 | concurrency: 16 | group: "${{ github.workflow }}-${{ github.ref }}" 17 | cancel-in-progress: true 18 | 19 | jobs: 20 | pre-commit: 21 | permissions: 22 | contents: read 23 | runs-on: ubuntu-latest 24 | steps: 25 | - uses: actions/checkout@v4 26 | - uses: actions/setup-python@v5 27 | with: 28 | python-version: '3.x' 29 | - uses: pre-commit/action@v3.0.1 30 | -------------------------------------------------------------------------------- /.github/workflows/release-notes.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import argparse 4 | import re 5 | import pathlib 6 | import sys 7 | 8 | 9 | _STDIO = pathlib.Path("-") 10 | 11 | 12 | def main(): 13 | parser = argparse.ArgumentParser() 14 | parser.add_argument("-i", "--input", type=pathlib.Path, default="CHANGELOG.md") 15 | parser.add_argument("--tag", required=True) 16 | parser.add_argument("-o", "--output", type=pathlib.Path, required=True) 17 | args = parser.parse_args() 18 | 19 | if args.input == _STDIO: 20 | lines = sys.stdin.readlines() 21 | else: 22 | with args.input.open() as fh: 23 | lines = fh.readlines() 24 | version = args.tag.lstrip("v") 25 | 26 | note_lines = [] 27 | for line in lines: 28 | if line.startswith("## ") and version in line: 29 | note_lines.append(line) 30 | elif note_lines and line.startswith("## "): 31 | break 32 | elif note_lines: 33 | note_lines.append(line) 34 | 35 | notes = "".join(note_lines).strip() 36 | if args.output == _STDIO: 37 | print(notes) 38 | else: 39 | args.output.write_text(notes) 40 | 41 | 42 | if __name__ == "__main__": 43 | main() 44 | -------------------------------------------------------------------------------- /.github/workflows/spelling.yml: -------------------------------------------------------------------------------- 1 | name: Spelling 2 | 3 | permissions: 4 | contents: read 5 | 6 | on: [pull_request] 7 | 8 | env: 9 | RUST_BACKTRACE: 1 10 | CARGO_TERM_COLOR: always 11 | CLICOLOR: 1 12 | 13 | concurrency: 14 | group: "${{ github.workflow }}-${{ github.ref }}" 15 | cancel-in-progress: true 16 | 17 | jobs: 18 | spelling: 19 | name: Spell Check with Typos 20 | runs-on: ubuntu-latest 21 | steps: 22 | - name: Checkout Actions Repository 23 | uses: actions/checkout@v4 24 | - name: Spell Check Repo 25 | uses: crate-ci/typos@master 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | exclude: | 2 | (?x)^( 3 | tests/.*| 4 | CHANGELOG.md 5 | )$ 6 | repos: 7 | - repo: https://github.com/pre-commit/pre-commit-hooks 8 | rev: v4.5.0 9 | hooks: 10 | - id: check-yaml 11 | stages: [commit] 12 | - id: check-json 13 | stages: [commit] 14 | - id: check-toml 15 | stages: [commit] 16 | - id: check-merge-conflict 17 | stages: [commit] 18 | - id: check-case-conflict 19 | stages: [commit] 20 | - id: detect-private-key 21 | stages: [commit] 22 | - repo: https://github.com/crate-ci/typos 23 | rev: v1.16.20 24 | hooks: 25 | - id: typos 26 | stages: [commit] 27 | - repo: https://github.com/crate-ci/committed 28 | rev: v1.0.20 29 | hooks: 30 | - id: committed 31 | stages: [commit-msg] 32 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | # Parser settings. 2 | cff-version: 1.2.0 3 | message: Please cite this crate using these information. 4 | 5 | # Version information. 6 | date-released: 2025-05-27 7 | version: 4.5.39 8 | 9 | # Project information. 10 | abstract: A full featured, fast Command Line Argument Parser for Rust 11 | authors: 12 | - alias: kbknapp 13 | family-names: Knapp 14 | given-names: Kevin B. 15 | - name: The Clap Community 16 | license: 17 | - Apache-2.0 18 | - MIT 19 | repository-artifact: https://crates.io/crates/clap 20 | repository-code: https://github.com/clap-rs/clap 21 | title: clap 22 | url: https://docs.rs/clap 23 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) Individual contributors 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # CI Steps 2 | # 3 | # Considerations 4 | # - Easy to debug: show the command being run 5 | # - Leverage CI features: Only run individual steps so we can use features like reporting elapsed time per step 6 | 7 | ARGS?=--workspace 8 | TOOLCHAIN_TARGET ?= 9 | ifneq (${TOOLCHAIN_TARGET},) 10 | ARGS+=--target ${TOOLCHAIN_TARGET} 11 | endif 12 | 13 | STABLE?=1.87 14 | 15 | _FEATURES = minimal default wasm full debug release 16 | _FEATURES_minimal = --no-default-features --features "std" 17 | _FEATURES_default = 18 | _FEATURES_wasm = --no-default-features --features "std help usage error-context suggestions" --features "deprecated derive cargo env unicode string" 19 | _FEATURES_full = --features "deprecated derive cargo env unicode string wrap_help unstable-ext" 20 | _FEATURES_next = ${_FEATURES_full} --features "unstable-v5 unstable-markdown" 21 | _FEATURES_debug = ${_FEATURES_full} --features debug --features clap_complete/debug 22 | _FEATURES_release = ${_FEATURES_full} --release 23 | 24 | check-wasm: 25 | cargo check ${_FEATURES_${@:check-%=%}} ${ARGS} 26 | 27 | check-%: 28 | cargo check ${_FEATURES_${@:check-%=%}} --all-targets ${ARGS} 29 | 30 | build-%: 31 | cargo test ${_FEATURES_${@:build-%=%}} --all-targets --no-run ${ARGS} 32 | 33 | test-%: 34 | cargo test ${_FEATURES_${@:test-%=%}} ${ARGS} 35 | 36 | clippy-%: 37 | cargo clippy ${_FEATURES_${@:clippy-%=%}} ${ARGS} --all-targets -- -D warnings -A deprecated 38 | 39 | test-ui-%: 40 | cargo +${STABLE} test --test derive_ui --features derive,unstable-derive-ui-tests ${_FEATURES_${@:test-ui-%=%}} 41 | 42 | doc: 43 | cargo doc --workspace --all-features --no-deps --document-private-items 44 | -------------------------------------------------------------------------------- /assets/clap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clap-rs/clap/4099a3356c453bf412e35f218b62866c7ec9c012/assets/clap.png -------------------------------------------------------------------------------- /clap_bench/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "clap_bench" 3 | version = "0.0.0" 4 | description = "Benchmarks for clap" 5 | publish = false 6 | repository.workspace = true 7 | license.workspace = true 8 | edition.workspace = true 9 | rust-version.workspace = true 10 | include.workspace = true 11 | 12 | [package.metadata.release] 13 | release = false 14 | 15 | [dev-dependencies] 16 | clap = { path = "../", version = "4.0.0", default-features = false, features = ["std", "help"] } 17 | divan = "0.1.14" 18 | lazy_static = "1.4.0" 19 | 20 | [[bench]] 21 | harness = false 22 | name = "empty" 23 | 24 | [[bench]] 25 | harness = false 26 | name = "simple" 27 | 28 | [[bench]] 29 | harness = false 30 | name = "complex" 31 | 32 | [[bench]] 33 | harness = false 34 | name = "rustup" 35 | 36 | [[bench]] 37 | harness = false 38 | name = "ripgrep" 39 | 40 | [lints] 41 | workspace = true 42 | -------------------------------------------------------------------------------- /clap_bench/benches/empty.rs: -------------------------------------------------------------------------------- 1 | #![allow(elided_lifetimes_in_paths)] // needed for divan 2 | 3 | use clap::ArgMatches; 4 | use clap::Command; 5 | 6 | macro_rules! create_app { 7 | () => {{ 8 | Command::new("claptests") 9 | }}; 10 | } 11 | 12 | #[divan::bench] 13 | fn build() -> Command { 14 | create_app!() 15 | } 16 | 17 | #[divan::bench] 18 | fn startup() -> ArgMatches { 19 | create_app!().get_matches_from(vec![""]) 20 | } 21 | 22 | #[divan::bench] 23 | fn render_help(bencher: divan::Bencher) { 24 | let mut cmd = create_app!(); 25 | bencher.bench_local(|| build_help(&mut cmd)); 26 | } 27 | 28 | fn build_help(cmd: &mut Command) -> String { 29 | let help = cmd.render_help(); 30 | help.to_string() 31 | } 32 | 33 | fn main() { 34 | divan::main(); 35 | } 36 | -------------------------------------------------------------------------------- /clap_bench/benches/simple.rs: -------------------------------------------------------------------------------- 1 | #![allow(elided_lifetimes_in_paths)] // needed for divan 2 | 3 | use clap::{arg, ArgMatches, Command}; 4 | 5 | macro_rules! create_app { 6 | () => {{ 7 | Command::new("claptests") 8 | .version("0.1") 9 | .about("tests clap library") 10 | .author("Kevin K. ") 11 | .arg(arg!(-f --flag "tests flags")) 12 | .arg(arg!(-o --option "tests options")) 13 | .arg(arg!([positional] "tests positional")) 14 | }}; 15 | } 16 | 17 | #[divan::bench] 18 | fn build() -> Command { 19 | create_app!() 20 | } 21 | 22 | mod startup { 23 | use super::{arg, ArgMatches, Command}; 24 | 25 | #[divan::bench] 26 | fn flag() -> ArgMatches { 27 | create_app!().get_matches_from(vec!["myprog", "-f"]) 28 | } 29 | 30 | #[divan::bench] 31 | fn opt() -> ArgMatches { 32 | create_app!().get_matches_from(vec!["myprog", "-o", "option1"]) 33 | } 34 | 35 | #[divan::bench] 36 | fn pos() -> ArgMatches { 37 | create_app!().get_matches_from(vec!["myprog", "arg1"]) 38 | } 39 | } 40 | 41 | #[divan::bench] 42 | fn render_help(bencher: divan::Bencher) { 43 | let mut cmd = create_app!(); 44 | bencher.bench_local(|| build_help(&mut cmd)); 45 | } 46 | 47 | fn build_help(cmd: &mut Command) -> String { 48 | let help = cmd.render_help(); 49 | help.to_string() 50 | } 51 | 52 | fn main() { 53 | divan::main(); 54 | } 55 | -------------------------------------------------------------------------------- /clap_bench/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(docsrs, feature(doc_auto_cfg))] 2 | #![forbid(unsafe_code)] 3 | #![warn(clippy::print_stderr)] 4 | #![warn(clippy::print_stdout)] 5 | -------------------------------------------------------------------------------- /clap_builder/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | See the [clap-wide CONTRIBUTING.md](../CONTRIBUTING.md). This will contain `clap_builder` specific notes. 4 | -------------------------------------------------------------------------------- /clap_builder/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../LICENSE-APACHE -------------------------------------------------------------------------------- /clap_builder/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../LICENSE-MIT -------------------------------------------------------------------------------- /clap_builder/README.md: -------------------------------------------------------------------------------- 1 | # `clap_builder` 2 | 3 | Builder implementation for clap. 4 | 5 | [docs.rs](https://docs.rs/clap) 6 | - [Derive Tutorial](https://docs.rs/clap/latest/clap/_derive/_tutorial/index.html) 7 | - [Derive Reference](https://docs.rs/clap/latest/clap/_derive/index.html) 8 | 9 | ## License 10 | 11 | Licensed under either of 12 | 13 | - Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or ) 14 | - MIT license ([LICENSE-MIT](LICENSE-MIT) or ) 15 | 16 | at your option. 17 | 18 | ### Contribution 19 | 20 | Unless you explicitly state otherwise, any contribution intentionally submitted 21 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be 22 | dual licensed as above, without any additional terms or conditions. 23 | 24 | See [CONTRIBUTING](CONTRIBUTING.md) for more details. 25 | -------------------------------------------------------------------------------- /clap_builder/src/builder/arg_predicate.rs: -------------------------------------------------------------------------------- 1 | use crate::builder::OsStr; 2 | 3 | /// Operations to perform on argument values 4 | /// 5 | /// These do not apply to [`ValueSource::DefaultValue`][crate::parser::ValueSource::DefaultValue] 6 | #[derive(Clone, Debug, PartialEq, Eq)] 7 | #[cfg_attr(feature = "unstable-v5", non_exhaustive)] 8 | pub enum ArgPredicate { 9 | /// Is the argument present? 10 | IsPresent, 11 | /// Does the argument match the specified value? 12 | Equals(OsStr), 13 | } 14 | 15 | impl> From for ArgPredicate { 16 | fn from(other: S) -> Self { 17 | Self::Equals(other.into()) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /clap_builder/src/builder/ext.rs: -------------------------------------------------------------------------------- 1 | use crate::util::AnyValue; 2 | use crate::util::AnyValueId; 3 | use crate::util::FlatMap; 4 | 5 | #[derive(Default, Clone, Debug)] 6 | pub(crate) struct Extensions { 7 | extensions: FlatMap, 8 | } 9 | 10 | impl Extensions { 11 | #[allow(dead_code)] 12 | pub(crate) fn get(&self) -> Option<&T> { 13 | let id = AnyValueId::of::(); 14 | self.extensions.get(&id).map(|e| { 15 | e.downcast_ref::() 16 | .expect("`Extensions` tracks values by type") 17 | }) 18 | } 19 | 20 | #[allow(dead_code)] 21 | pub(crate) fn set(&mut self, tagged: T) -> bool { 22 | let value = AnyValue::new(tagged); 23 | let id = value.type_id(); 24 | self.extensions.insert(id, value).is_some() 25 | } 26 | 27 | #[allow(dead_code)] 28 | pub(crate) fn remove(&mut self) -> Option { 29 | let id = AnyValueId::of::(); 30 | self.extensions.remove(&id).map(|e| { 31 | e.downcast_into::() 32 | .expect("`Extensions` tracks values by type") 33 | }) 34 | } 35 | 36 | pub(crate) fn update(&mut self, other: &Self) { 37 | for (key, value) in other.extensions.iter() { 38 | self.extensions.insert(*key, value.clone()); 39 | } 40 | } 41 | } 42 | 43 | #[allow(unreachable_pub)] 44 | pub trait Extension: std::fmt::Debug + Clone + std::any::Any + Send + Sync + 'static {} 45 | 46 | impl Extension for T where T: std::fmt::Debug + Clone + std::any::Any + Send + Sync + 'static {} 47 | -------------------------------------------------------------------------------- /clap_builder/src/builder/tests.rs: -------------------------------------------------------------------------------- 1 | use crate::Arg; 2 | use crate::Command; 3 | 4 | #[test] 5 | fn propagate_version() { 6 | let mut cmd = Command::new("test") 7 | .propagate_version(true) 8 | .version("1.1") 9 | .subcommand(Command::new("sub1")); 10 | cmd._propagate(); 11 | assert_eq!( 12 | cmd.get_subcommands().next().unwrap().get_version(), 13 | Some("1.1") 14 | ); 15 | } 16 | 17 | #[test] 18 | fn global_setting() { 19 | let mut cmd = Command::new("test") 20 | .disable_version_flag(true) 21 | .subcommand(Command::new("subcmd")); 22 | cmd._propagate(); 23 | assert!(cmd 24 | .get_subcommands() 25 | .find(|s| s.get_name() == "subcmd") 26 | .unwrap() 27 | .is_disable_version_flag_set()); 28 | } 29 | 30 | // This test will *fail to compile* if Command is not Send + Sync 31 | #[test] 32 | fn app_send_sync() { 33 | fn foo(_: T) {} 34 | foo(Command::new("test")); 35 | } 36 | 37 | #[test] 38 | fn issue_2090() { 39 | let mut cmd = Command::new("cmd") 40 | .disable_version_flag(true) 41 | .subcommand(Command::new("sub")); 42 | cmd._build_self(false); 43 | 44 | assert!(cmd 45 | .get_subcommands() 46 | .next() 47 | .unwrap() 48 | .is_disable_version_flag_set()); 49 | } 50 | 51 | // This test will *fail to compile* if Arg is not Send + Sync 52 | #[test] 53 | fn arg_send_sync() { 54 | fn foo(_: T) {} 55 | foo(Arg::new("test")); 56 | } 57 | -------------------------------------------------------------------------------- /clap_builder/src/output/help.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(not(feature = "help"), allow(unused_variables))] 2 | 3 | // Internal 4 | use crate::builder::Command; 5 | use crate::builder::StyledStr; 6 | use crate::output::Usage; 7 | 8 | /// Writes the parser help to the wrapped stream. 9 | pub(crate) fn write_help(writer: &mut StyledStr, cmd: &Command, usage: &Usage<'_>, use_long: bool) { 10 | debug!("write_help"); 11 | 12 | if let Some(h) = cmd.get_override_help() { 13 | writer.push_styled(h); 14 | } else { 15 | #[cfg(feature = "help")] 16 | { 17 | use super::AutoHelp; 18 | use super::HelpTemplate; 19 | if let Some(tmpl) = cmd.get_help_template() { 20 | HelpTemplate::new(writer, cmd, usage, use_long) 21 | .write_templated_help(tmpl.as_styled_str()); 22 | } else { 23 | AutoHelp::new(writer, cmd, usage, use_long).write_help(); 24 | } 25 | } 26 | 27 | #[cfg(not(feature = "help"))] 28 | { 29 | debug!("write_help: no help, `Command::override_help` and `help` is missing"); 30 | } 31 | } 32 | 33 | // Remove any lines from unused sections 34 | writer.trim_start_lines(); 35 | // Remove any whitespace caused by book keeping 36 | writer.trim_end(); 37 | // Ensure there is still a trailing newline 38 | writer.push_str("\n"); 39 | } 40 | -------------------------------------------------------------------------------- /clap_builder/src/output/mod.rs: -------------------------------------------------------------------------------- 1 | mod help; 2 | #[cfg(feature = "help")] 3 | mod help_template; 4 | mod usage; 5 | 6 | pub(crate) mod fmt; 7 | #[cfg(feature = "help")] 8 | pub(crate) mod textwrap; 9 | 10 | pub(crate) use self::help::write_help; 11 | #[cfg(feature = "help")] 12 | pub(crate) use self::help_template::AutoHelp; 13 | #[cfg(feature = "help")] 14 | pub(crate) use self::help_template::HelpTemplate; 15 | #[cfg(feature = "help")] 16 | pub(crate) use self::textwrap::core::display_width; 17 | #[cfg(feature = "help")] 18 | pub(crate) use self::textwrap::wrap; 19 | pub(crate) use self::usage::Usage; 20 | 21 | pub(crate) const TAB: &str = " "; 22 | #[cfg(feature = "help")] 23 | pub(crate) const TAB_WIDTH: usize = TAB.len(); 24 | -------------------------------------------------------------------------------- /clap_builder/src/parser/features/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod suggestions; 2 | -------------------------------------------------------------------------------- /clap_builder/src/parser/matches/mod.rs: -------------------------------------------------------------------------------- 1 | mod arg_matches; 2 | mod matched_arg; 3 | mod value_source; 4 | 5 | pub use arg_matches::IdsRef; 6 | pub use arg_matches::RawValues; 7 | pub use arg_matches::Values; 8 | pub use arg_matches::ValuesRef; 9 | pub use arg_matches::{ArgMatches, Indices}; 10 | pub use value_source::ValueSource; 11 | 12 | pub(crate) use arg_matches::SubCommand; 13 | pub(crate) use matched_arg::MatchedArg; 14 | -------------------------------------------------------------------------------- /clap_builder/src/parser/matches/value_source.rs: -------------------------------------------------------------------------------- 1 | /// Origin of the argument's value 2 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] 3 | #[non_exhaustive] 4 | pub enum ValueSource { 5 | /// Value came [`Arg::default_value`][crate::Arg::default_value] 6 | DefaultValue, 7 | /// Value came [`Arg::env`][crate::Arg::env] 8 | EnvVariable, 9 | /// Value was passed in on the command-line 10 | CommandLine, 11 | } 12 | 13 | impl ValueSource { 14 | pub(crate) fn is_explicit(self) -> bool { 15 | self != Self::DefaultValue 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /clap_builder/src/parser/mod.rs: -------------------------------------------------------------------------------- 1 | //! [`Command`][crate::Command] line argument parser 2 | 3 | mod arg_matcher; 4 | mod error; 5 | mod matches; 6 | #[allow(clippy::module_inception)] 7 | mod parser; 8 | mod validator; 9 | 10 | pub(crate) mod features; 11 | 12 | pub(crate) use self::arg_matcher::ArgMatcher; 13 | pub(crate) use self::matches::{MatchedArg, SubCommand}; 14 | pub(crate) use self::parser::Identifier; 15 | pub(crate) use self::parser::Parser; 16 | pub(crate) use self::parser::PendingArg; 17 | pub(crate) use self::validator::get_possible_values_cli; 18 | pub(crate) use self::validator::Validator; 19 | 20 | pub use self::matches::IdsRef; 21 | pub use self::matches::RawValues; 22 | pub use self::matches::Values; 23 | pub use self::matches::ValuesRef; 24 | pub use self::matches::{ArgMatches, Indices, ValueSource}; 25 | pub use error::MatchesError; 26 | -------------------------------------------------------------------------------- /clap_builder/src/util/graph.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug)] 2 | struct Child { 3 | id: T, 4 | children: Vec, 5 | } 6 | 7 | impl Child { 8 | fn new(id: T) -> Self { 9 | Child { 10 | id, 11 | children: vec![], 12 | } 13 | } 14 | } 15 | 16 | #[derive(Debug)] 17 | pub(crate) struct ChildGraph(Vec>); 18 | 19 | impl ChildGraph 20 | where 21 | T: Sized + PartialEq + Clone, 22 | { 23 | pub(crate) fn with_capacity(s: usize) -> Self { 24 | ChildGraph(Vec::with_capacity(s)) 25 | } 26 | 27 | pub(crate) fn insert(&mut self, req: T) -> usize { 28 | self.0.iter().position(|e| e.id == req).unwrap_or_else(|| { 29 | let idx = self.0.len(); 30 | self.0.push(Child::new(req)); 31 | idx 32 | }) 33 | } 34 | 35 | pub(crate) fn insert_child(&mut self, parent: usize, child: T) -> usize { 36 | let c_idx = self.0.len(); 37 | self.0.push(Child::new(child)); 38 | self.0[parent].children.push(c_idx); 39 | c_idx 40 | } 41 | 42 | pub(crate) fn iter(&self) -> impl Iterator { 43 | self.0.iter().map(|r| &r.id) 44 | } 45 | 46 | pub(crate) fn contains(&self, req: &T) -> bool { 47 | self.0.iter().any(|r| r.id == *req) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /clap_builder/src/util/mod.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::single_component_path_imports)] 2 | 3 | mod any_value; 4 | pub(crate) mod flat_map; 5 | pub(crate) mod flat_set; 6 | mod graph; 7 | mod id; 8 | mod str_to_bool; 9 | 10 | pub use self::id::Id; 11 | 12 | pub(crate) use self::any_value::AnyValue; 13 | pub(crate) use self::any_value::AnyValueId; 14 | pub(crate) use self::flat_map::Entry; 15 | pub(crate) use self::flat_map::FlatMap; 16 | pub(crate) use self::flat_set::FlatSet; 17 | pub(crate) use self::graph::ChildGraph; 18 | pub(crate) use self::str_to_bool::str_to_bool; 19 | pub(crate) use self::str_to_bool::FALSE_LITERALS; 20 | pub(crate) use self::str_to_bool::TRUE_LITERALS; 21 | 22 | pub(crate) mod color; 23 | 24 | pub(crate) const SUCCESS_CODE: i32 = 0; 25 | // While sysexists.h defines EX_USAGE as 64, this doesn't seem to be used much in practice but 26 | // instead 2 seems to be frequently used. 27 | // Examples 28 | // - GNU `ls` returns 2 29 | // - Python's `argparse` returns 2 30 | pub(crate) const USAGE_CODE: i32 = 2; 31 | 32 | #[cfg(not(feature = "unicode"))] 33 | pub(crate) fn eq_ignore_case(left: &str, right: &str) -> bool { 34 | left.eq_ignore_ascii_case(right) 35 | } 36 | 37 | #[cfg(feature = "unicode")] 38 | pub(crate) use unicase::eq as eq_ignore_case; 39 | -------------------------------------------------------------------------------- /clap_builder/src/util/str_to_bool.rs: -------------------------------------------------------------------------------- 1 | /// True values are `y`, `yes`, `t`, `true`, `on`, and `1`. 2 | pub(crate) const TRUE_LITERALS: [&str; 6] = ["y", "yes", "t", "true", "on", "1"]; 3 | 4 | /// False values are `n`, `no`, `f`, `false`, `off`, and `0`. 5 | pub(crate) const FALSE_LITERALS: [&str; 6] = ["n", "no", "f", "false", "off", "0"]; 6 | 7 | /// Converts a string literal representation of truth to true or false. 8 | /// 9 | /// `false` values are `n`, `no`, `f`, `false`, `off`, and `0` (case insensitive). 10 | /// 11 | /// Any other value will be considered as `true`. 12 | pub(crate) fn str_to_bool(val: impl AsRef) -> Option { 13 | let pat: &str = &val.as_ref().to_lowercase(); 14 | if TRUE_LITERALS.contains(&pat) { 15 | Some(true) 16 | } else if FALSE_LITERALS.contains(&pat) { 17 | Some(false) 18 | } else { 19 | None 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /clap_complete/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | See the [clap-wide CONTRIBUTING.md](../CONTRIBUTING.md). This will contain `clap_complete` specific notes. 4 | 5 | ### Scope 6 | 7 | `clap_complete` contains the core completion generators, meaning ones 8 | maintained by the clap maintainers that get priority for features and fixes. 9 | Additional, including contributor-maintained generators can also be contributed 10 | to the clap repo and sit alongside `clap_complete` in a `clap_complete_` 11 | crate. 12 | -------------------------------------------------------------------------------- /clap_complete/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../LICENSE-APACHE -------------------------------------------------------------------------------- /clap_complete/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../LICENSE-MIT -------------------------------------------------------------------------------- /clap_complete/README.md: -------------------------------------------------------------------------------- 1 | 2 | # clap_complete 3 | 4 | > **Shell completion generation for `clap`** 5 | 6 | [![Crates.io](https://img.shields.io/crates/v/clap_complete?style=flat-square)](https://crates.io/crates/clap_complete) 7 | [![Crates.io](https://img.shields.io/crates/d/clap_complete?style=flat-square)](https://crates.io/crates/clap_complete) 8 | [![License](https://img.shields.io/badge/license-Apache%202.0-blue?style=flat-square)](https://github.com/clap-rs/clap/blob/clap_complete-v4.5.52/LICENSE-APACHE) 9 | [![License](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](https://github.com/clap-rs/clap/blob/clap_complete-v4.5.52/LICENSE-MIT) 10 | 11 | Dual-licensed under [Apache 2.0](LICENSE-APACHE) or [MIT](LICENSE-MIT). 12 | 13 | 1. [About](#about) 14 | 2. [API Reference](https://docs.rs/clap_complete) 15 | 3. [Questions & Discussions](https://github.com/clap-rs/clap/discussions) 16 | 4. [CONTRIBUTING](https://github.com/clap-rs/clap/blob/clap_complete-v4.5.52/clap_complete/CONTRIBUTING.md) 17 | 5. [Sponsors](https://github.com/clap-rs/clap/blob/clap_complete-v4.5.52/README.md#sponsors) 18 | 19 | ## About 20 | 21 | ### Related Projects 22 | 23 | - [clap_complete_nushell](https://crates.io/crates/clap_complete_nushell) for [nushell](https://www.nushell.sh/) shell completion support 24 | -------------------------------------------------------------------------------- /clap_complete/examples/dynamic.rs: -------------------------------------------------------------------------------- 1 | fn command() -> clap::Command { 2 | clap::Command::new("dynamic") 3 | .arg( 4 | clap::Arg::new("input") 5 | .long("input") 6 | .short('i') 7 | .value_hint(clap::ValueHint::FilePath), 8 | ) 9 | .arg( 10 | clap::Arg::new("format") 11 | .long("format") 12 | .short('F') 13 | .value_parser(["json", "yaml", "toml"]), 14 | ) 15 | .args_conflicts_with_subcommands(true) 16 | } 17 | 18 | fn main() { 19 | clap_complete::CompleteEnv::with_factory(command).complete(); 20 | 21 | let cmd = command(); 22 | let matches = cmd.get_matches(); 23 | println!("{matches:#?}"); 24 | } 25 | 26 | #[test] 27 | fn verify_cli() { 28 | command().debug_assert(); 29 | } 30 | -------------------------------------------------------------------------------- /clap_complete/src/aot/shells/mod.rs: -------------------------------------------------------------------------------- 1 | //! Shell-specific generators 2 | 3 | mod bash; 4 | mod elvish; 5 | mod fish; 6 | mod powershell; 7 | mod shell; 8 | mod zsh; 9 | 10 | pub use bash::Bash; 11 | pub use elvish::Elvish; 12 | pub use fish::Fish; 13 | pub use powershell::PowerShell; 14 | pub use shell::Shell; 15 | pub use zsh::Zsh; 16 | -------------------------------------------------------------------------------- /clap_complete/src/engine/mod.rs: -------------------------------------------------------------------------------- 1 | //! `clap`-native completion system 2 | //! 3 | //! See [`complete()`] 4 | 5 | mod candidate; 6 | mod complete; 7 | mod custom; 8 | 9 | pub use candidate::CompletionCandidate; 10 | pub use complete::complete; 11 | pub use custom::ArgValueCandidates; 12 | pub use custom::ArgValueCompleter; 13 | pub use custom::PathCompleter; 14 | pub use custom::SubcommandCandidates; 15 | pub use custom::ValueCandidates; 16 | pub use custom::ValueCompleter; 17 | -------------------------------------------------------------------------------- /clap_complete/src/macros.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "debug")] 2 | macro_rules! debug { 3 | ($($arg:tt)*) => { 4 | eprint!("[{:>w$}] \t", module_path!(), w = 28); 5 | eprintln!($($arg)*) 6 | } 7 | } 8 | 9 | #[cfg(not(feature = "debug"))] 10 | macro_rules! debug { 11 | ($($arg:tt)*) => {}; 12 | } 13 | -------------------------------------------------------------------------------- /clap_complete/tests/examples.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | fn example_tests() { 3 | let t = trycmd::TestCases::new(); 4 | let features: &[&str] = &[ 5 | #[cfg(feature = "unstable-dynamic")] 6 | "unstable-dynamic", 7 | ]; 8 | let features = features.join(" "); 9 | t.register_bins(trycmd::cargo::compile_examples(["--features", &features]).unwrap()); 10 | t.case("examples/**/*.md"); 11 | } 12 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/aliases.elvish: -------------------------------------------------------------------------------- 1 | 2 | use builtin; 3 | use str; 4 | 5 | set edit:completion:arg-completer[my-app] = {|@words| 6 | fn spaces {|n| 7 | builtin:repeat $n ' ' | str:join '' 8 | } 9 | fn cand {|text desc| 10 | edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc 11 | } 12 | var command = 'my-app' 13 | for word $words[1..-1] { 14 | if (str:has-prefix $word '-') { 15 | break 16 | } 17 | set command = $command';'$word 18 | } 19 | var completions = [ 20 | &'my-app'= { 21 | cand -o 'cmd option' 22 | cand -O 'cmd option' 23 | cand --option 'cmd option' 24 | cand --opt 'cmd option' 25 | cand -f 'cmd flag' 26 | cand -F 'cmd flag' 27 | cand --flag 'cmd flag' 28 | cand --flg 'cmd flag' 29 | cand -h 'Print help' 30 | cand --help 'Print help' 31 | cand -V 'Print version' 32 | cand --version 'Print version' 33 | } 34 | ] 35 | $completions[$command] 36 | } 37 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/aliases.fish: -------------------------------------------------------------------------------- 1 | complete -c my-app -s o -s O -l option -l opt -d 'cmd option' -r 2 | complete -c my-app -s f -s F -l flag -l flg -d 'cmd flag' 3 | complete -c my-app -s h -l help -d 'Print help' 4 | complete -c my-app -s V -l version -d 'Print version' 5 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/aliases.zsh: -------------------------------------------------------------------------------- 1 | #compdef my-app 2 | 3 | autoload -U is-at-least 4 | 5 | _my-app() { 6 | typeset -A opt_args 7 | typeset -a _arguments_options 8 | local ret=1 9 | 10 | if is-at-least 5.2; then 11 | _arguments_options=(-s -S -C) 12 | else 13 | _arguments_options=(-s -C) 14 | fi 15 | 16 | local context curcontext="$curcontext" state line 17 | _arguments "${_arguments_options[@]}" : \ 18 | '-o+[cmd option]: :_default' \ 19 | '-O+[cmd option]: :_default' \ 20 | '--option=[cmd option]: :_default' \ 21 | '--opt=[cmd option]: :_default' \ 22 | '-f[cmd flag]' \ 23 | '-F[cmd flag]' \ 24 | '--flag[cmd flag]' \ 25 | '--flg[cmd flag]' \ 26 | '-h[Print help]' \ 27 | '--help[Print help]' \ 28 | '-V[Print version]' \ 29 | '--version[Print version]' \ 30 | '::positional:_default' \ 31 | && ret=0 32 | } 33 | 34 | (( $+functions[_my-app_commands] )) || 35 | _my-app_commands() { 36 | local commands; commands=() 37 | _describe -t commands 'my-app commands' commands "$@" 38 | } 39 | 40 | if [ "$funcstack[1]" = "_my-app" ]; then 41 | _my-app "$@" 42 | else 43 | compdef _my-app my-app 44 | fi 45 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/basic.elvish: -------------------------------------------------------------------------------- 1 | 2 | use builtin; 3 | use str; 4 | 5 | set edit:completion:arg-completer[my-app] = {|@words| 6 | fn spaces {|n| 7 | builtin:repeat $n ' ' | str:join '' 8 | } 9 | fn cand {|text desc| 10 | edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc 11 | } 12 | var command = 'my-app' 13 | for word $words[1..-1] { 14 | if (str:has-prefix $word '-') { 15 | break 16 | } 17 | set command = $command';'$word 18 | } 19 | var completions = [ 20 | &'my-app'= { 21 | cand -c 'c' 22 | cand -v 'v' 23 | cand -h 'Print help' 24 | cand --help 'Print help' 25 | cand test 'Subcommand with a second line' 26 | cand help 'Print this message or the help of the given subcommand(s)' 27 | } 28 | &'my-app;test'= { 29 | cand -d 'd' 30 | cand -c 'c' 31 | cand -h 'Print help' 32 | cand --help 'Print help' 33 | } 34 | &'my-app;help'= { 35 | cand test 'Subcommand with a second line' 36 | cand help 'Print this message or the help of the given subcommand(s)' 37 | } 38 | &'my-app;help;test'= { 39 | } 40 | &'my-app;help;help'= { 41 | } 42 | ] 43 | $completions[$command] 44 | } 45 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/custom_bin_name.elvish: -------------------------------------------------------------------------------- 1 | 2 | use builtin; 3 | use str; 4 | 5 | set edit:completion:arg-completer[bin-name] = {|@words| 6 | fn spaces {|n| 7 | builtin:repeat $n ' ' | str:join '' 8 | } 9 | fn cand {|text desc| 10 | edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc 11 | } 12 | var command = 'bin-name' 13 | for word $words[1..-1] { 14 | if (str:has-prefix $word '-') { 15 | break 16 | } 17 | set command = $command';'$word 18 | } 19 | var completions = [ 20 | &'bin-name'= { 21 | cand -c 'c' 22 | cand -v 'v' 23 | cand -h 'Print help' 24 | cand --help 'Print help' 25 | cand test 'Subcommand with a second line' 26 | cand help 'Print this message or the help of the given subcommand(s)' 27 | } 28 | &'bin-name;test'= { 29 | cand -d 'd' 30 | cand -c 'c' 31 | cand -h 'Print help' 32 | cand --help 'Print help' 33 | } 34 | &'bin-name;help'= { 35 | cand test 'Subcommand with a second line' 36 | cand help 'Print this message or the help of the given subcommand(s)' 37 | } 38 | &'bin-name;help;test'= { 39 | } 40 | &'bin-name;help;help'= { 41 | } 42 | ] 43 | $completions[$command] 44 | } 45 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/home/.gitignore: -------------------------------------------------------------------------------- 1 | # Fish 2 | conf.d 3 | fish_variables 4 | functions 5 | 6 | # Zsh 7 | .zcompdump 8 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/home/dynamic-env/exhaustive/bash/.bashrc: -------------------------------------------------------------------------------- 1 | PS1='% ' 2 | . /etc/bash_completion 3 | 4 | _clap_complete_exhaustive() { 5 | local IFS=$'\013' 6 | local _CLAP_COMPLETE_INDEX=${COMP_CWORD} 7 | local _CLAP_COMPLETE_COMP_TYPE=${COMP_TYPE} 8 | if compopt +o nospace 2> /dev/null; then 9 | local _CLAP_COMPLETE_SPACE=false 10 | else 11 | local _CLAP_COMPLETE_SPACE=true 12 | fi 13 | local words=("${COMP_WORDS[@]}") 14 | if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then 15 | words[COMP_CWORD]="$2" 16 | fi 17 | COMPREPLY=( $( \ 18 | _CLAP_IFS="$IFS" \ 19 | _CLAP_COMPLETE_INDEX="$_CLAP_COMPLETE_INDEX" \ 20 | _CLAP_COMPLETE_COMP_TYPE="$_CLAP_COMPLETE_COMP_TYPE" \ 21 | _CLAP_COMPLETE_SPACE="$_CLAP_COMPLETE_SPACE" \ 22 | COMPLETE="bash" \ 23 | "exhaustive" -- "${words[@]}" \ 24 | ) ) 25 | if [[ $? != 0 ]]; then 26 | unset COMPREPLY 27 | elif [[ $_CLAP_COMPLETE_SPACE == false ]] && [[ "${COMPREPLY-}" =~ [=/:]$ ]]; then 28 | compopt -o nospace 29 | fi 30 | } 31 | if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERSINFO[0]}" -gt 4 ]]; then 32 | complete -o nospace -o bashdefault -o nosort -F _clap_complete_exhaustive exhaustive 33 | else 34 | complete -o nospace -o bashdefault -F _clap_complete_exhaustive exhaustive 35 | fi 36 | 37 | 38 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/home/dynamic-env/exhaustive/elvish/elvish/rc.elv: -------------------------------------------------------------------------------- 1 | set edit:rprompt = (constantly "") 2 | set edit:prompt = (constantly "% ") 3 | 4 | set edit:completion:arg-completer[exhaustive] = { |@words| 5 | var index = (count $words) 6 | set index = (- $index 1) 7 | 8 | put (env _CLAP_IFS="\n" _CLAP_COMPLETE_INDEX=(to-string $index) COMPLETE="elvish" exhaustive -- $@words) | to-lines 9 | } 10 | 11 | 12 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/home/dynamic-env/exhaustive/fish/fish/completions/exhaustive.fish: -------------------------------------------------------------------------------- 1 | complete --keep-order --exclusive --command exhaustive --arguments "(COMPLETE=fish "'exhaustive'" -- (commandline --current-process --tokenize --cut-at-cursor) (commandline --current-token))" 2 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/home/dynamic-env/exhaustive/fish/fish/config.fish: -------------------------------------------------------------------------------- 1 | set -U fish_greeting "" 2 | set -U fish_autosuggestion_enabled 0 3 | function fish_title 4 | end 5 | function fish_prompt 6 | printf '%% ' 7 | end; 8 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/home/dynamic-env/exhaustive/zsh/.zshenv: -------------------------------------------------------------------------------- 1 | fpath=($fpath $ZDOTDIR/zsh) 2 | autoload -U +X compinit && compinit -u # bypass compaudit security checking 3 | precmd_functions="" # avoid the prompt being overwritten 4 | PS1='%% ' 5 | PROMPT='%% ' 6 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/home/dynamic-env/exhaustive/zsh/zsh/_exhaustive: -------------------------------------------------------------------------------- 1 | #compdef exhaustive 2 | function _clap_dynamic_completer_exhaustive() { 3 | local _CLAP_COMPLETE_INDEX=$(expr $CURRENT - 1) 4 | local _CLAP_IFS=$'\n' 5 | 6 | local completions=("${(@f)$( \ 7 | _CLAP_IFS="$_CLAP_IFS" \ 8 | _CLAP_COMPLETE_INDEX="$_CLAP_COMPLETE_INDEX" \ 9 | COMPLETE="zsh" \ 10 | exhaustive -- "${words[@]}" 2>/dev/null \ 11 | )}") 12 | 13 | if [[ -n $completions ]]; then 14 | _describe 'values' completions 15 | fi 16 | } 17 | 18 | compdef _clap_dynamic_completer_exhaustive exhaustive 19 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/home/static/exhaustive/bash/.inputrc: -------------------------------------------------------------------------------- 1 | # expected empty file to disable loading ~/.inputrc 2 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/home/static/exhaustive/fish/fish/config.fish: -------------------------------------------------------------------------------- 1 | set -U fish_greeting "" 2 | set -U fish_autosuggestion_enabled 0 3 | function fish_title 4 | end 5 | function fish_prompt 6 | printf '%% ' 7 | end; 8 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/home/static/exhaustive/zsh/.zshenv: -------------------------------------------------------------------------------- 1 | fpath=($fpath $ZDOTDIR/zsh) 2 | autoload -U +X compinit && compinit -u # bypass compaudit security checking 3 | precmd_functions="" # avoid the prompt being overwritten 4 | PS1='%% ' 5 | PROMPT='%% ' 6 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/register_dynamic.fish: -------------------------------------------------------------------------------- 1 | complete -x -c my-app -a 'my-app'" complete --shell fish -- (commandline --current-process --tokenize --cut-at-cursor) (commandline --current-token)" 2 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/register_minimal.bash: -------------------------------------------------------------------------------- 1 | 2 | _clap_complete_my_app() { 3 | local IFS=$'/013' 4 | local _CLAP_COMPLETE_INDEX=${COMP_CWORD} 5 | local _CLAP_COMPLETE_COMP_TYPE=${COMP_TYPE} 6 | if compopt +o nospace 2> /dev/null; then 7 | local _CLAP_COMPLETE_SPACE=false 8 | else 9 | local _CLAP_COMPLETE_SPACE=true 10 | fi 11 | COMPREPLY=( $( / 12 | IFS="$IFS" / 13 | _CLAP_COMPLETE_INDEX="$_CLAP_COMPLETE_INDEX" / 14 | _CLAP_COMPLETE_COMP_TYPE="$_CLAP_COMPLETE_COMP_TYPE" / 15 | _CLAP_COMPLETE_SPACE="$_CLAP_COMPLETE_SPACE" / 16 | "my-app" complete bash -- "${COMP_WORDS[@]}" / 17 | ) ) 18 | if [[ $? != 0 ]]; then 19 | unset COMPREPLY 20 | elif [[ $_CLAP_COMPLETE_SPACE == false ]] && [[ "${COMPREPLY-}" =~ [=/:]$ ]]; then 21 | compopt -o nospace 22 | fi 23 | } 24 | if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERSINFO[0]}" -gt 4 ]]; then 25 | complete -o nospace -o bashdefault -o nosort -F _clap_complete_my_app my-app 26 | else 27 | complete -o nospace -o bashdefault -F _clap_complete_my_app my-app 28 | fi 29 | 30 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/subcommand_last.elvish: -------------------------------------------------------------------------------- 1 | 2 | use builtin; 3 | use str; 4 | 5 | set edit:completion:arg-completer[my-app] = {|@words| 6 | fn spaces {|n| 7 | builtin:repeat $n ' ' | str:join '' 8 | } 9 | fn cand {|text desc| 10 | edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc 11 | } 12 | var command = 'my-app' 13 | for word $words[1..-1] { 14 | if (str:has-prefix $word '-') { 15 | break 16 | } 17 | set command = $command';'$word 18 | } 19 | var completions = [ 20 | &'my-app'= { 21 | cand -h 'Print help' 22 | cand --help 'Print help' 23 | cand foo 'foo' 24 | cand bar 'bar' 25 | cand help 'Print this message or the help of the given subcommand(s)' 26 | } 27 | &'my-app;foo'= { 28 | cand -h 'Print help' 29 | cand --help 'Print help' 30 | } 31 | &'my-app;bar'= { 32 | cand -h 'Print help' 33 | cand --help 'Print help' 34 | } 35 | &'my-app;help'= { 36 | cand foo 'foo' 37 | cand bar 'bar' 38 | cand help 'Print this message or the help of the given subcommand(s)' 39 | } 40 | &'my-app;help;foo'= { 41 | } 42 | &'my-app;help;bar'= { 43 | } 44 | &'my-app;help;help'= { 45 | } 46 | ] 47 | $completions[$command] 48 | } 49 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/two_multi_valued_arguments.bash: -------------------------------------------------------------------------------- 1 | _my-app() { 2 | local i cur prev opts cmd 3 | COMPREPLY=() 4 | if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then 5 | cur="$2" 6 | else 7 | cur="${COMP_WORDS[COMP_CWORD]}" 8 | fi 9 | prev="$3" 10 | cmd="" 11 | opts="" 12 | 13 | for i in "${COMP_WORDS[@]:0:COMP_CWORD}" 14 | do 15 | case "${cmd},${i}" in 16 | ",$1") 17 | cmd="my__app" 18 | ;; 19 | *) 20 | ;; 21 | esac 22 | done 23 | 24 | case "${cmd}" in 25 | my__app) 26 | opts="-h --help [first]... [second]..." 27 | if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then 28 | COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) 29 | return 0 30 | fi 31 | case "${prev}" in 32 | *) 33 | COMPREPLY=() 34 | ;; 35 | esac 36 | COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) 37 | return 0 38 | ;; 39 | esac 40 | } 41 | 42 | if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERSINFO[0]}" -gt 4 ]]; then 43 | complete -F _my-app -o nosort -o bashdefault -o default my-app 44 | else 45 | complete -F _my-app -o bashdefault -o default my-app 46 | fi 47 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/two_multi_valued_arguments.elvish: -------------------------------------------------------------------------------- 1 | 2 | use builtin; 3 | use str; 4 | 5 | set edit:completion:arg-completer[my-app] = {|@words| 6 | fn spaces {|n| 7 | builtin:repeat $n ' ' | str:join '' 8 | } 9 | fn cand {|text desc| 10 | edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc 11 | } 12 | var command = 'my-app' 13 | for word $words[1..-1] { 14 | if (str:has-prefix $word '-') { 15 | break 16 | } 17 | set command = $command';'$word 18 | } 19 | var completions = [ 20 | &'my-app'= { 21 | cand -h 'Print help' 22 | cand --help 'Print help' 23 | } 24 | ] 25 | $completions[$command] 26 | } 27 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/two_multi_valued_arguments.fish: -------------------------------------------------------------------------------- 1 | complete -c my-app -s h -l help -d 'Print help' 2 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/two_multi_valued_arguments.ps1: -------------------------------------------------------------------------------- 1 | 2 | using namespace System.Management.Automation 3 | using namespace System.Management.Automation.Language 4 | 5 | Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock { 6 | param($wordToComplete, $commandAst, $cursorPosition) 7 | 8 | $commandElements = $commandAst.CommandElements 9 | $command = @( 10 | 'my-app' 11 | for ($i = 1; $i -lt $commandElements.Count; $i++) { 12 | $element = $commandElements[$i] 13 | if ($element -isnot [StringConstantExpressionAst] -or 14 | $element.StringConstantType -ne [StringConstantType]::BareWord -or 15 | $element.Value.StartsWith('-') -or 16 | $element.Value -eq $wordToComplete) { 17 | break 18 | } 19 | $element.Value 20 | }) -join ';' 21 | 22 | $completions = @(switch ($command) { 23 | 'my-app' { 24 | [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help') 25 | [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help') 26 | break 27 | } 28 | }) 29 | 30 | $completions.Where{ $_.CompletionText -like "$wordToComplete*" } | 31 | Sort-Object -Property ListItemText 32 | } 33 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/two_multi_valued_arguments.zsh: -------------------------------------------------------------------------------- 1 | #compdef my-app 2 | 3 | autoload -U is-at-least 4 | 5 | _my-app() { 6 | typeset -A opt_args 7 | typeset -a _arguments_options 8 | local ret=1 9 | 10 | if is-at-least 5.2; then 11 | _arguments_options=(-s -S -C) 12 | else 13 | _arguments_options=(-s -C) 14 | fi 15 | 16 | local context curcontext="$curcontext" state line 17 | _arguments "${_arguments_options[@]}" : \ 18 | '-h[Print help]' \ 19 | '--help[Print help]' \ 20 | '*::first -- first multi-valued argument:_default' \ 21 | && ret=0 22 | } 23 | 24 | (( $+functions[_my-app_commands] )) || 25 | _my-app_commands() { 26 | local commands; commands=() 27 | _describe -t commands 'my-app commands' commands "$@" 28 | } 29 | 30 | if [ "$funcstack[1]" = "_my-app" ]; then 31 | _my-app "$@" 32 | else 33 | compdef _my-app my-app 34 | fi 35 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/value_hint.elvish: -------------------------------------------------------------------------------- 1 | 2 | use builtin; 3 | use str; 4 | 5 | set edit:completion:arg-completer[my-app] = {|@words| 6 | fn spaces {|n| 7 | builtin:repeat $n ' ' | str:join '' 8 | } 9 | fn cand {|text desc| 10 | edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc 11 | } 12 | var command = 'my-app' 13 | for word $words[1..-1] { 14 | if (str:has-prefix $word '-') { 15 | break 16 | } 17 | set command = $command';'$word 18 | } 19 | var completions = [ 20 | &'my-app'= { 21 | cand --choice 'choice' 22 | cand --unknown 'unknown' 23 | cand --other 'other' 24 | cand -p 'p' 25 | cand --path 'path' 26 | cand -f 'f' 27 | cand --file 'file' 28 | cand -d 'd' 29 | cand --dir 'dir' 30 | cand -e 'e' 31 | cand --exe 'exe' 32 | cand --cmd-name 'cmd-name' 33 | cand -c 'c' 34 | cand --cmd 'cmd' 35 | cand -u 'u' 36 | cand --user 'user' 37 | cand -H 'H' 38 | cand --host 'host' 39 | cand --url 'url' 40 | cand --email 'email' 41 | cand -h 'Print help' 42 | cand --help 'Print help' 43 | } 44 | ] 45 | $completions[$command] 46 | } 47 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/value_hint.fish: -------------------------------------------------------------------------------- 1 | complete -c my-app -l choice -r -f -a "bash\t'' 2 | fish\t'' 3 | zsh\t''" 4 | complete -c my-app -l unknown -r 5 | complete -c my-app -l other -r -f 6 | complete -c my-app -s p -l path -r -F 7 | complete -c my-app -s f -l file -r -F 8 | complete -c my-app -s d -l dir -r -f -a "(__fish_complete_directories)" 9 | complete -c my-app -s e -l exe -r -F 10 | complete -c my-app -l cmd-name -r -f -a "(__fish_complete_command)" 11 | complete -c my-app -s c -l cmd -r -f -a "(__fish_complete_command)" 12 | complete -c my-app -s u -l user -r -f -a "(__fish_complete_users)" 13 | complete -c my-app -s H -l host -r -f -a "(__fish_print_hostnames)" 14 | complete -c my-app -l url -r -f 15 | complete -c my-app -l email -r -f 16 | complete -c my-app -s h -l help -d 'Print help' 17 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/value_hint.zsh: -------------------------------------------------------------------------------- 1 | #compdef my-app 2 | 3 | autoload -U is-at-least 4 | 5 | _my-app() { 6 | typeset -A opt_args 7 | typeset -a _arguments_options 8 | local ret=1 9 | 10 | if is-at-least 5.2; then 11 | _arguments_options=(-s -S -C) 12 | else 13 | _arguments_options=(-s -C) 14 | fi 15 | 16 | local context curcontext="$curcontext" state line 17 | _arguments "${_arguments_options[@]}" : \ 18 | '--choice=[]: :(bash fish zsh)' \ 19 | '--unknown=[]: :_default' \ 20 | '--other=[]: :' \ 21 | '-p+[]: :_files' \ 22 | '--path=[]: :_files' \ 23 | '-f+[]: :_files' \ 24 | '--file=[]: :_files' \ 25 | '-d+[]: :_files -/' \ 26 | '--dir=[]: :_files -/' \ 27 | '-e+[]: :_absolute_command_paths' \ 28 | '--exe=[]: :_absolute_command_paths' \ 29 | '--cmd-name=[]: :_command_names -e' \ 30 | '-c+[]: :_cmdstring' \ 31 | '--cmd=[]: :_cmdstring' \ 32 | '-u+[]: :_users' \ 33 | '--user=[]: :_users' \ 34 | '-H+[]: :_hosts' \ 35 | '--host=[]: :_hosts' \ 36 | '--url=[]: :_urls' \ 37 | '--email=[]: :_email_addresses' \ 38 | '-h[Print help]' \ 39 | '--help[Print help]' \ 40 | '*::command_with_args:_cmdambivalent' \ 41 | && ret=0 42 | } 43 | 44 | (( $+functions[_my-app_commands] )) || 45 | _my-app_commands() { 46 | local commands; commands=() 47 | _describe -t commands 'my-app commands' commands "$@" 48 | } 49 | 50 | if [ "$funcstack[1]" = "_my-app" ]; then 51 | _my-app "$@" 52 | else 53 | compdef _my-app my-app 54 | fi 55 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/value_terminator.bash: -------------------------------------------------------------------------------- 1 | _my-app() { 2 | local i cur prev opts cmd 3 | COMPREPLY=() 4 | if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then 5 | cur="$2" 6 | else 7 | cur="${COMP_WORDS[COMP_CWORD]}" 8 | fi 9 | prev="$3" 10 | cmd="" 11 | opts="" 12 | 13 | for i in "${COMP_WORDS[@]:0:COMP_CWORD}" 14 | do 15 | case "${cmd},${i}" in 16 | ",$1") 17 | cmd="my__app" 18 | ;; 19 | *) 20 | ;; 21 | esac 22 | done 23 | 24 | case "${cmd}" in 25 | my__app) 26 | opts="-h --help [arguments]..." 27 | if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then 28 | COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) 29 | return 0 30 | fi 31 | case "${prev}" in 32 | *) 33 | COMPREPLY=() 34 | ;; 35 | esac 36 | COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) 37 | return 0 38 | ;; 39 | esac 40 | } 41 | 42 | if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERSINFO[0]}" -gt 4 ]]; then 43 | complete -F _my-app -o nosort -o bashdefault -o default my-app 44 | else 45 | complete -F _my-app -o bashdefault -o default my-app 46 | fi 47 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/value_terminator.elvish: -------------------------------------------------------------------------------- 1 | 2 | use builtin; 3 | use str; 4 | 5 | set edit:completion:arg-completer[my-app] = {|@words| 6 | fn spaces {|n| 7 | builtin:repeat $n ' ' | str:join '' 8 | } 9 | fn cand {|text desc| 10 | edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc 11 | } 12 | var command = 'my-app' 13 | for word $words[1..-1] { 14 | if (str:has-prefix $word '-') { 15 | break 16 | } 17 | set command = $command';'$word 18 | } 19 | var completions = [ 20 | &'my-app'= { 21 | cand -h 'Print help' 22 | cand --help 'Print help' 23 | } 24 | ] 25 | $completions[$command] 26 | } 27 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/value_terminator.fish: -------------------------------------------------------------------------------- 1 | complete -c my-app -s h -l help -d 'Print help' 2 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/value_terminator.ps1: -------------------------------------------------------------------------------- 1 | 2 | using namespace System.Management.Automation 3 | using namespace System.Management.Automation.Language 4 | 5 | Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock { 6 | param($wordToComplete, $commandAst, $cursorPosition) 7 | 8 | $commandElements = $commandAst.CommandElements 9 | $command = @( 10 | 'my-app' 11 | for ($i = 1; $i -lt $commandElements.Count; $i++) { 12 | $element = $commandElements[$i] 13 | if ($element -isnot [StringConstantExpressionAst] -or 14 | $element.StringConstantType -ne [StringConstantType]::BareWord -or 15 | $element.Value.StartsWith('-') -or 16 | $element.Value -eq $wordToComplete) { 17 | break 18 | } 19 | $element.Value 20 | }) -join ';' 21 | 22 | $completions = @(switch ($command) { 23 | 'my-app' { 24 | [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help') 25 | [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help') 26 | break 27 | } 28 | }) 29 | 30 | $completions.Where{ $_.CompletionText -like "$wordToComplete*" } | 31 | Sort-Object -Property ListItemText 32 | } 33 | -------------------------------------------------------------------------------- /clap_complete/tests/snapshots/value_terminator.zsh: -------------------------------------------------------------------------------- 1 | #compdef my-app 2 | 3 | autoload -U is-at-least 4 | 5 | _my-app() { 6 | typeset -A opt_args 7 | typeset -a _arguments_options 8 | local ret=1 9 | 10 | if is-at-least 5.2; then 11 | _arguments_options=(-s -S -C) 12 | else 13 | _arguments_options=(-s -C) 14 | fi 15 | 16 | local context curcontext="$curcontext" state line 17 | _arguments "${_arguments_options[@]}" : \ 18 | '-h[Print help]' \ 19 | '--help[Print help]' \ 20 | '*;::arguments -- multi-valued argument with a value terminator:_default' \ 21 | && ret=0 22 | } 23 | 24 | (( $+functions[_my-app_commands] )) || 25 | _my-app_commands() { 26 | local commands; commands=() 27 | _describe -t commands 'my-app commands' commands "$@" 28 | } 29 | 30 | if [ "$funcstack[1]" = "_my-app" ]; then 31 | _my-app "$@" 32 | else 33 | compdef _my-app my-app 34 | fi 35 | -------------------------------------------------------------------------------- /clap_complete/tests/testsuite/general.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | fn infer_value_hint_for_path_buf() { 3 | let mut cmd = clap::Command::new("completer") 4 | .arg(clap::Arg::new("input").value_parser(clap::value_parser!(std::path::PathBuf))); 5 | cmd.build(); 6 | let input = cmd 7 | .get_arguments() 8 | .find(|arg| arg.get_id() == "input") 9 | .unwrap(); 10 | assert_eq!(input.get_value_hint(), clap::builder::ValueHint::AnyPath); 11 | } 12 | -------------------------------------------------------------------------------- /clap_complete/tests/testsuite/main.rs: -------------------------------------------------------------------------------- 1 | automod::dir!("tests/testsuite"); 2 | -------------------------------------------------------------------------------- /clap_complete_nushell/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../LICENSE-APACHE -------------------------------------------------------------------------------- /clap_complete_nushell/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../LICENSE-MIT -------------------------------------------------------------------------------- /clap_complete_nushell/examples/nushell_completion.rs: -------------------------------------------------------------------------------- 1 | use clap::Command; 2 | use clap_complete::generate; 3 | use clap_complete_nushell::Nushell; 4 | use std::io; 5 | 6 | fn main() { 7 | let mut cmd = Command::new("myapp") 8 | .subcommand(Command::new("test").subcommand(Command::new("config"))) 9 | .subcommand(Command::new("hello")); 10 | 11 | generate(Nushell, &mut cmd, "myapp", &mut io::stdout()); 12 | } 13 | -------------------------------------------------------------------------------- /clap_complete_nushell/tests/snapshots/aliases.nu: -------------------------------------------------------------------------------- 1 | module completions { 2 | 3 | # testing nushell completions 4 | export extern my-app [ 5 | --flag(-f) # cmd flag 6 | --flg # cmd flag 7 | -F # cmd flag 8 | --option(-o): string # cmd option 9 | --opt: string # cmd option 10 | -O: string # cmd option 11 | positional?: string 12 | --help(-h) # Print help 13 | --version(-V) # Print version 14 | ] 15 | 16 | } 17 | 18 | export use completions * 19 | -------------------------------------------------------------------------------- /clap_complete_nushell/tests/snapshots/basic.nu: -------------------------------------------------------------------------------- 1 | module completions { 2 | 3 | export extern my-app [ 4 | -c 5 | -v 6 | --help(-h) # Print help 7 | ] 8 | 9 | # Subcommand with a second line 10 | export extern "my-app test" [ 11 | -d 12 | -c 13 | --help(-h) # Print help 14 | ] 15 | 16 | # Print this message or the help of the given subcommand(s) 17 | export extern "my-app help" [ 18 | ] 19 | 20 | # Subcommand with a second line 21 | export extern "my-app help test" [ 22 | ] 23 | 24 | # Print this message or the help of the given subcommand(s) 25 | export extern "my-app help help" [ 26 | ] 27 | 28 | } 29 | 30 | export use completions * 31 | -------------------------------------------------------------------------------- /clap_complete_nushell/tests/snapshots/feature_sample.nu: -------------------------------------------------------------------------------- 1 | module completions { 2 | 3 | def "nu-complete my-app choice" [] { 4 | [ "first" "second" ] 5 | } 6 | 7 | # Tests completions 8 | export extern my-app [ 9 | file?: path # some input file 10 | --config(-c) # some config file with another line 11 | --conf # some config file with another line 12 | -C # some config file with another line 13 | choice?: string@"nu-complete my-app choice" 14 | --help(-h) # Print help 15 | --version(-V) # Print version 16 | ] 17 | 18 | # tests things 19 | export extern "my-app test" [ 20 | --case: string # the case to test 21 | --help(-h) # Print help 22 | --version(-V) # Print version 23 | ] 24 | 25 | # Print this message or the help of the given subcommand(s) 26 | export extern "my-app help" [ 27 | ] 28 | 29 | # tests things 30 | export extern "my-app help test" [ 31 | ] 32 | 33 | # Print this message or the help of the given subcommand(s) 34 | export extern "my-app help help" [ 35 | ] 36 | 37 | } 38 | 39 | export use completions * 40 | -------------------------------------------------------------------------------- /clap_complete_nushell/tests/snapshots/home/static/test/nu/.config/nushell/config.nu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clap-rs/clap/4099a3356c453bf412e35f218b62866c7ec9c012/clap_complete_nushell/tests/snapshots/home/static/test/nu/.config/nushell/config.nu -------------------------------------------------------------------------------- /clap_complete_nushell/tests/snapshots/value_hint.nu: -------------------------------------------------------------------------------- 1 | module completions { 2 | 3 | def "nu-complete my-app choice" [] { 4 | [ "bash" "fish" "zsh" ] 5 | } 6 | 7 | export extern my-app [ 8 | --choice: string@"nu-complete my-app choice" 9 | --unknown: string 10 | --other: string 11 | --path(-p): path 12 | --file(-f): path 13 | --dir(-d): path 14 | --exe(-e): path 15 | --cmd-name: string 16 | --cmd(-c): string 17 | command_with_args?: string 18 | --user(-u): string 19 | --host(-H): string 20 | --url: string 21 | --email: string 22 | --help(-h) # Print help 23 | ] 24 | 25 | } 26 | 27 | export use completions * 28 | -------------------------------------------------------------------------------- /clap_derive/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | See the [clap-wide CONTRIBUTING.md](../CONTRIBUTING.md). This will contain `clap_derive` specific notes. 4 | 5 | ## Derive Gotchas 6 | 7 | - Always prefix generated variables with `__clap_` to minimize clashes with the user's variables, see [#2934](https://github.com/clap-rs/clap/issues/2934). 8 | - Prefer the path `clap` over `::clap` to allow users to re-export clap, see [#2258](https://github.com/clap-rs/clap/pull/2258). 9 | - Prefer substituting variable names to avoid problems with `macro_rules`, see [#2823](https://github.com/clap-rs/clap/pull/2823). 10 | - Prefer `::std::result::Result` and `::std::option::Option`, see [#3092](https://github.com/clap-rs/clap/pull/3092). 11 | - Put whitespace between `#quoted #variables`. 12 | - New "magic" attributes must be documented in the [derive reference](../src/_derive.rs) 13 | - If there is no related builder method, a `#![doc(alias = "")]` should also be added, see [#4984](https://github.com/clap-rs/clap/pull/4984) 14 | -------------------------------------------------------------------------------- /clap_derive/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "clap_derive" 3 | version = "4.5.32" 4 | description = "Parse command line argument by defining a struct, derive crate." 5 | categories = ["command-line-interface", "development-tools::procedural-macro-helpers"] 6 | keywords = [ 7 | "clap", 8 | "cli", 9 | "parse", 10 | "derive", 11 | "proc_macro" 12 | ] 13 | repository.workspace = true 14 | license.workspace = true 15 | edition.workspace = true 16 | rust-version.workspace = true 17 | include.workspace = true 18 | 19 | [package.metadata.docs.rs] 20 | targets = ["x86_64-unknown-linux-gnu"] 21 | 22 | [package.metadata.release] 23 | shared-version = true 24 | dependent-version = "upgrade" 25 | tag-name = "v{{version}}" 26 | 27 | [lib] 28 | proc-macro = true 29 | bench = false 30 | 31 | [dependencies] 32 | syn = { version = "2.0.8", features = ["full"] } 33 | quote = "1.0.9" 34 | proc-macro2 = "1.0.69" 35 | heck = "0.5.0" 36 | pulldown-cmark = { version = "0.13.0", default-features = false, optional = true} 37 | anstyle = {version ="1.0.10", optional = true} 38 | 39 | [features] 40 | default = [] 41 | debug = [] 42 | unstable-v5 = ["deprecated"] 43 | deprecated = [] 44 | raw-deprecated = ["deprecated"] 45 | unstable-markdown = ["dep:pulldown-cmark", "dep:anstyle"] 46 | 47 | [lints] 48 | workspace = true 49 | -------------------------------------------------------------------------------- /clap_derive/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../LICENSE-APACHE -------------------------------------------------------------------------------- /clap_derive/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../LICENSE-MIT -------------------------------------------------------------------------------- /clap_derive/README.md: -------------------------------------------------------------------------------- 1 | # `clap_derive` 2 | 3 | Macro implementation for clap's derives. 4 | 5 | [docs.rs](https://docs.rs/clap) 6 | - [Derive Tutorial](https://docs.rs/clap/latest/clap/_derive/_tutorial/index.html) 7 | - [Derive Reference](https://docs.rs/clap/latest/clap/_derive/index.html) 8 | 9 | ## License 10 | 11 | Licensed under either of 12 | 13 | - Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or ) 14 | - MIT license ([LICENSE-MIT](LICENSE-MIT) or ) 15 | 16 | at your option. 17 | 18 | ### Contribution 19 | 20 | Unless you explicitly state otherwise, any contribution intentionally submitted 21 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be 22 | dual licensed as above, without any additional terms or conditions. 23 | 24 | See [CONTRIBUTING](CONTRIBUTING.md) for more details. 25 | -------------------------------------------------------------------------------- /clap_derive/src/derives/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Guillaume Pinot (@TeXitoi) , 2 | // Kevin Knapp (@kbknapp) , and 3 | // Ana Hobden (@hoverbear) 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | // 11 | // This work was derived from Structopt (https://github.com/TeXitoi/structopt) 12 | // commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the 13 | // MIT/Apache 2.0 license. 14 | mod args; 15 | mod into_app; 16 | mod parser; 17 | mod subcommand; 18 | mod value_enum; 19 | 20 | pub(crate) use self::parser::derive_parser; 21 | pub(crate) use args::derive_args; 22 | pub(crate) use subcommand::derive_subcommand; 23 | pub(crate) use value_enum::derive_value_enum; 24 | -------------------------------------------------------------------------------- /clap_derive/src/macros.rs: -------------------------------------------------------------------------------- 1 | macro_rules! format_err { 2 | ($obj:expr, $($format:tt)+) => {{ 3 | #[allow(unused_imports)] 4 | use $crate::utils::error::*; 5 | let msg = format!($($format)+); 6 | $obj.EXPECTED_Span_OR_ToTokens(msg) 7 | }}; 8 | } 9 | 10 | macro_rules! abort { 11 | ($obj:expr, $($format:tt)+) => {{ 12 | return Err(format_err!($obj, $($format)+)); 13 | }}; 14 | } 15 | 16 | macro_rules! abort_call_site { 17 | ($($format:tt)+) => {{ 18 | let span = proc_macro2::Span::call_site(); 19 | abort!(span, $($format)+) 20 | }}; 21 | } 22 | -------------------------------------------------------------------------------- /clap_derive/src/utils/error.rs: -------------------------------------------------------------------------------- 1 | pub(crate) trait SpanError { 2 | #[allow(non_snake_case)] 3 | fn EXPECTED_Span_OR_ToTokens(&self, msg: D) -> syn::Error; 4 | } 5 | 6 | pub(crate) trait ToTokensError { 7 | #[allow(non_snake_case)] 8 | fn EXPECTED_Span_OR_ToTokens(&self, msg: D) -> syn::Error; 9 | } 10 | 11 | impl ToTokensError for T { 12 | fn EXPECTED_Span_OR_ToTokens(&self, msg: D) -> syn::Error { 13 | // Curb monomorphization from generating too many identical `new_spanned`. 14 | syn::Error::new_spanned(self.to_token_stream(), msg) 15 | } 16 | } 17 | 18 | impl SpanError for proc_macro2::Span { 19 | fn EXPECTED_Span_OR_ToTokens(&self, msg: D) -> syn::Error { 20 | syn::Error::new(*self, msg) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /clap_derive/src/utils/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod error; 2 | 3 | mod doc_comments; 4 | mod spanned; 5 | mod ty; 6 | 7 | pub(crate) use doc_comments::extract_doc_comment; 8 | pub(crate) use doc_comments::format_doc_comment; 9 | 10 | pub(crate) use self::{ 11 | spanned::Sp, 12 | ty::{inner_type, is_simple_ty, sub_type, subty_if_name, Ty}, 13 | }; 14 | -------------------------------------------------------------------------------- /clap_lex/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | See the [clap-wide CONTRIBUTING.md](../CONTRIBUTING.md). This will contain `clap_lex` specific notes. 4 | -------------------------------------------------------------------------------- /clap_lex/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "clap_lex" 3 | version = "0.7.4" 4 | description = "Minimal, flexible command line parser" 5 | categories = ["command-line-interface"] 6 | keywords = [ 7 | "argument", 8 | "cli", 9 | "arg", 10 | "parser", 11 | "parse" 12 | ] 13 | repository.workspace = true 14 | license.workspace = true 15 | edition.workspace = true 16 | rust-version.workspace = true 17 | include.workspace = true 18 | 19 | [package.metadata.release] 20 | pre-release-replacements = [ 21 | {file="CHANGELOG.md", search="Unreleased", replace="{{version}}", min=1}, 22 | {file="CHANGELOG.md", search="\\.\\.\\.HEAD", replace="...{{tag_name}}", exactly=1}, 23 | {file="CHANGELOG.md", search="ReleaseDate", replace="{{date}}", min=1}, 24 | {file="CHANGELOG.md", search="", replace="\n## [Unreleased] - ReleaseDate\n", exactly=1}, 25 | {file="CHANGELOG.md", search="", replace="\n[Unreleased]: https://github.com/clap-rs/clap/compare/{{tag_name}}...HEAD", exactly=1}, 26 | {file="README.md", search="github.com/clap-rs/clap/blob/[^/]+/", replace="github.com/clap-rs/clap/blob/{{tag_name}}/", exactly=4, prerelease = true}, 27 | ] 28 | 29 | [dev-dependencies] 30 | automod = "1.0.14" 31 | 32 | [lib] 33 | bench = false 34 | 35 | [lints] 36 | workspace = true 37 | -------------------------------------------------------------------------------- /clap_lex/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../LICENSE-APACHE -------------------------------------------------------------------------------- /clap_lex/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../LICENSE-MIT -------------------------------------------------------------------------------- /clap_lex/README.md: -------------------------------------------------------------------------------- 1 | 2 | # clap_lex 3 | 4 | > **Minimal, flexible command line parser** 5 | 6 | [![Crates.io](https://img.shields.io/crates/v/clap_lex?style=flat-square)](https://crates.io/crates/clap_lex) 7 | [![Crates.io](https://img.shields.io/crates/d/clap_lex?style=flat-square)](https://crates.io/crates/clap_lex) 8 | [![License](https://img.shields.io/badge/license-Apache%202.0-blue?style=flat-square)](https://github.com/clap-rs/clap/blob/clap_lex-v0.7.4/LICENSE-APACHE) 9 | [![License](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](https://github.com/clap-rs/clap/blob/clap_lex-v0.7.4/LICENSE-MIT) 10 | 11 | Dual-licensed under [Apache 2.0](LICENSE-APACHE) or [MIT](LICENSE-MIT). 12 | 13 | 1. [About](#about) 14 | 2. [API Reference](https://docs.rs/clap_lex) 15 | 3. [Questions & Discussions](https://github.com/clap-rs/clap/discussions) 16 | 4. [CONTRIBUTING](https://github.com/clap-rs/clap/blob/clap_lex-v0.7.4/clap_lex/CONTRIBUTING.md) 17 | 5. [Sponsors](https://github.com/clap-rs/clap/blob/clap_lex-v0.7.4/README.md#sponsors) 18 | 19 | ## About 20 | -------------------------------------------------------------------------------- /clap_lex/tests/testsuite/lexer.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | fn insert() { 3 | let mut raw = clap_lex::RawArgs::new(["bin", "a", "b", "c"]); 4 | let mut cursor = raw.cursor(); 5 | 6 | assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("bin"))); 7 | assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("a"))); 8 | raw.insert(&cursor, ["1", "2", "3"]); 9 | assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("1"))); 10 | assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("2"))); 11 | assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("3"))); 12 | assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("b"))); 13 | assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("c"))); 14 | 15 | let mut cursor = raw.cursor(); 16 | let rest = raw 17 | .remaining(&mut cursor) 18 | .map(|s| s.to_string_lossy()) 19 | .collect::>(); 20 | assert_eq!(rest, vec!["bin", "a", "1", "2", "3", "b", "c"]); 21 | } 22 | -------------------------------------------------------------------------------- /clap_lex/tests/testsuite/main.rs: -------------------------------------------------------------------------------- 1 | automod::dir!("tests/testsuite"); 2 | -------------------------------------------------------------------------------- /clap_mangen/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | See the [clap-wide CONTRIBUTING.md](../CONTRIBUTING.md). This will contain `clap_mangen` specific notes. 4 | -------------------------------------------------------------------------------- /clap_mangen/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../LICENSE-APACHE -------------------------------------------------------------------------------- /clap_mangen/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../LICENSE-MIT -------------------------------------------------------------------------------- /clap_mangen/examples/man.rs: -------------------------------------------------------------------------------- 1 | use clap::{arg, Command}; 2 | use clap_mangen::Man; 3 | use std::io; 4 | 5 | // Run this example as `cargo run --example man | man -l -`. 6 | 7 | fn main() -> Result<(), io::Error> { 8 | let cmd = Command::new("myapp") 9 | .version("1.0") 10 | .author("Kevin K. :Ola Nordmann ") 11 | .about("Does awesome things") 12 | .long_about( 13 | "With a longer description to help clarify some things. 14 | 15 | And a few newlines.", 16 | ) 17 | .after_help("This is an extra section added to the end of the manpage.") 18 | .after_long_help("With even more text added.") 19 | .arg( 20 | arg!(-c --config "Sets a custom config file") 21 | .long_help("Some more text about how to set a custom config file") 22 | .default_value("config.toml") 23 | .env("CONFIG_FILE"), 24 | ) 25 | .arg(arg!([output] "Sets an output file").default_value("result.txt")) 26 | .arg( 27 | arg!(-d --debug ... "Turn debugging information on") 28 | .env("DEBUG_ON") 29 | .hide_env(true), 30 | ) 31 | .subcommand( 32 | Command::new("test") 33 | .about("does testing things") 34 | .arg(arg!(-l --list "Lists test values")), 35 | ); 36 | 37 | Man::new(cmd).render(&mut io::stdout()) 38 | } 39 | -------------------------------------------------------------------------------- /clap_mangen/tests/snapshots/aliases.bash.roff: -------------------------------------------------------------------------------- 1 | .ie \n(.g .ds Aq \(aq 2 | .el .ds Aq ' 3 | .TH my-app 1 "my-app 3.0" 4 | .SH NAME 5 | my\-app \- testing bash completions 6 | .SH SYNOPSIS 7 | \fBmy\-app\fR [\fB\-f\fR|\fB\-\-flag\fR] [\fB\-o\fR|\fB\-\-option\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR] [\fIpositional\fR] 8 | .SH DESCRIPTION 9 | testing bash completions 10 | .SH OPTIONS 11 | .TP 12 | \fB\-f\fR, \fB\-\-flag\fR 13 | cmd flag 14 | .TP 15 | \fB\-o\fR, \fB\-\-option\fR 16 | cmd option 17 | .TP 18 | \fB\-h\fR, \fB\-\-help\fR 19 | Print help 20 | .TP 21 | \fB\-V\fR, \fB\-\-version\fR 22 | Print version 23 | .TP 24 | [\fIpositional\fR] 25 | 26 | .SH VERSION 27 | v3.0 28 | -------------------------------------------------------------------------------- /clap_mangen/tests/snapshots/basic.bash.roff: -------------------------------------------------------------------------------- 1 | .ie \n(.g .ds Aq \(aq 2 | .el .ds Aq ' 3 | .TH my-app 1 "my-app " 4 | .SH NAME 5 | my\-app 6 | .SH SYNOPSIS 7 | \fBmy\-app\fR [\fB\-c \fR] [\fB\-v \fR] [\fB\-h\fR|\fB\-\-help\fR] [\fIsubcommands\fR] 8 | .SH DESCRIPTION 9 | .SH OPTIONS 10 | .TP 11 | \fB\-c\fR 12 | 13 | .TP 14 | \fB\-v\fR 15 | 16 | .TP 17 | \fB\-h\fR, \fB\-\-help\fR 18 | Print help 19 | .SH SUBCOMMANDS 20 | .TP 21 | my\-app\-test(1) 22 | Subcommand 23 | with a second line 24 | .TP 25 | my\-app\-help(1) 26 | Print this message or the help of the given subcommand(s) 27 | -------------------------------------------------------------------------------- /clap_mangen/tests/snapshots/feature_sample.bash.roff: -------------------------------------------------------------------------------- 1 | .ie \n(.g .ds Aq \(aq 2 | .el .ds Aq ' 3 | .TH my-app 1 "my-app 3.0" 4 | .SH NAME 5 | my\-app \- Tests completions 6 | .SH SYNOPSIS 7 | \fBmy\-app\fR [\fB\-c\fR|\fB\-\-config\fR]... [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR] [\fIfile\fR] [\fIchoice\fR] [\fIsubcommands\fR] 8 | .SH DESCRIPTION 9 | Tests completions 10 | .SH OPTIONS 11 | .TP 12 | \fB\-c\fR, \fB\-\-config\fR 13 | some config file 14 | .TP 15 | \fB\-h\fR, \fB\-\-help\fR 16 | Print help 17 | .TP 18 | \fB\-V\fR, \fB\-\-version\fR 19 | Print version 20 | .TP 21 | [\fIfile\fR] 22 | some input file 23 | .TP 24 | [\fIchoice\fR] 25 | 26 | .br 27 | [\fIpossible values: \fRfirst, second] 28 | .SH SUBCOMMANDS 29 | .TP 30 | my\-app\-test(1) 31 | tests things 32 | .TP 33 | my\-app\-help(1) 34 | Print this message or the help of the given subcommand(s) 35 | .SH VERSION 36 | v3.0 37 | -------------------------------------------------------------------------------- /clap_mangen/tests/snapshots/help_headings.bash.roff: -------------------------------------------------------------------------------- 1 | .ie \n(.g .ds Aq \(aq 2 | .el .ds Aq ' 3 | .TH my-app 1 "my-app " 4 | .SH NAME 5 | my\-app 6 | .SH SYNOPSIS 7 | \fBmy\-app\fR [\fB\-r\fR|\fB\-\-recursive\fR] [\fB\-f\fR|\fB\-\-force\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fIcolor\fR] 8 | .SH DESCRIPTION 9 | .SH OPTIONS 10 | .TP 11 | \fB\-r\fR, \fB\-\-recursive\fR 12 | 13 | .TP 14 | \fB\-h\fR, \fB\-\-help\fR 15 | Print help 16 | .SH "CONFLICT OPTIONS" 17 | .TP 18 | \fB\-f\fR, \fB\-\-force\fR 19 | 20 | .SH "GLOBAL OPTIONS" 21 | .TP 22 | [\fIcolor\fR] 23 | 24 | .br 25 | [\fIpossible values: \fRalways, never, auto] 26 | -------------------------------------------------------------------------------- /clap_mangen/tests/snapshots/hidden_option.bash.roff: -------------------------------------------------------------------------------- 1 | .ie \n(.g .ds Aq \(aq 2 | .el .ds Aq ' 3 | .TH my-app 1 "my-app " 4 | .SH NAME 5 | my\-app 6 | .SH SYNOPSIS 7 | \fBmy\-app\fR [\fB\-\-config\fR] [\fB\-h\fR|\fB\-\-help\fR] 8 | .SH DESCRIPTION 9 | .SH OPTIONS 10 | .TP 11 | \fB\-\-config\fR 12 | 13 | .TP 14 | \fB\-h\fR, \fB\-\-help\fR 15 | Print help 16 | -------------------------------------------------------------------------------- /clap_mangen/tests/snapshots/possible_values.bash.roff: -------------------------------------------------------------------------------- 1 | .ie \n(.g .ds Aq \(aq 2 | .el .ds Aq ' 3 | .TH my-app 1 "my-app " 4 | .SH NAME 5 | my\-app 6 | .SH SYNOPSIS 7 | \fBmy\-app\fR [\fB\-\-choice\fR] [\fB\-\-method\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fIpositional_choice\fR] 8 | .SH DESCRIPTION 9 | .SH OPTIONS 10 | .TP 11 | \fB\-\-choice\fR 12 | 13 | .br 14 | [\fIpossible values: \fRbash, fish, zsh] 15 | .TP 16 | \fB\-\-method\fR 17 | 18 | .br 19 | \fIPossible values:\fR 20 | .RS 14 21 | .IP \(bu 2 22 | fast: use the Fast method 23 | .IP \(bu 2 24 | slow: use the slow method 25 | .RE 26 | .TP 27 | \fB\-h\fR, \fB\-\-help\fR 28 | Print help (see a summary with \*(Aq\-h\*(Aq) 29 | .TP 30 | [\fIpositional_choice\fR] 31 | Pick the Position you want the command to run in 32 | .br 33 | 34 | .br 35 | \fIPossible values:\fR 36 | .RS 14 37 | .IP \(bu 2 38 | left: run left adjusted 39 | .IP \(bu 2 40 | right 41 | .RE 42 | -------------------------------------------------------------------------------- /clap_mangen/tests/snapshots/quoting.bash.roff: -------------------------------------------------------------------------------- 1 | .ie \n(.g .ds Aq \(aq 2 | .el .ds Aq ' 3 | .TH my-app 1 "my-app 3.0" 4 | .SH NAME 5 | my\-app 6 | .SH SYNOPSIS 7 | \fBmy\-app\fR [\fB\-\-single\-quotes\fR] [\fB\-\-double\-quotes\fR] [\fB\-\-backticks\fR] [\fB\-\-backslash\fR] [\fB\-\-brackets\fR] [\fB\-\-expansions\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR] [\fIsubcommands\fR] 8 | .SH DESCRIPTION 9 | .SH OPTIONS 10 | .TP 11 | \fB\-\-single\-quotes\fR 12 | Can be \*(Aqalways\*(Aq, \*(Aqauto\*(Aq, or \*(Aqnever\*(Aq 13 | .TP 14 | \fB\-\-double\-quotes\fR 15 | Can be "always", "auto", or "never" 16 | .TP 17 | \fB\-\-backticks\fR 18 | For more information see `echo test` 19 | .TP 20 | \fB\-\-backslash\fR 21 | Avoid \*(Aq\\n\*(Aq 22 | .TP 23 | \fB\-\-brackets\fR 24 | List packages [filter] 25 | .TP 26 | \fB\-\-expansions\fR 27 | Execute the shell command with $SHELL 28 | .TP 29 | \fB\-h\fR, \fB\-\-help\fR 30 | Print help 31 | .TP 32 | \fB\-V\fR, \fB\-\-version\fR 33 | Print version 34 | .SH SUBCOMMANDS 35 | .TP 36 | my\-app\-cmd\-single\-quotes(1) 37 | Can be \*(Aqalways\*(Aq, \*(Aqauto\*(Aq, or \*(Aqnever\*(Aq 38 | .TP 39 | my\-app\-cmd\-double\-quotes(1) 40 | Can be "always", "auto", or "never" 41 | .TP 42 | my\-app\-cmd\-backticks(1) 43 | For more information see `echo test` 44 | .TP 45 | my\-app\-cmd\-backslash(1) 46 | Avoid \*(Aq\\n\*(Aq 47 | .TP 48 | my\-app\-cmd\-brackets(1) 49 | List packages [filter] 50 | .TP 51 | my\-app\-cmd\-expansions(1) 52 | Execute the shell command with $SHELL 53 | .TP 54 | my\-app\-help(1) 55 | Print this message or the help of the given subcommand(s) 56 | .SH VERSION 57 | v3.0 58 | -------------------------------------------------------------------------------- /clap_mangen/tests/snapshots/special_commands.bash.roff: -------------------------------------------------------------------------------- 1 | .ie \n(.g .ds Aq \(aq 2 | .el .ds Aq ' 3 | .TH my-app 1 "my-app 3.0" 4 | .SH NAME 5 | my\-app \- Tests completions 6 | .SH SYNOPSIS 7 | \fBmy\-app\fR [\fB\-c\fR|\fB\-\-config\fR]... [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR] [\fIfile\fR] [\fIchoice\fR] [\fIsubcommands\fR] 8 | .SH DESCRIPTION 9 | Tests completions 10 | .SH OPTIONS 11 | .TP 12 | \fB\-c\fR, \fB\-\-config\fR 13 | some config file 14 | .TP 15 | \fB\-h\fR, \fB\-\-help\fR 16 | Print help 17 | .TP 18 | \fB\-V\fR, \fB\-\-version\fR 19 | Print version 20 | .TP 21 | [\fIfile\fR] 22 | some input file 23 | .TP 24 | [\fIchoice\fR] 25 | 26 | .br 27 | [\fIpossible values: \fRfirst, second] 28 | .SH SUBCOMMANDS 29 | .TP 30 | my\-app\-test(1) 31 | tests things 32 | .TP 33 | my\-app\-some_cmd(1) 34 | tests other things 35 | .TP 36 | my\-app\-some\-cmd\-with\-hyphens(1) 37 | .TP 38 | my\-app\-help(1) 39 | Print this message or the help of the given subcommand(s) 40 | .SH VERSION 41 | v3.0 42 | -------------------------------------------------------------------------------- /clap_mangen/tests/snapshots/sub_subcommand_help.roff: -------------------------------------------------------------------------------- 1 | .ie \n(.g .ds Aq \(aq 2 | .el .ds Aq ' 3 | .TH my-app-help 1 "help " 4 | .SH NAME 5 | my\-app\-help \- Print this message or the help of the given subcommand(s) 6 | .SH SYNOPSIS 7 | \fBmy\-app help\fR [\fIsubcommands\fR] 8 | .SH DESCRIPTION 9 | Print this message or the help of the given subcommand(s) 10 | .SH SUBCOMMANDS 11 | .TP 12 | my\-app\-help\-test(1) 13 | tests things 14 | .TP 15 | my\-app\-help\-some_cmd(1) 16 | top level subcommand 17 | .TP 18 | my\-app\-help\-help(1) 19 | Print this message or the help of the given subcommand(s) 20 | -------------------------------------------------------------------------------- /clap_mangen/tests/snapshots/sub_subcommands.bash.roff: -------------------------------------------------------------------------------- 1 | .ie \n(.g .ds Aq \(aq 2 | .el .ds Aq ' 3 | .TH my-app 1 "my-app 3.0" 4 | .SH NAME 5 | my\-app \- Tests completions 6 | .SH SYNOPSIS 7 | \fBmy\-app\fR [\fB\-c\fR|\fB\-\-config\fR]... [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR] [\fIfile\fR] [\fIchoice\fR] [\fIsubcommands\fR] 8 | .SH DESCRIPTION 9 | Tests completions 10 | .SH OPTIONS 11 | .TP 12 | \fB\-c\fR, \fB\-\-config\fR 13 | some config file 14 | .TP 15 | \fB\-h\fR, \fB\-\-help\fR 16 | Print help 17 | .TP 18 | \fB\-V\fR, \fB\-\-version\fR 19 | Print version 20 | .TP 21 | [\fIfile\fR] 22 | some input file 23 | .TP 24 | [\fIchoice\fR] 25 | 26 | .br 27 | [\fIpossible values: \fRfirst, second] 28 | .SH SUBCOMMANDS 29 | .TP 30 | my\-app\-test(1) 31 | tests things 32 | .TP 33 | my\-app\-some_cmd(1) 34 | top level subcommand 35 | .TP 36 | my\-app\-help(1) 37 | Print this message or the help of the given subcommand(s) 38 | .SH VERSION 39 | v3.0 40 | -------------------------------------------------------------------------------- /clap_mangen/tests/snapshots/value_env.bash.roff: -------------------------------------------------------------------------------- 1 | .ie \n(.g .ds Aq \(aq 2 | .el .ds Aq ' 3 | .TH my-app 1 "my-app " 4 | .SH NAME 5 | my\-app 6 | .SH SYNOPSIS 7 | \fBmy\-app\fR [\fB\-c \fR] [\fB\-h\fR|\fB\-\-help\fR] 8 | .SH DESCRIPTION 9 | .SH OPTIONS 10 | .TP 11 | \fB\-c\fR [default: config.toml] 12 | Set configuration file path 13 | .RS 14 | May also be specified with the \fBCONFIG_FILE\fR environment variable. 15 | .RE 16 | .TP 17 | \fB\-h\fR, \fB\-\-help\fR 18 | Print help (see a summary with \*(Aq\-h\*(Aq) 19 | -------------------------------------------------------------------------------- /clap_mangen/tests/snapshots/value_hint.bash.roff: -------------------------------------------------------------------------------- 1 | .ie \n(.g .ds Aq \(aq 2 | .el .ds Aq ' 3 | .TH my-app 1 "my-app " 4 | .SH NAME 5 | my\-app 6 | .SH SYNOPSIS 7 | \fBmy\-app\fR [\fB\-\-choice\fR] [\fB\-\-unknown\fR] [\fB\-\-other\fR] [\fB\-p\fR|\fB\-\-path\fR] [\fB\-f\fR|\fB\-\-file\fR] [\fB\-d\fR|\fB\-\-dir\fR] [\fB\-e\fR|\fB\-\-exe\fR] [\fB\-\-cmd\-name\fR] [\fB\-c\fR|\fB\-\-cmd\fR] [\fB\-u\fR|\fB\-\-user\fR] [\fB\-H\fR|\fB\-\-host\fR] [\fB\-\-url\fR] [\fB\-\-email\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fIcommand_with_args\fR] 8 | .SH DESCRIPTION 9 | .SH OPTIONS 10 | .TP 11 | \fB\-\-choice\fR 12 | 13 | .br 14 | [\fIpossible values: \fRbash, fish, zsh] 15 | .TP 16 | \fB\-\-unknown\fR 17 | 18 | .TP 19 | \fB\-\-other\fR 20 | 21 | .TP 22 | \fB\-p\fR, \fB\-\-path\fR 23 | 24 | .TP 25 | \fB\-f\fR, \fB\-\-file\fR 26 | 27 | .TP 28 | \fB\-d\fR, \fB\-\-dir\fR 29 | 30 | .TP 31 | \fB\-e\fR, \fB\-\-exe\fR 32 | 33 | .TP 34 | \fB\-\-cmd\-name\fR 35 | 36 | .TP 37 | \fB\-c\fR, \fB\-\-cmd\fR 38 | 39 | .TP 40 | \fB\-u\fR, \fB\-\-user\fR 41 | 42 | .TP 43 | \fB\-H\fR, \fB\-\-host\fR 44 | 45 | .TP 46 | \fB\-\-url\fR 47 | 48 | .TP 49 | \fB\-\-email\fR 50 | 51 | .TP 52 | \fB\-h\fR, \fB\-\-help\fR 53 | Print help 54 | .TP 55 | [\fIcommand_with_args\fR] 56 | 57 | -------------------------------------------------------------------------------- /clap_mangen/tests/snapshots/value_name_without_arg.bash.roff: -------------------------------------------------------------------------------- 1 | .ie \n(.g .ds Aq \(aq 2 | .el .ds Aq ' 3 | .TH my-app 1 "my-app " 4 | .SH NAME 5 | my\-app 6 | .SH SYNOPSIS 7 | \fBmy\-app\fR [\fB\-\-flag\fR] [\fB\-h\fR|\fB\-\-help\fR] 8 | .SH DESCRIPTION 9 | .SH OPTIONS 10 | .TP 11 | \fB\-\-flag\fR 12 | 13 | .TP 14 | \fB\-h\fR, \fB\-\-help\fR 15 | Print help 16 | -------------------------------------------------------------------------------- /clap_mangen/tests/testsuite/main.rs: -------------------------------------------------------------------------------- 1 | automod::dir!("tests/testsuite"); 2 | -------------------------------------------------------------------------------- /committed.toml: -------------------------------------------------------------------------------- 1 | style="conventional" 2 | ignore_author_re="(dependabot|renovate)" 3 | merge_commit = false 4 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | We try to focus our documentation on the [four types of 4 | documentation](https://documentation.divio.com/). Examples fit into this by 5 | providing: 6 | - [Cookbook / How-To Guides](https://docs.rs/clap/latest/clap/_cookbook/index.html) 7 | - Tutorials ([derive](https://docs.rs/clap/latest/clap/_derive/_tutorial/index.html), [builder](https://docs.rs/clap/latest/clap/_tutorial/index.html)) 8 | 9 | This directory contains the source for the above. 10 | 11 | ## Contributing 12 | 13 | New examples should fit within the above structure and support their narrative 14 | - Add the example to [Cargo.toml](../Cargo.toml) for any `required-features` 15 | - Document how the example works with a `.md` file which will be verified using [trycmd](https://docs.rs/trycmd) 16 | - Pull the `.rs` and `.md` file into the appropriate module doc comment to be accessible on docs.rs 17 | -------------------------------------------------------------------------------- /examples/cargo-example-derive.md: -------------------------------------------------------------------------------- 1 | For more on creating a custom subcommand, see [the cargo 2 | book](https://doc.rust-lang.org/cargo/reference/external-tools.html#custom-subcommands). 3 | The crate [`clap-cargo`](https://github.com/crate-ci/clap-cargo) can help in 4 | mimicking cargo's interface. 5 | 6 | The help looks like: 7 | ```console 8 | $ cargo-example-derive --help 9 | Usage: cargo 10 | 11 | Commands: 12 | example-derive A simple to use, efficient, and full-featured Command Line Argument Parser 13 | help Print this message or the help of the given subcommand(s) 14 | 15 | Options: 16 | -h, --help Print help 17 | 18 | $ cargo-example-derive example-derive --help 19 | A simple to use, efficient, and full-featured Command Line Argument Parser 20 | 21 | Usage: cargo example-derive [OPTIONS] 22 | 23 | Options: 24 | --manifest-path 25 | -h, --help Print help 26 | -V, --version Print version 27 | 28 | ``` 29 | 30 | Then to directly invoke the command, run: 31 | ```console 32 | $ cargo-example-derive example-derive 33 | None 34 | 35 | $ cargo-example-derive example-derive --manifest-path Cargo.toml 36 | Some("Cargo.toml") 37 | 38 | ``` 39 | -------------------------------------------------------------------------------- /examples/cargo-example-derive.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser)] // requires `derive` feature 4 | #[command(name = "cargo")] 5 | #[command(bin_name = "cargo")] 6 | #[command(styles = CLAP_STYLING)] 7 | enum CargoCli { 8 | ExampleDerive(ExampleDeriveArgs), 9 | } 10 | 11 | // See also `clap_cargo::style::CLAP_STYLING` 12 | pub const CLAP_STYLING: clap::builder::styling::Styles = clap::builder::styling::Styles::styled() 13 | .header(clap_cargo::style::HEADER) 14 | .usage(clap_cargo::style::USAGE) 15 | .literal(clap_cargo::style::LITERAL) 16 | .placeholder(clap_cargo::style::PLACEHOLDER) 17 | .error(clap_cargo::style::ERROR) 18 | .valid(clap_cargo::style::VALID) 19 | .invalid(clap_cargo::style::INVALID); 20 | 21 | #[derive(clap::Args)] 22 | #[command(version, about, long_about = None)] 23 | struct ExampleDeriveArgs { 24 | #[arg(long)] 25 | manifest_path: Option, 26 | } 27 | 28 | fn main() { 29 | let CargoCli::ExampleDerive(args) = CargoCli::parse(); 30 | println!("{:?}", args.manifest_path); 31 | } 32 | -------------------------------------------------------------------------------- /examples/cargo-example.md: -------------------------------------------------------------------------------- 1 | For more on creating a custom subcommand, see [the cargo 2 | book](https://doc.rust-lang.org/cargo/reference/external-tools.html#custom-subcommands). 3 | The crate [`clap-cargo`](https://github.com/crate-ci/clap-cargo) can help in 4 | mimicking cargo's interface. 5 | 6 | The help looks like: 7 | ```console 8 | $ cargo-example --help 9 | Usage: cargo 10 | 11 | Commands: 12 | example A simple to use, efficient, and full-featured Command Line Argument Parser 13 | help Print this message or the help of the given subcommand(s) 14 | 15 | Options: 16 | -h, --help Print help 17 | 18 | $ cargo-example example --help 19 | A simple to use, efficient, and full-featured Command Line Argument Parser 20 | 21 | Usage: cargo example [OPTIONS] 22 | 23 | Options: 24 | --manifest-path 25 | -h, --help Print help 26 | -V, --version Print version 27 | 28 | ``` 29 | 30 | Then to directly invoke the command, run: 31 | ```console 32 | $ cargo-example example 33 | None 34 | 35 | $ cargo-example example --manifest-path Cargo.toml 36 | Some("Cargo.toml") 37 | 38 | ``` 39 | -------------------------------------------------------------------------------- /examples/cargo-example.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let cmd = clap::Command::new("cargo") 3 | .bin_name("cargo") 4 | .styles(CLAP_STYLING) 5 | .subcommand_required(true) 6 | .subcommand( 7 | clap::command!("example").arg( 8 | clap::arg!(--"manifest-path" ) 9 | .value_parser(clap::value_parser!(std::path::PathBuf)), 10 | ), 11 | ); 12 | let matches = cmd.get_matches(); 13 | let matches = match matches.subcommand() { 14 | Some(("example", matches)) => matches, 15 | _ => unreachable!("clap should ensure we don't get here"), 16 | }; 17 | let manifest_path = matches.get_one::("manifest-path"); 18 | println!("{manifest_path:?}"); 19 | } 20 | 21 | // See also `clap_cargo::style::CLAP_STYLING` 22 | pub const CLAP_STYLING: clap::builder::styling::Styles = clap::builder::styling::Styles::styled() 23 | .header(clap_cargo::style::HEADER) 24 | .usage(clap_cargo::style::USAGE) 25 | .literal(clap_cargo::style::LITERAL) 26 | .placeholder(clap_cargo::style::PLACEHOLDER) 27 | .error(clap_cargo::style::ERROR) 28 | .valid(clap_cargo::style::VALID) 29 | .invalid(clap_cargo::style::INVALID); 30 | -------------------------------------------------------------------------------- /examples/demo.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ demo --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: demo[EXE] [OPTIONS] --name 6 | 7 | Options: 8 | -n, --name Name of the person to greet 9 | -c, --count Number of times to greet [default: 1] 10 | -h, --help Print help 11 | -V, --version Print version 12 | 13 | $ demo --name Me 14 | Hello Me! 15 | 16 | ``` 17 | *(version number and `.exe` extension on windows replaced by placeholders)* 18 | -------------------------------------------------------------------------------- /examples/demo.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | /// Simple program to greet a person 4 | #[derive(Parser, Debug)] 5 | #[command(version, about, long_about = None)] 6 | struct Args { 7 | /// Name of the person to greet 8 | #[arg(short, long)] 9 | name: String, 10 | 11 | /// Number of times to greet 12 | #[arg(short, long, default_value_t = 1)] 13 | count: u8, 14 | } 15 | 16 | fn main() { 17 | let args = Args::parse(); 18 | 19 | for _ in 0..args.count { 20 | println!("Hello {}!", args.name); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /examples/derive_ref/augment_args.rs: -------------------------------------------------------------------------------- 1 | use clap::{arg, Args, Command, FromArgMatches as _}; 2 | 3 | #[derive(Args, Debug)] 4 | struct DerivedArgs { 5 | #[arg(short, long)] 6 | derived: bool, 7 | } 8 | 9 | fn main() { 10 | let cli = Command::new("CLI").arg(arg!(-b - -built).action(clap::ArgAction::SetTrue)); 11 | // Augment built args with derived args 12 | let cli = DerivedArgs::augment_args(cli); 13 | 14 | let matches = cli.get_matches(); 15 | println!("Value of built: {:?}", matches.get_flag("built")); 16 | println!( 17 | "Value of derived via ArgMatches: {:?}", 18 | matches.get_flag("derived") 19 | ); 20 | 21 | // Since DerivedArgs implements FromArgMatches, we can extract it from the unstructured ArgMatches. 22 | // This is the main benefit of using derived arguments. 23 | let derived_matches = DerivedArgs::from_arg_matches(&matches) 24 | .map_err(|err| err.exit()) 25 | .unwrap(); 26 | println!("Value of derived: {derived_matches:#?}"); 27 | } 28 | -------------------------------------------------------------------------------- /examples/derive_ref/augment_subcommands.rs: -------------------------------------------------------------------------------- 1 | use clap::{Command, FromArgMatches as _, Parser, Subcommand as _}; 2 | 3 | #[derive(Parser, Debug)] 4 | enum Subcommands { 5 | Derived { 6 | #[arg(short, long)] 7 | derived_flag: bool, 8 | }, 9 | } 10 | 11 | fn main() { 12 | let cli = Command::new("Built CLI"); 13 | // Augment with derived subcommands 14 | let cli = Subcommands::augment_subcommands(cli); 15 | 16 | let matches = cli.get_matches(); 17 | let derived_subcommands = Subcommands::from_arg_matches(&matches) 18 | .map_err(|err| err.exit()) 19 | .unwrap(); 20 | println!("Derived subcommands: {derived_subcommands:#?}"); 21 | } 22 | -------------------------------------------------------------------------------- /examples/escaped-positional-derive.md: -------------------------------------------------------------------------------- 1 | **This requires enabling the [`derive` feature flag][crate::_features].** 2 | 3 | You can use `--` to escape further arguments. 4 | 5 | Let's see what this looks like in the help: 6 | ```console 7 | $ escaped-positional-derive --help 8 | A simple to use, efficient, and full-featured Command Line Argument Parser 9 | 10 | Usage: escaped-positional-derive[EXE] [OPTIONS] [-- ...] 11 | 12 | Arguments: 13 | [SLOP]... 14 | 15 | Options: 16 | -f 17 | -p 18 | -h, --help Print help 19 | -V, --version Print version 20 | 21 | ``` 22 | 23 | Here is a baseline without any arguments: 24 | ```console 25 | $ escaped-positional-derive 26 | -f used: false 27 | -p's value: None 28 | 'slops' values: [] 29 | 30 | ``` 31 | 32 | Notice that we can't pass positional arguments before `--`: 33 | ```console 34 | $ escaped-positional-derive foo bar 35 | ? failed 36 | error: unexpected argument 'foo' found 37 | 38 | Usage: escaped-positional-derive[EXE] [OPTIONS] [-- ...] 39 | 40 | For more information, try '--help'. 41 | 42 | ``` 43 | 44 | But you can after: 45 | ```console 46 | $ escaped-positional-derive -f -p=bob -- sloppy slop slop 47 | -f used: true 48 | -p's value: Some("bob") 49 | 'slops' values: ["sloppy", "slop", "slop"] 50 | 51 | ``` 52 | 53 | As mentioned, the parser will directly pass everything through: 54 | ```console 55 | $ escaped-positional-derive -- -f -p=bob sloppy slop slop 56 | -f used: false 57 | -p's value: None 58 | 'slops' values: ["-f", "-p=bob", "sloppy", "slop", "slop"] 59 | 60 | ``` 61 | -------------------------------------------------------------------------------- /examples/escaped-positional-derive.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser)] // requires `derive` feature 4 | #[command(version, about, long_about = None)] 5 | struct Cli { 6 | #[arg(short = 'f')] 7 | eff: bool, 8 | 9 | #[arg(short = 'p', value_name = "PEAR")] 10 | pea: Option, 11 | 12 | #[arg(last = true)] 13 | slop: Vec, 14 | } 15 | 16 | fn main() { 17 | let args = Cli::parse(); 18 | 19 | // This is what will happen with `myprog -f -p=bob -- sloppy slop slop`... 20 | println!("-f used: {:?}", args.eff); // -f used: true 21 | println!("-p's value: {:?}", args.pea); // -p's value: Some("bob") 22 | println!("'slops' values: {:?}", args.slop); // 'slops' values: Some(["sloppy", "slop", "slop"]) 23 | 24 | // Continued program logic goes here... 25 | } 26 | -------------------------------------------------------------------------------- /examples/escaped-positional.md: -------------------------------------------------------------------------------- 1 | **This requires enabling the [`cargo` feature flag][crate::_features].** 2 | 3 | You can use `--` to escape further arguments. 4 | 5 | Let's see what this looks like in the help: 6 | ```console 7 | $ escaped-positional --help 8 | A simple to use, efficient, and full-featured Command Line Argument Parser 9 | 10 | Usage: escaped-positional[EXE] [OPTIONS] [-- ...] 11 | 12 | Arguments: 13 | [SLOP]... 14 | 15 | Options: 16 | -f 17 | -p 18 | -h, --help Print help 19 | -V, --version Print version 20 | 21 | ``` 22 | 23 | Here is a baseline without any arguments: 24 | ```console 25 | $ escaped-positional 26 | -f used: false 27 | -p's value: None 28 | 'slops' values: [] 29 | 30 | ``` 31 | 32 | Notice that we can't pass positional arguments before `--`: 33 | ```console 34 | $ escaped-positional foo bar 35 | ? failed 36 | error: unexpected argument 'foo' found 37 | 38 | Usage: escaped-positional[EXE] [OPTIONS] [-- ...] 39 | 40 | For more information, try '--help'. 41 | 42 | ``` 43 | 44 | But you can after: 45 | ```console 46 | $ escaped-positional -f -p=bob -- sloppy slop slop 47 | -f used: true 48 | -p's value: Some("bob") 49 | 'slops' values: ["sloppy", "slop", "slop"] 50 | 51 | ``` 52 | 53 | As mentioned, the parser will directly pass everything through: 54 | ```console 55 | $ escaped-positional -- -f -p=bob sloppy slop slop 56 | -f used: false 57 | -p's value: None 58 | 'slops' values: ["-f", "-p=bob", "sloppy", "slop", "slop"] 59 | 60 | ``` 61 | -------------------------------------------------------------------------------- /examples/escaped-positional.rs: -------------------------------------------------------------------------------- 1 | use clap::{arg, command, value_parser, ArgAction}; 2 | 3 | fn main() { 4 | let matches = command!() // requires `cargo` feature 5 | .arg(arg!(eff: -f).action(ArgAction::SetTrue)) 6 | .arg(arg!(pea: -p ).value_parser(value_parser!(String))) 7 | .arg( 8 | // Indicates that `slop` is only accessible after `--`. 9 | arg!(slop: [SLOP]) 10 | .num_args(1..) 11 | .last(true) 12 | .value_parser(value_parser!(String)), 13 | ) 14 | .get_matches(); 15 | 16 | // This is what will happen with `myprog -f -p=bob -- sloppy slop slop`... 17 | 18 | // -f used: true 19 | println!("-f used: {:?}", matches.get_flag("eff")); 20 | // -p's value: Some("bob") 21 | println!("-p's value: {:?}", matches.get_one::("pea")); 22 | // 'slops' values: Some(["sloppy", "slop", "slop"]) 23 | println!( 24 | "'slops' values: {:?}", 25 | matches 26 | .get_many::("slop") 27 | .map(|vals| vals.collect::>()) 28 | .unwrap_or_default() 29 | ); 30 | 31 | // Continued program logic goes here... 32 | } 33 | -------------------------------------------------------------------------------- /examples/find.md: -------------------------------------------------------------------------------- 1 | `find` is an example of position-sensitive flags 2 | 3 | ```console 4 | $ find --help 5 | A simple to use, efficient, and full-featured Command Line Argument Parser 6 | 7 | Usage: find[EXE] [OPTIONS] 8 | 9 | Options: 10 | -h, --help Print help 11 | -V, --version Print version 12 | 13 | TESTS: 14 | --empty File is empty and is either a regular file or a directory 15 | --name Base of file name (the path with the leading directories removed) matches shell 16 | pattern pattern 17 | 18 | OPERATORS: 19 | -o, --or expr2 is not evaluate if exp1 is true 20 | -a, --and Same as `expr1 expr1` 21 | 22 | $ find --empty -o --name .keep 23 | [ 24 | ( 25 | "empty", 26 | Bool( 27 | true, 28 | ), 29 | ), 30 | ( 31 | "or", 32 | Bool( 33 | true, 34 | ), 35 | ), 36 | ( 37 | "name", 38 | String( 39 | ".keep", 40 | ), 41 | ), 42 | ] 43 | 44 | $ find --empty -o --name .keep -o --name foo 45 | [ 46 | ( 47 | "empty", 48 | Bool( 49 | true, 50 | ), 51 | ), 52 | ( 53 | "or", 54 | Bool( 55 | true, 56 | ), 57 | ), 58 | ( 59 | "name", 60 | String( 61 | ".keep", 62 | ), 63 | ), 64 | ( 65 | "or", 66 | Bool( 67 | true, 68 | ), 69 | ), 70 | ( 71 | "name", 72 | String( 73 | "foo", 74 | ), 75 | ), 76 | ] 77 | 78 | ``` 79 | 80 | -------------------------------------------------------------------------------- /examples/multicall-busybox.md: -------------------------------------------------------------------------------- 1 | See the documentation for [`Command::multicall`][crate::Command::multicall] for rationale. 2 | 3 | This example omits every command except true and false, 4 | which are the most trivial to implement, 5 | ```console 6 | $ busybox true 7 | ? 0 8 | 9 | $ busybox false 10 | ? 1 11 | 12 | ``` 13 | *Note: without the links setup, we can't demonstrate the multicall behavior* 14 | 15 | But includes the `--install` option as an example of why it can be useful 16 | for the main program to take arguments that aren't applet subcommands. 17 | ```console 18 | $ busybox --install 19 | ? failed 20 | ... 21 | 22 | ``` 23 | 24 | Though users must pass something: 25 | ```console 26 | $ busybox 27 | ? failed 28 | Usage: busybox [OPTIONS] [APPLET] 29 | 30 | APPLETS: 31 | true does nothing successfully 32 | false does nothing unsuccessfully 33 | help Print this message or the help of the given subcommand(s) 34 | 35 | Options: 36 | --install Install hardlinks for all subcommands in path 37 | -h, --help Print help 38 | 39 | ``` 40 | -------------------------------------------------------------------------------- /examples/multicall-hostname.md: -------------------------------------------------------------------------------- 1 | See the documentation for [`Command::multicall`][crate::Command::multicall] for rationale. 2 | 3 | This example omits the implementation of displaying address config 4 | 5 | ```console 6 | $ hostname 7 | www 8 | 9 | ``` 10 | *Note: without the links setup, we can't demonstrate the multicall behavior* 11 | -------------------------------------------------------------------------------- /examples/multicall-hostname.rs: -------------------------------------------------------------------------------- 1 | use clap::Command; 2 | 3 | fn main() { 4 | let cmd = Command::new(env!("CARGO_CRATE_NAME")) 5 | .multicall(true) 6 | .arg_required_else_help(true) 7 | .subcommand_value_name("APPLET") 8 | .subcommand_help_heading("APPLETS") 9 | .subcommand(Command::new("hostname").about("show hostname part of FQDN")) 10 | .subcommand(Command::new("dnsdomainname").about("show domain name part of FQDN")); 11 | 12 | match cmd.get_matches().subcommand_name() { 13 | Some("hostname") => println!("www"), 14 | Some("dnsdomainname") => println!("example.com"), 15 | _ => unreachable!("parser should ensure only valid subcommand names are used"), 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/tutorial_builder/01_quick.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 01_quick --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 01_quick[EXE] [OPTIONS] [name] [COMMAND] 6 | 7 | Commands: 8 | test does testing things 9 | help Print this message or the help of the given subcommand(s) 10 | 11 | Arguments: 12 | [name] Optional name to operate on 13 | 14 | Options: 15 | -c, --config Sets a custom config file 16 | -d, --debug... Turn debugging information on 17 | -h, --help Print help 18 | -V, --version Print version 19 | 20 | ``` 21 | 22 | By default, the program does nothing: 23 | ```console 24 | $ 01_quick 25 | Debug mode is off 26 | 27 | ``` 28 | 29 | But you can mix and match the various features 30 | ```console 31 | $ 01_quick -dd test 32 | Debug mode is on 33 | Not printing testing lists... 34 | 35 | ``` 36 | -------------------------------------------------------------------------------- /examples/tutorial_builder/02_app_settings.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 02_app_settings --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 02_app_settings[EXE] --two --one 6 | 7 | Options: 8 | --two 9 | 10 | --one 11 | 12 | -h, --help 13 | Print help 14 | -V, --version 15 | Print version 16 | 17 | ``` 18 | -------------------------------------------------------------------------------- /examples/tutorial_builder/02_app_settings.rs: -------------------------------------------------------------------------------- 1 | use clap::{arg, command, ArgAction}; 2 | 3 | fn main() { 4 | let matches = command!() // requires `cargo` feature 5 | .next_line_help(true) 6 | .arg(arg!(--two ).required(true).action(ArgAction::Set)) 7 | .arg(arg!(--one ).required(true).action(ArgAction::Set)) 8 | .get_matches(); 9 | 10 | println!( 11 | "two: {:?}", 12 | matches.get_one::("two").expect("required") 13 | ); 14 | println!( 15 | "one: {:?}", 16 | matches.get_one::("one").expect("required") 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /examples/tutorial_builder/02_apps.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 02_apps --help 3 | Does awesome things 4 | 5 | Usage: 02_apps[EXE] --two --one 6 | 7 | Options: 8 | --two 9 | --one 10 | -h, --help Print help 11 | -V, --version Print version 12 | 13 | $ 02_apps --version 14 | MyApp 1.0 15 | 16 | ``` 17 | -------------------------------------------------------------------------------- /examples/tutorial_builder/02_apps.rs: -------------------------------------------------------------------------------- 1 | use clap::{arg, Command}; 2 | 3 | fn main() { 4 | let matches = Command::new("MyApp") 5 | .version("1.0") 6 | .about("Does awesome things") 7 | .arg(arg!(--two ).required(true)) 8 | .arg(arg!(--one ).required(true)) 9 | .get_matches(); 10 | 11 | println!( 12 | "two: {:?}", 13 | matches.get_one::("two").expect("required") 14 | ); 15 | println!( 16 | "one: {:?}", 17 | matches.get_one::("one").expect("required") 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /examples/tutorial_builder/02_crate.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 02_crate --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 02_crate[EXE] --two --one 6 | 7 | Options: 8 | --two 9 | --one 10 | -h, --help Print help 11 | -V, --version Print version 12 | 13 | $ 02_crate --version 14 | clap [..] 15 | 16 | ``` 17 | -------------------------------------------------------------------------------- /examples/tutorial_builder/02_crate.rs: -------------------------------------------------------------------------------- 1 | use clap::{arg, command}; 2 | 3 | fn main() { 4 | // requires `cargo` feature, reading name, version, author, and description from `Cargo.toml` 5 | let matches = command!() 6 | .arg(arg!(--two ).required(true)) 7 | .arg(arg!(--one ).required(true)) 8 | .get_matches(); 9 | 10 | println!( 11 | "two: {:?}", 12 | matches.get_one::("two").expect("required") 13 | ); 14 | println!( 15 | "one: {:?}", 16 | matches.get_one::("one").expect("required") 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /examples/tutorial_builder/03_01_flag_bool.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 03_01_flag_bool --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 03_01_flag_bool[EXE] [OPTIONS] 6 | 7 | Options: 8 | -v, --verbose 9 | -h, --help Print help 10 | -V, --version Print version 11 | 12 | $ 03_01_flag_bool 13 | verbose: false 14 | 15 | $ 03_01_flag_bool --verbose 16 | verbose: true 17 | 18 | $ 03_01_flag_bool --verbose --verbose 19 | ? failed 20 | error: the argument '--verbose' cannot be used multiple times 21 | 22 | Usage: 03_01_flag_bool[EXE] [OPTIONS] 23 | 24 | For more information, try '--help'. 25 | 26 | ``` 27 | -------------------------------------------------------------------------------- /examples/tutorial_builder/03_01_flag_bool.rs: -------------------------------------------------------------------------------- 1 | use clap::{command, Arg, ArgAction}; 2 | 3 | fn main() { 4 | let matches = command!() // requires `cargo` feature 5 | .arg( 6 | Arg::new("verbose") 7 | .short('v') 8 | .long("verbose") 9 | .action(ArgAction::SetTrue), 10 | ) 11 | .get_matches(); 12 | 13 | println!("verbose: {:?}", matches.get_flag("verbose")); 14 | } 15 | -------------------------------------------------------------------------------- /examples/tutorial_builder/03_01_flag_count.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 03_01_flag_count --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 03_01_flag_count[EXE] [OPTIONS] 6 | 7 | Options: 8 | -v, --verbose... 9 | -h, --help Print help 10 | -V, --version Print version 11 | 12 | $ 03_01_flag_count 13 | verbose: 0 14 | 15 | $ 03_01_flag_count --verbose 16 | verbose: 1 17 | 18 | $ 03_01_flag_count --verbose --verbose 19 | verbose: 2 20 | 21 | ``` 22 | -------------------------------------------------------------------------------- /examples/tutorial_builder/03_01_flag_count.rs: -------------------------------------------------------------------------------- 1 | use clap::{command, Arg, ArgAction}; 2 | 3 | fn main() { 4 | let matches = command!() // requires `cargo` feature 5 | .arg( 6 | Arg::new("verbose") 7 | .short('v') 8 | .long("verbose") 9 | .action(ArgAction::Count), 10 | ) 11 | .get_matches(); 12 | 13 | println!("verbose: {:?}", matches.get_count("verbose")); 14 | } 15 | -------------------------------------------------------------------------------- /examples/tutorial_builder/03_02_option.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 03_02_option --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 03_02_option[EXE] [OPTIONS] 6 | 7 | Options: 8 | -n, --name 9 | -h, --help Print help 10 | -V, --version Print version 11 | 12 | $ 03_02_option 13 | name: None 14 | 15 | $ 03_02_option --name bob 16 | name: Some("bob") 17 | 18 | $ 03_02_option --name=bob 19 | name: Some("bob") 20 | 21 | $ 03_02_option -n bob 22 | name: Some("bob") 23 | 24 | $ 03_02_option -n=bob 25 | name: Some("bob") 26 | 27 | $ 03_02_option -nbob 28 | name: Some("bob") 29 | 30 | ``` 31 | -------------------------------------------------------------------------------- /examples/tutorial_builder/03_02_option.rs: -------------------------------------------------------------------------------- 1 | use clap::{command, Arg}; 2 | 3 | fn main() { 4 | let matches = command!() // requires `cargo` feature 5 | .arg(Arg::new("name").short('n').long("name")) 6 | .get_matches(); 7 | 8 | println!("name: {:?}", matches.get_one::("name")); 9 | } 10 | -------------------------------------------------------------------------------- /examples/tutorial_builder/03_02_option_mult.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 03_02_option_mult --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 03_02_option_mult[EXE] [OPTIONS] 6 | 7 | Options: 8 | -n, --name 9 | -h, --help Print help 10 | -V, --version Print version 11 | 12 | $ 03_02_option_mult 13 | names: [] 14 | 15 | $ 03_02_option_mult --name bob 16 | names: ["bob"] 17 | 18 | $ 03_02_option_mult --name bob --name john 19 | names: ["bob", "john"] 20 | 21 | $ 03_02_option_mult_derive --name bob --name=john -n tom -n=chris -nsteve 22 | name: ["bob", "john", "tom", "chris", "steve"] 23 | 24 | ``` 25 | -------------------------------------------------------------------------------- /examples/tutorial_builder/03_02_option_mult.rs: -------------------------------------------------------------------------------- 1 | use clap::{command, Arg, ArgAction}; 2 | 3 | fn main() { 4 | let matches = command!() // requires `cargo` feature 5 | .arg( 6 | Arg::new("name") 7 | .short('n') 8 | .long("name") 9 | .action(ArgAction::Append), 10 | ) 11 | .get_matches(); 12 | 13 | let args = matches 14 | .get_many::("name") 15 | .unwrap_or_default() 16 | .map(|v| v.as_str()) 17 | .collect::>(); 18 | 19 | println!("names: {:?}", &args); 20 | } 21 | -------------------------------------------------------------------------------- /examples/tutorial_builder/03_03_positional.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 03_03_positional --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 03_03_positional[EXE] [name] 6 | 7 | Arguments: 8 | [name] 9 | 10 | Options: 11 | -h, --help Print help 12 | -V, --version Print version 13 | 14 | $ 03_03_positional 15 | name: None 16 | 17 | $ 03_03_positional bob 18 | name: Some("bob") 19 | 20 | ``` 21 | -------------------------------------------------------------------------------- /examples/tutorial_builder/03_03_positional.rs: -------------------------------------------------------------------------------- 1 | use clap::{command, Arg}; 2 | 3 | fn main() { 4 | let matches = command!() // requires `cargo` feature 5 | .arg(Arg::new("name")) 6 | .get_matches(); 7 | 8 | println!("name: {:?}", matches.get_one::("name")); 9 | } 10 | -------------------------------------------------------------------------------- /examples/tutorial_builder/03_03_positional_mult.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 03_03_positional_mult --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 03_03_positional_mult[EXE] [name]... 6 | 7 | Arguments: 8 | [name]... 9 | 10 | Options: 11 | -h, --help Print help 12 | -V, --version Print version 13 | 14 | $ 03_03_positional_mult 15 | names: [] 16 | 17 | $ 03_03_positional_mult bob 18 | names: ["bob"] 19 | 20 | $ 03_03_positional_mult bob john 21 | names: ["bob", "john"] 22 | 23 | ``` 24 | -------------------------------------------------------------------------------- /examples/tutorial_builder/03_03_positional_mult.rs: -------------------------------------------------------------------------------- 1 | use clap::{command, Arg, ArgAction}; 2 | 3 | fn main() { 4 | let matches = command!() // requires `cargo` feature 5 | .arg(Arg::new("name").action(ArgAction::Append)) 6 | .get_matches(); 7 | 8 | let args = matches 9 | .get_many::("name") 10 | .unwrap_or_default() 11 | .map(|v| v.as_str()) 12 | .collect::>(); 13 | 14 | println!("names: {:?}", &args); 15 | } 16 | -------------------------------------------------------------------------------- /examples/tutorial_builder/03_04_subcommands.rs: -------------------------------------------------------------------------------- 1 | use clap::{arg, command, Command}; 2 | 3 | fn main() { 4 | let matches = command!() // requires `cargo` feature 5 | .propagate_version(true) 6 | .subcommand_required(true) 7 | .arg_required_else_help(true) 8 | .subcommand( 9 | Command::new("add") 10 | .about("Adds files to myapp") 11 | .arg(arg!([NAME])), 12 | ) 13 | .get_matches(); 14 | 15 | match matches.subcommand() { 16 | Some(("add", sub_matches)) => println!( 17 | "'myapp add' was used, name is: {:?}", 18 | sub_matches.get_one::("NAME") 19 | ), 20 | _ => unreachable!("Exhausted list of subcommands and subcommand_required prevents `None`"), 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /examples/tutorial_builder/03_05_default_values.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 03_05_default_values --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 03_05_default_values[EXE] [PORT] 6 | 7 | Arguments: 8 | [PORT] [default: 2020] 9 | 10 | Options: 11 | -h, --help Print help 12 | -V, --version Print version 13 | 14 | $ 03_05_default_values 15 | port: 2020 16 | 17 | $ 03_05_default_values 22 18 | port: 22 19 | 20 | ``` 21 | -------------------------------------------------------------------------------- /examples/tutorial_builder/03_05_default_values.rs: -------------------------------------------------------------------------------- 1 | use clap::{arg, command, value_parser}; 2 | 3 | fn main() { 4 | let matches = command!() // requires `cargo` feature 5 | .arg( 6 | arg!([PORT]) 7 | .value_parser(value_parser!(u16)) 8 | .default_value("2020"), 9 | ) 10 | .get_matches(); 11 | 12 | println!( 13 | "port: {:?}", 14 | matches 15 | .get_one::("PORT") 16 | .expect("default ensures there is always a value") 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /examples/tutorial_builder/03_06_required.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 03_06_required --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 03_06_required[EXE] 6 | 7 | Arguments: 8 | 9 | 10 | Options: 11 | -h, --help Print help 12 | -V, --version Print version 13 | 14 | $ 03_06_required 15 | ? 2 16 | error: the following required arguments were not provided: 17 | 18 | 19 | Usage: 03_06_required[EXE] 20 | 21 | For more information, try '--help'. 22 | 23 | $ 03_06_required bob 24 | name: "bob" 25 | 26 | ``` 27 | -------------------------------------------------------------------------------- /examples/tutorial_builder/03_06_required.rs: -------------------------------------------------------------------------------- 1 | use clap::{command, Arg}; 2 | 3 | fn main() { 4 | let matches = command!() // requires `cargo` feature 5 | .arg(Arg::new("name").required(true)) 6 | .get_matches(); 7 | 8 | println!( 9 | "name: {:?}", 10 | matches 11 | .get_one::("name") 12 | .expect("clap `required` ensures its present") 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /examples/tutorial_builder/04_01_enum.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 04_01_enum --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 04_01_enum[EXE] 6 | 7 | Arguments: 8 | 9 | What mode to run the program in 10 | 11 | Possible values: 12 | - fast: Run swiftly 13 | - slow: Crawl slowly but steadily 14 | 15 | Options: 16 | -h, --help 17 | Print help (see a summary with '-h') 18 | 19 | -V, --version 20 | Print version 21 | 22 | $ 04_01_enum -h 23 | A simple to use, efficient, and full-featured Command Line Argument Parser 24 | 25 | Usage: 04_01_enum[EXE] 26 | 27 | Arguments: 28 | What mode to run the program in [possible values: fast, slow] 29 | 30 | Options: 31 | -h, --help Print help (see more with '--help') 32 | -V, --version Print version 33 | 34 | $ 04_01_enum fast 35 | Hare 36 | 37 | $ 04_01_enum slow 38 | Tortoise 39 | 40 | $ 04_01_enum medium 41 | ? failed 42 | error: invalid value 'medium' for '' 43 | [possible values: fast, slow] 44 | 45 | For more information, try '--help'. 46 | 47 | ``` 48 | -------------------------------------------------------------------------------- /examples/tutorial_builder/04_01_possible.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 04_01_possible --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 04_01_possible[EXE] 6 | 7 | Arguments: 8 | What mode to run the program in [possible values: fast, slow] 9 | 10 | Options: 11 | -h, --help Print help 12 | -V, --version Print version 13 | 14 | $ 04_01_possible fast 15 | Hare 16 | 17 | $ 04_01_possible slow 18 | Tortoise 19 | 20 | $ 04_01_possible medium 21 | ? failed 22 | error: invalid value 'medium' for '' 23 | [possible values: fast, slow] 24 | 25 | For more information, try '--help'. 26 | 27 | ``` 28 | -------------------------------------------------------------------------------- /examples/tutorial_builder/04_01_possible.rs: -------------------------------------------------------------------------------- 1 | use clap::{arg, command}; 2 | 3 | fn main() { 4 | let matches = command!() // requires `cargo` feature 5 | .arg( 6 | arg!() 7 | .help("What mode to run the program in") 8 | .value_parser(["fast", "slow"]), 9 | ) 10 | .get_matches(); 11 | 12 | // Note, it's safe to call unwrap() because the arg is required 13 | match matches 14 | .get_one::("MODE") 15 | .expect("'MODE' is required and parsing will fail if its missing") 16 | .as_str() 17 | { 18 | "fast" => { 19 | println!("Hare"); 20 | } 21 | "slow" => { 22 | println!("Tortoise"); 23 | } 24 | _ => unreachable!(), 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /examples/tutorial_builder/04_02_parse.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 04_02_parse --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 04_02_parse[EXE] 6 | 7 | Arguments: 8 | Network port to use 9 | 10 | Options: 11 | -h, --help Print help 12 | -V, --version Print version 13 | 14 | $ 04_02_parse 22 15 | PORT = 22 16 | 17 | $ 04_02_parse foobar 18 | ? failed 19 | error: invalid value 'foobar' for '': invalid digit found in string 20 | 21 | For more information, try '--help'. 22 | 23 | $ 04_02_parse_derive 0 24 | ? failed 25 | error: invalid value '0' for '': 0 is not in 1..=65535 26 | 27 | For more information, try '--help'. 28 | 29 | ``` 30 | -------------------------------------------------------------------------------- /examples/tutorial_builder/04_02_parse.rs: -------------------------------------------------------------------------------- 1 | use clap::{arg, command, value_parser}; 2 | 3 | fn main() { 4 | let matches = command!() // requires `cargo` feature 5 | .arg( 6 | arg!() 7 | .help("Network port to use") 8 | .value_parser(value_parser!(u16).range(1..)), 9 | ) 10 | .get_matches(); 11 | 12 | // Note, it's safe to call unwrap() because the arg is required 13 | let port: u16 = *matches 14 | .get_one::("PORT") 15 | .expect("'PORT' is required and parsing will fail if its missing"); 16 | println!("PORT = {port}"); 17 | } 18 | -------------------------------------------------------------------------------- /examples/tutorial_builder/04_02_validate.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 04_02_validate --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 04_02_validate[EXE] 6 | 7 | Arguments: 8 | Network port to use 9 | 10 | Options: 11 | -h, --help Print help 12 | -V, --version Print version 13 | 14 | $ 04_02_validate 22 15 | PORT = 22 16 | 17 | $ 04_02_validate foobar 18 | ? failed 19 | error: invalid value 'foobar' for '': `foobar` isn't a port number 20 | 21 | For more information, try '--help'. 22 | 23 | $ 04_02_validate 0 24 | ? failed 25 | error: invalid value '0' for '': port not in range 1-65535 26 | 27 | For more information, try '--help'. 28 | 29 | ``` 30 | -------------------------------------------------------------------------------- /examples/tutorial_builder/04_02_validate.rs: -------------------------------------------------------------------------------- 1 | use std::ops::RangeInclusive; 2 | 3 | use clap::{arg, command}; 4 | 5 | fn main() { 6 | let matches = command!() // requires `cargo` feature 7 | .arg( 8 | arg!() 9 | .help("Network port to use") 10 | .value_parser(port_in_range), 11 | ) 12 | .get_matches(); 13 | 14 | // Note, it's safe to call unwrap() because the arg is required 15 | let port: u16 = *matches 16 | .get_one::("PORT") 17 | .expect("'PORT' is required and parsing will fail if its missing"); 18 | println!("PORT = {port}"); 19 | } 20 | 21 | const PORT_RANGE: RangeInclusive = 1..=65535; 22 | 23 | fn port_in_range(s: &str) -> Result { 24 | let port: usize = s 25 | .parse() 26 | .map_err(|_| format!("`{s}` isn't a port number"))?; 27 | if PORT_RANGE.contains(&port) { 28 | Ok(port as u16) 29 | } else { 30 | Err(format!( 31 | "port not in range {}-{}", 32 | PORT_RANGE.start(), 33 | PORT_RANGE.end() 34 | )) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /examples/tutorial_builder/04_04_custom.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 04_04_custom --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 04_04_custom[EXE] [OPTIONS] [INPUT_FILE] 6 | 7 | Arguments: 8 | [INPUT_FILE] some regular input 9 | 10 | Options: 11 | --set-ver set version manually 12 | --major auto inc major 13 | --minor auto inc minor 14 | --patch auto inc patch 15 | --spec-in some special input argument 16 | -c 17 | -h, --help Print help 18 | -V, --version Print version 19 | 20 | $ 04_04_custom 21 | ? failed 22 | error: Can only modify one version field 23 | 24 | Usage: 04_04_custom[EXE] [OPTIONS] [INPUT_FILE] 25 | 26 | For more information, try '--help'. 27 | 28 | $ 04_04_custom --major 29 | Version: 2.2.3 30 | 31 | $ 04_04_custom --major --minor 32 | ? failed 33 | error: Can only modify one version field 34 | 35 | Usage: 04_04_custom[EXE] [OPTIONS] [INPUT_FILE] 36 | 37 | For more information, try '--help'. 38 | 39 | $ 04_04_custom --major -c config.toml 40 | ? failed 41 | Version: 2.2.3 42 | error: INPUT_FILE or --spec-in is required when using --config 43 | 44 | Usage: 04_04_custom[EXE] [OPTIONS] [INPUT_FILE] 45 | 46 | For more information, try '--help'. 47 | 48 | $ 04_04_custom --major -c config.toml --spec-in input.txt 49 | Version: 2.2.3 50 | Doing work using input input.txt and config config.toml 51 | 52 | ``` 53 | -------------------------------------------------------------------------------- /examples/tutorial_builder/05_01_assert.rs: -------------------------------------------------------------------------------- 1 | use clap::{arg, command, value_parser}; 2 | 3 | fn main() { 4 | let matches = cmd().get_matches(); 5 | 6 | // Note, it's safe to call unwrap() because the arg is required 7 | let port: usize = *matches 8 | .get_one::("PORT") 9 | .expect("'PORT' is required and parsing will fail if its missing"); 10 | println!("PORT = {port}"); 11 | } 12 | 13 | fn cmd() -> clap::Command { 14 | command!() // requires `cargo` feature 15 | .arg( 16 | arg!() 17 | .help("Network port to use") 18 | .value_parser(value_parser!(usize)), 19 | ) 20 | } 21 | 22 | #[test] 23 | fn verify_cmd() { 24 | cmd().debug_assert(); 25 | } 26 | -------------------------------------------------------------------------------- /examples/tutorial_derive/01_quick.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 01_quick_derive --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 01_quick_derive[EXE] [OPTIONS] [NAME] [COMMAND] 6 | 7 | Commands: 8 | test does testing things 9 | help Print this message or the help of the given subcommand(s) 10 | 11 | Arguments: 12 | [NAME] Optional name to operate on 13 | 14 | Options: 15 | -c, --config Sets a custom config file 16 | -d, --debug... Turn debugging information on 17 | -h, --help Print help 18 | -V, --version Print version 19 | 20 | ``` 21 | 22 | By default, the program does nothing: 23 | ```console 24 | $ 01_quick_derive 25 | Debug mode is off 26 | 27 | ``` 28 | 29 | But you can mix and match the various features 30 | ```console 31 | $ 01_quick_derive -dd test 32 | Debug mode is on 33 | Not printing testing lists... 34 | 35 | ``` 36 | -------------------------------------------------------------------------------- /examples/tutorial_derive/02_app_settings.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 02_app_settings_derive --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 02_app_settings_derive[EXE] --two --one 6 | 7 | Options: 8 | --two 9 | 10 | --one 11 | 12 | -h, --help 13 | Print help 14 | -V, --version 15 | Print version 16 | 17 | ``` 18 | -------------------------------------------------------------------------------- /examples/tutorial_derive/02_app_settings.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser)] 4 | #[command(version, about, long_about = None)] 5 | #[command(next_line_help = true)] 6 | struct Cli { 7 | #[arg(long)] 8 | two: String, 9 | #[arg(long)] 10 | one: String, 11 | } 12 | 13 | fn main() { 14 | let cli = Cli::parse(); 15 | 16 | println!("two: {:?}", cli.two); 17 | println!("one: {:?}", cli.one); 18 | } 19 | -------------------------------------------------------------------------------- /examples/tutorial_derive/02_apps.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 02_apps_derive --help 3 | Does awesome things 4 | 5 | Usage: 02_apps_derive[EXE] --two --one 6 | 7 | Options: 8 | --two 9 | --one 10 | -h, --help Print help 11 | -V, --version Print version 12 | 13 | $ 02_apps_derive --version 14 | MyApp 1.0 15 | 16 | ``` 17 | -------------------------------------------------------------------------------- /examples/tutorial_derive/02_apps.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser)] 4 | #[command(name = "MyApp")] 5 | #[command(version = "1.0")] 6 | #[command(about = "Does awesome things", long_about = None)] 7 | struct Cli { 8 | #[arg(long)] 9 | two: String, 10 | #[arg(long)] 11 | one: String, 12 | } 13 | 14 | fn main() { 15 | let cli = Cli::parse(); 16 | 17 | println!("two: {:?}", cli.two); 18 | println!("one: {:?}", cli.one); 19 | } 20 | -------------------------------------------------------------------------------- /examples/tutorial_derive/02_crate.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 02_crate_derive --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 02_crate_derive[EXE] --two --one 6 | 7 | Options: 8 | --two 9 | --one 10 | -h, --help Print help 11 | -V, --version Print version 12 | 13 | $ 02_crate_derive --version 14 | clap [..] 15 | 16 | ``` 17 | -------------------------------------------------------------------------------- /examples/tutorial_derive/02_crate.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser)] 4 | #[command(version, about, long_about = None)] // Read from `Cargo.toml` 5 | struct Cli { 6 | #[arg(long)] 7 | two: String, 8 | #[arg(long)] 9 | one: String, 10 | } 11 | 12 | fn main() { 13 | let cli = Cli::parse(); 14 | 15 | println!("two: {:?}", cli.two); 16 | println!("one: {:?}", cli.one); 17 | } 18 | -------------------------------------------------------------------------------- /examples/tutorial_derive/03_01_flag_bool.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 03_01_flag_bool_derive --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 03_01_flag_bool_derive[EXE] [OPTIONS] 6 | 7 | Options: 8 | -v, --verbose 9 | -h, --help Print help 10 | -V, --version Print version 11 | 12 | $ 03_01_flag_bool_derive 13 | verbose: false 14 | 15 | $ 03_01_flag_bool_derive --verbose 16 | verbose: true 17 | 18 | $ 03_01_flag_bool_derive --verbose --verbose 19 | ? failed 20 | error: the argument '--verbose' cannot be used multiple times 21 | 22 | Usage: 03_01_flag_bool_derive[EXE] [OPTIONS] 23 | 24 | For more information, try '--help'. 25 | 26 | ``` 27 | -------------------------------------------------------------------------------- /examples/tutorial_derive/03_01_flag_bool.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser)] 4 | #[command(version, about, long_about = None)] 5 | struct Cli { 6 | #[arg(short, long)] 7 | verbose: bool, 8 | } 9 | 10 | fn main() { 11 | let cli = Cli::parse(); 12 | 13 | println!("verbose: {:?}", cli.verbose); 14 | } 15 | -------------------------------------------------------------------------------- /examples/tutorial_derive/03_01_flag_count.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 03_01_flag_count_derive --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 03_01_flag_count_derive[EXE] [OPTIONS] 6 | 7 | Options: 8 | -v, --verbose... 9 | -h, --help Print help 10 | -V, --version Print version 11 | 12 | $ 03_01_flag_count_derive 13 | verbose: 0 14 | 15 | $ 03_01_flag_count_derive --verbose 16 | verbose: 1 17 | 18 | $ 03_01_flag_count_derive --verbose --verbose 19 | verbose: 2 20 | 21 | ``` 22 | -------------------------------------------------------------------------------- /examples/tutorial_derive/03_01_flag_count.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser)] 4 | #[command(version, about, long_about = None)] 5 | struct Cli { 6 | #[arg(short, long, action = clap::ArgAction::Count)] 7 | verbose: u8, 8 | } 9 | 10 | fn main() { 11 | let cli = Cli::parse(); 12 | 13 | println!("verbose: {:?}", cli.verbose); 14 | } 15 | -------------------------------------------------------------------------------- /examples/tutorial_derive/03_02_option.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 03_02_option_derive --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 03_02_option_derive[EXE] --name 6 | 7 | Options: 8 | -n, --name 9 | -h, --help Print help 10 | -V, --version Print version 11 | 12 | $ 03_02_option_derive 13 | ? 2 14 | error: the following required arguments were not provided: 15 | --name 16 | 17 | Usage: 03_02_option_derive[EXE] --name 18 | 19 | For more information, try '--help'. 20 | 21 | $ 03_02_option_derive --name bob 22 | name: "bob" 23 | 24 | $ 03_02_option_derive --name=bob 25 | name: "bob" 26 | 27 | $ 03_02_option_derive -n bob 28 | name: "bob" 29 | 30 | $ 03_02_option_derive -n=bob 31 | name: "bob" 32 | 33 | $ 03_02_option_derive -nbob 34 | name: "bob" 35 | 36 | ``` 37 | -------------------------------------------------------------------------------- /examples/tutorial_derive/03_02_option.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser)] 4 | #[command(version, about, long_about = None)] 5 | struct Cli { 6 | #[arg(short, long)] 7 | name: String, 8 | } 9 | 10 | fn main() { 11 | let cli = Cli::parse(); 12 | 13 | println!("name: {:?}", cli.name); 14 | } 15 | -------------------------------------------------------------------------------- /examples/tutorial_derive/03_02_option_mult.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 03_02_option_mult_derive --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 03_02_option_mult_derive[EXE] [OPTIONS] 6 | 7 | Options: 8 | -n, --name 9 | -h, --help Print help 10 | -V, --version Print version 11 | 12 | $ 03_02_option_mult_derive 13 | name: [] 14 | 15 | $ 03_02_option_mult_derive --name bob 16 | name: ["bob"] 17 | 18 | $ 03_02_option_mult_derive --name bob --name john 19 | name: ["bob", "john"] 20 | 21 | $ 03_02_option_mult_derive --name bob --name=john -n tom -n=chris -nsteve 22 | name: ["bob", "john", "tom", "chris", "steve"] 23 | 24 | ``` 25 | -------------------------------------------------------------------------------- /examples/tutorial_derive/03_02_option_mult.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser)] 4 | #[command(version, about, long_about = None)] 5 | struct Cli { 6 | #[arg(short, long)] 7 | name: Vec, 8 | } 9 | 10 | fn main() { 11 | let cli = Cli::parse(); 12 | 13 | println!("name: {:?}", cli.name); 14 | } 15 | -------------------------------------------------------------------------------- /examples/tutorial_derive/03_03_positional.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 03_03_positional_derive --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 03_03_positional_derive[EXE] 6 | 7 | Arguments: 8 | 9 | 10 | Options: 11 | -h, --help Print help 12 | -V, --version Print version 13 | 14 | $ 03_03_positional_derive 15 | ? 2 16 | error: the following required arguments were not provided: 17 | 18 | 19 | Usage: 03_03_positional_derive[EXE] 20 | 21 | For more information, try '--help'. 22 | 23 | $ 03_03_positional_derive bob 24 | name: "bob" 25 | 26 | ``` 27 | -------------------------------------------------------------------------------- /examples/tutorial_derive/03_03_positional.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser)] 4 | #[command(version, about, long_about = None)] 5 | struct Cli { 6 | name: String, 7 | } 8 | 9 | fn main() { 10 | let cli = Cli::parse(); 11 | 12 | println!("name: {:?}", cli.name); 13 | } 14 | -------------------------------------------------------------------------------- /examples/tutorial_derive/03_03_positional_mult.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 03_03_positional_mult_derive --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 03_03_positional_mult_derive[EXE] [NAME]... 6 | 7 | Arguments: 8 | [NAME]... 9 | 10 | Options: 11 | -h, --help Print help 12 | -V, --version Print version 13 | 14 | $ 03_03_positional_mult_derive 15 | name: [] 16 | 17 | $ 03_03_positional_mult_derive bob 18 | name: ["bob"] 19 | 20 | $ 03_03_positional_mult_derive bob john 21 | name: ["bob", "john"] 22 | 23 | ``` 24 | -------------------------------------------------------------------------------- /examples/tutorial_derive/03_03_positional_mult.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser)] 4 | #[command(version, about, long_about = None)] 5 | struct Cli { 6 | name: Vec, 7 | } 8 | 9 | fn main() { 10 | let cli = Cli::parse(); 11 | 12 | println!("name: {:?}", cli.name); 13 | } 14 | -------------------------------------------------------------------------------- /examples/tutorial_derive/03_04_subcommands.rs: -------------------------------------------------------------------------------- 1 | use clap::{Parser, Subcommand}; 2 | 3 | #[derive(Parser)] 4 | #[command(version, about, long_about = None)] 5 | #[command(propagate_version = true)] 6 | struct Cli { 7 | #[command(subcommand)] 8 | command: Commands, 9 | } 10 | 11 | #[derive(Subcommand)] 12 | enum Commands { 13 | /// Adds files to myapp 14 | Add { name: Option }, 15 | } 16 | 17 | fn main() { 18 | let cli = Cli::parse(); 19 | 20 | // You can check for the existence of subcommands, and if found use their 21 | // matches just as you would the top level cmd 22 | match &cli.command { 23 | Commands::Add { name } => { 24 | println!("'myapp add' was used, name is: {name:?}"); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /examples/tutorial_derive/03_04_subcommands_alt.rs: -------------------------------------------------------------------------------- 1 | use clap::{Args, Parser, Subcommand}; 2 | 3 | #[derive(Parser)] 4 | #[command(version, about, long_about = None)] 5 | #[command(propagate_version = true)] 6 | struct Cli { 7 | #[command(subcommand)] 8 | command: Commands, 9 | } 10 | 11 | #[derive(Subcommand)] 12 | enum Commands { 13 | /// Adds files to myapp 14 | Add(AddArgs), 15 | } 16 | 17 | #[derive(Args)] 18 | struct AddArgs { 19 | name: Option, 20 | } 21 | 22 | fn main() { 23 | let cli = Cli::parse(); 24 | 25 | // You can check for the existence of subcommands, and if found use their 26 | // matches just as you would the top level cmd 27 | match &cli.command { 28 | Commands::Add(name) => { 29 | println!("'myapp add' was used, name is: {:?}", name.name); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples/tutorial_derive/03_05_default_values.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 03_05_default_values_derive --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 03_05_default_values_derive[EXE] [PORT] 6 | 7 | Arguments: 8 | [PORT] [default: 2020] 9 | 10 | Options: 11 | -h, --help Print help 12 | -V, --version Print version 13 | 14 | $ 03_05_default_values_derive 15 | port: 2020 16 | 17 | $ 03_05_default_values_derive 22 18 | port: 22 19 | 20 | ``` 21 | -------------------------------------------------------------------------------- /examples/tutorial_derive/03_05_default_values.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser)] 4 | #[command(version, about, long_about = None)] 5 | struct Cli { 6 | #[arg(default_value_t = 2020)] 7 | port: u16, 8 | } 9 | 10 | fn main() { 11 | let cli = Cli::parse(); 12 | 13 | println!("port: {:?}", cli.port); 14 | } 15 | -------------------------------------------------------------------------------- /examples/tutorial_derive/03_06_optional.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 03_06_optional_derive --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 03_06_optional_derive[EXE] [NAME] 6 | 7 | Arguments: 8 | [NAME] 9 | 10 | Options: 11 | -h, --help Print help 12 | -V, --version Print version 13 | 14 | $ 03_06_optional_derive 15 | name: None 16 | 17 | $ 03_06_optional_derive bob 18 | name: Some("bob") 19 | 20 | ``` 21 | -------------------------------------------------------------------------------- /examples/tutorial_derive/03_06_optional.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser)] 4 | #[command(version, about, long_about = None)] 5 | struct Cli { 6 | name: Option, 7 | } 8 | 9 | fn main() { 10 | let cli = Cli::parse(); 11 | 12 | println!("name: {:?}", cli.name); 13 | } 14 | -------------------------------------------------------------------------------- /examples/tutorial_derive/04_01_enum.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 04_01_enum_derive --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 04_01_enum_derive[EXE] 6 | 7 | Arguments: 8 | 9 | What mode to run the program in 10 | 11 | Possible values: 12 | - fast: Run swiftly 13 | - slow: Crawl slowly but steadily 14 | 15 | Options: 16 | -h, --help 17 | Print help (see a summary with '-h') 18 | 19 | -V, --version 20 | Print version 21 | 22 | $ 04_01_enum_derive -h 23 | A simple to use, efficient, and full-featured Command Line Argument Parser 24 | 25 | Usage: 04_01_enum_derive[EXE] 26 | 27 | Arguments: 28 | What mode to run the program in [possible values: fast, slow] 29 | 30 | Options: 31 | -h, --help Print help (see more with '--help') 32 | -V, --version Print version 33 | 34 | $ 04_01_enum_derive fast 35 | Hare 36 | 37 | $ 04_01_enum_derive slow 38 | Tortoise 39 | 40 | $ 04_01_enum_derive medium 41 | ? failed 42 | error: invalid value 'medium' for '' 43 | [possible values: fast, slow] 44 | 45 | For more information, try '--help'. 46 | 47 | ``` 48 | -------------------------------------------------------------------------------- /examples/tutorial_derive/04_01_enum.rs: -------------------------------------------------------------------------------- 1 | use clap::{Parser, ValueEnum}; 2 | 3 | #[derive(Parser)] 4 | #[command(version, about, long_about = None)] 5 | struct Cli { 6 | /// What mode to run the program in 7 | #[arg(value_enum)] 8 | mode: Mode, 9 | } 10 | 11 | #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] 12 | enum Mode { 13 | /// Run swiftly 14 | Fast, 15 | /// Crawl slowly but steadily 16 | /// 17 | /// This paragraph is ignored because there is no long help text for possible values. 18 | Slow, 19 | } 20 | 21 | fn main() { 22 | let cli = Cli::parse(); 23 | 24 | match cli.mode { 25 | Mode::Fast => { 26 | println!("Hare"); 27 | } 28 | Mode::Slow => { 29 | println!("Tortoise"); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples/tutorial_derive/04_02_parse.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 04_02_parse_derive --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 04_02_parse_derive[EXE] 6 | 7 | Arguments: 8 | Network port to use 9 | 10 | Options: 11 | -h, --help Print help 12 | -V, --version Print version 13 | 14 | $ 04_02_parse_derive 22 15 | PORT = 22 16 | 17 | $ 04_02_parse_derive foobar 18 | ? failed 19 | error: invalid value 'foobar' for '': invalid digit found in string 20 | 21 | For more information, try '--help'. 22 | 23 | $ 04_02_parse_derive 0 24 | ? failed 25 | error: invalid value '0' for '': 0 is not in 1..=65535 26 | 27 | For more information, try '--help'. 28 | 29 | ``` 30 | -------------------------------------------------------------------------------- /examples/tutorial_derive/04_02_parse.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser)] 4 | #[command(version, about, long_about = None)] 5 | struct Cli { 6 | /// Network port to use 7 | #[arg(value_parser = clap::value_parser!(u16).range(1..))] 8 | port: u16, 9 | } 10 | 11 | fn main() { 12 | let cli = Cli::parse(); 13 | 14 | println!("PORT = {}", cli.port); 15 | } 16 | -------------------------------------------------------------------------------- /examples/tutorial_derive/04_02_validate.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 04_02_validate_derive --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 04_02_validate_derive[EXE] 6 | 7 | Arguments: 8 | Network port to use 9 | 10 | Options: 11 | -h, --help Print help 12 | -V, --version Print version 13 | 14 | $ 04_02_validate_derive 22 15 | PORT = 22 16 | 17 | $ 04_02_validate_derive foobar 18 | ? failed 19 | error: invalid value 'foobar' for '': `foobar` isn't a port number 20 | 21 | For more information, try '--help'. 22 | 23 | $ 04_02_validate_derive 0 24 | ? failed 25 | error: invalid value '0' for '': port not in range 1-65535 26 | 27 | For more information, try '--help'. 28 | 29 | ``` 30 | -------------------------------------------------------------------------------- /examples/tutorial_derive/04_02_validate.rs: -------------------------------------------------------------------------------- 1 | use std::ops::RangeInclusive; 2 | 3 | use clap::Parser; 4 | 5 | #[derive(Parser)] 6 | #[command(version, about, long_about = None)] 7 | struct Cli { 8 | /// Network port to use 9 | #[arg(value_parser = port_in_range)] 10 | port: u16, 11 | } 12 | 13 | fn main() { 14 | let cli = Cli::parse(); 15 | 16 | println!("PORT = {}", cli.port); 17 | } 18 | 19 | const PORT_RANGE: RangeInclusive = 1..=65535; 20 | 21 | fn port_in_range(s: &str) -> Result { 22 | let port: usize = s 23 | .parse() 24 | .map_err(|_| format!("`{s}` isn't a port number"))?; 25 | if PORT_RANGE.contains(&port) { 26 | Ok(port as u16) 27 | } else { 28 | Err(format!( 29 | "port not in range {}-{}", 30 | PORT_RANGE.start(), 31 | PORT_RANGE.end() 32 | )) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /examples/tutorial_derive/04_04_custom.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ 04_04_custom_derive --help 3 | A simple to use, efficient, and full-featured Command Line Argument Parser 4 | 5 | Usage: 04_04_custom_derive[EXE] [OPTIONS] [INPUT_FILE] 6 | 7 | Arguments: 8 | [INPUT_FILE] some regular input 9 | 10 | Options: 11 | --set-ver set version manually 12 | --major auto inc major 13 | --minor auto inc minor 14 | --patch auto inc patch 15 | --spec-in some special input argument 16 | -c 17 | -h, --help Print help 18 | -V, --version Print version 19 | 20 | $ 04_04_custom_derive 21 | ? failed 22 | error: Can only modify one version field 23 | 24 | Usage: clap [OPTIONS] [INPUT_FILE] 25 | 26 | For more information, try '--help'. 27 | 28 | $ 04_04_custom_derive --major 29 | Version: 2.2.3 30 | 31 | $ 04_04_custom_derive --major --minor 32 | ? failed 33 | error: Can only modify one version field 34 | 35 | Usage: clap [OPTIONS] [INPUT_FILE] 36 | 37 | For more information, try '--help'. 38 | 39 | $ 04_04_custom_derive --major -c config.toml 40 | ? failed 41 | Version: 2.2.3 42 | error: INPUT_FILE or --spec-in is required when using --config 43 | 44 | Usage: clap [OPTIONS] [INPUT_FILE] 45 | 46 | For more information, try '--help'. 47 | 48 | $ 04_04_custom_derive --major -c config.toml --spec-in input.txt 49 | Version: 2.2.3 50 | Doing work using input input.txt and config config.toml 51 | 52 | ``` 53 | -------------------------------------------------------------------------------- /examples/tutorial_derive/05_01_assert.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser)] 4 | #[command(version, about, long_about = None)] 5 | struct Cli { 6 | /// Network port to use 7 | port: u16, 8 | } 9 | 10 | fn main() { 11 | let cli = Cli::parse(); 12 | 13 | println!("PORT = {}", cli.port); 14 | } 15 | 16 | #[test] 17 | fn verify_cli() { 18 | use clap::CommandFactory; 19 | Cli::command().debug_assert(); 20 | } 21 | -------------------------------------------------------------------------------- /release.toml: -------------------------------------------------------------------------------- 1 | owners = ["github:clap-rs:Admins", "github:rust-cli:Maintainers"] 2 | dependent-version = "fix" 3 | allow-branch = ["master", "v*-master"] 4 | -------------------------------------------------------------------------------- /src/_cookbook/cargo_example.rs: -------------------------------------------------------------------------------- 1 | //! # Example: cargo subcommand (Builder API) 2 | //! 3 | //! ```rust 4 | #![doc = include_str!("../../examples/cargo-example.rs")] 5 | //! ``` 6 | //! 7 | #![doc = include_str!("../../examples/cargo-example.md")] 8 | -------------------------------------------------------------------------------- /src/_cookbook/cargo_example_derive.rs: -------------------------------------------------------------------------------- 1 | //! # Example: cargo subcommand (Derive API) 2 | //! 3 | //! ```rust 4 | #![doc = include_str!("../../examples/cargo-example-derive.rs")] 5 | //! ``` 6 | //! 7 | #![doc = include_str!("../../examples/cargo-example-derive.md")] 8 | -------------------------------------------------------------------------------- /src/_cookbook/escaped_positional.rs: -------------------------------------------------------------------------------- 1 | //! # Example (Builder API) 2 | //! 3 | //! ```rust 4 | #![doc = include_str!("../../examples/escaped-positional.rs")] 5 | //! ``` 6 | //! 7 | #![doc = include_str!("../../examples/escaped-positional.md")] 8 | -------------------------------------------------------------------------------- /src/_cookbook/escaped_positional_derive.rs: -------------------------------------------------------------------------------- 1 | //! # Example (Derive API) 2 | //! 3 | //! ```rust 4 | #![doc = include_str!("../../examples/escaped-positional-derive.rs")] 5 | //! ``` 6 | //! 7 | #![doc = include_str!("../../examples/escaped-positional-derive.md")] 8 | -------------------------------------------------------------------------------- /src/_cookbook/find.rs: -------------------------------------------------------------------------------- 1 | //! # Example: find-like CLI (Builder API) 2 | //! 3 | //! ```rust 4 | #![doc = include_str!("../../examples/find.rs")] 5 | //! ``` 6 | //! 7 | #![doc = include_str!("../../examples/find.md")] 8 | -------------------------------------------------------------------------------- /src/_cookbook/git.rs: -------------------------------------------------------------------------------- 1 | //! # Example: git-like CLI (Builder API) 2 | //! 3 | //! ```rust 4 | #![doc = include_str!("../../examples/git.rs")] 5 | //! ``` 6 | //! 7 | #![doc = include_str!("../../examples/git.md")] 8 | -------------------------------------------------------------------------------- /src/_cookbook/git_derive.rs: -------------------------------------------------------------------------------- 1 | //! # Example: git-like CLI (Derive API) 2 | //! 3 | //! ```rust 4 | #![doc = include_str!("../../examples/git-derive.rs")] 5 | //! ``` 6 | //! 7 | #![doc = include_str!("../../examples/git-derive.md")] 8 | -------------------------------------------------------------------------------- /src/_cookbook/multicall_busybox.rs: -------------------------------------------------------------------------------- 1 | //! # Example: busybox-like CLI (Builder API) 2 | //! 3 | //! ```rust 4 | #![doc = include_str!("../../examples/multicall-busybox.rs")] 5 | //! ``` 6 | //! 7 | #![doc = include_str!("../../examples/multicall-busybox.md")] 8 | -------------------------------------------------------------------------------- /src/_cookbook/multicall_hostname.rs: -------------------------------------------------------------------------------- 1 | //! # Example: hostname-like CLI (Builder API) 2 | //! 3 | //! ```rust 4 | #![doc = include_str!("../../examples/multicall-hostname.rs")] 5 | //! ``` 6 | //! 7 | #![doc = include_str!("../../examples/multicall-hostname.md")] 8 | -------------------------------------------------------------------------------- /src/_cookbook/pacman.rs: -------------------------------------------------------------------------------- 1 | //! # Example: pacman-like CLI (Builder API) 2 | //! 3 | //! ```rust 4 | #![doc = include_str!("../../examples/pacman.rs")] 5 | //! ``` 6 | //! 7 | #![doc = include_str!("../../examples/pacman.md")] 8 | -------------------------------------------------------------------------------- /src/_cookbook/repl.rs: -------------------------------------------------------------------------------- 1 | //! # Example: Command REPL (Builder API) 2 | //! 3 | //! ```rust 4 | #![doc = include_str!("../../examples/repl.rs")] 5 | //! ``` 6 | -------------------------------------------------------------------------------- /src/_cookbook/repl_derive.rs: -------------------------------------------------------------------------------- 1 | //! # Example: REPL (Derive API) 2 | //! 3 | //! ```rust 4 | #![doc = include_str!("../../examples/repl-derive.rs")] 5 | -------------------------------------------------------------------------------- /src/_cookbook/typed_derive.rs: -------------------------------------------------------------------------------- 1 | //! # Example: Custom Types (Derive API) 2 | //! 3 | //! ```rust 4 | #![doc = include_str!("../../examples/typed-derive.rs")] 5 | //! ``` 6 | //! 7 | #![doc = include_str!("../../examples/typed-derive.md")] 8 | -------------------------------------------------------------------------------- /src/bin/stdio-fixture.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | #[allow(unused_mut)] 3 | let mut cmd = clap::Command::new("stdio-fixture") 4 | .version("1.0") 5 | .long_version("1.0 - a2132c") 6 | .arg_required_else_help(true) 7 | .subcommand(clap::Command::new("more")) 8 | .arg( 9 | clap::Arg::new("verbose") 10 | .long("verbose") 11 | .help("log") 12 | .action(clap::ArgAction::SetTrue) 13 | .long_help("more log"), 14 | ); 15 | #[cfg(feature = "color")] 16 | { 17 | use clap::builder::styling; 18 | const STYLES: styling::Styles = styling::Styles::styled() 19 | .header(styling::AnsiColor::Green.on_default().bold()) 20 | .usage(styling::AnsiColor::Green.on_default().bold()) 21 | .literal(styling::AnsiColor::Blue.on_default().bold()) 22 | .placeholder(styling::AnsiColor::Cyan.on_default()); 23 | cmd = cmd.styles(STYLES); 24 | } 25 | cmd.get_matches(); 26 | } 27 | -------------------------------------------------------------------------------- /tests/builder/borrowed.rs: -------------------------------------------------------------------------------- 1 | use clap::{Arg, Command}; 2 | 3 | #[test] 4 | fn borrowed_args() { 5 | let arg = Arg::new("some").short('s').long("some").help("other help"); 6 | let arg2 = Arg::new("some2") 7 | .short('S') 8 | .long("some-thing") 9 | .help("other help"); 10 | let result = Command::new("sub_command_negate") 11 | .arg(Arg::new("test").index(1)) 12 | .arg(&arg) 13 | .arg(&arg2) 14 | .subcommand(Command::new("sub1").arg(&arg)) 15 | .try_get_matches_from(vec!["prog"]); 16 | assert!(result.is_ok(), "{}", result.unwrap_err()); 17 | } 18 | -------------------------------------------------------------------------------- /tests/builder/command.rs: -------------------------------------------------------------------------------- 1 | #![cfg(feature = "cargo")] 2 | 3 | use clap::{command, error::ErrorKind}; 4 | 5 | use crate::utils; 6 | 7 | static EVERYTHING: &str = "clap {{version}} 8 | A simple to use, efficient, and full-featured Command Line Argument Parser 9 | 10 | Usage: clap 11 | 12 | Options: 13 | -h, --help Print help 14 | -V, --version Print version 15 | "; 16 | 17 | #[test] 18 | fn command() { 19 | let res = command!() 20 | .help_template(utils::FULL_TEMPLATE) 21 | .try_get_matches_from(vec!["clap", "--help"]); 22 | 23 | assert!(res.is_err()); 24 | let err = res.unwrap_err(); 25 | assert_eq!(err.kind(), ErrorKind::DisplayHelp); 26 | assert_eq!( 27 | err.to_string(), 28 | EVERYTHING.replace("{{version}}", env!("CARGO_PKG_VERSION")) 29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /tests/builder/display_order.rs: -------------------------------------------------------------------------------- 1 | use super::utils; 2 | 3 | use clap::Command; 4 | 5 | #[test] 6 | fn very_large_display_order() { 7 | let cmd = Command::new("test").subcommand(Command::new("sub").display_order(usize::MAX)); 8 | 9 | utils::assert_output( 10 | cmd, 11 | "test --help", 12 | "\ 13 | Usage: test [COMMAND] 14 | 15 | Commands: 16 | help Print this message or the help of the given subcommand(s) 17 | sub 18 | 19 | Options: 20 | -h, --help Print help 21 | ", 22 | false, 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /tests/builder/main.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::self_named_module_files)] // false positive 2 | #![cfg(feature = "help")] 3 | #![cfg(feature = "usage")] 4 | 5 | automod::dir!("tests/builder"); 6 | -------------------------------------------------------------------------------- /tests/builder/unicode.rs: -------------------------------------------------------------------------------- 1 | #![cfg(feature = "unicode")] 2 | 3 | #[test] 4 | fn possible_values_ignore_case() { 5 | let m = clap::Command::new("pv") 6 | .arg( 7 | clap::Arg::new("option") 8 | .short('o') 9 | .long("option") 10 | .action(clap::ArgAction::Set) 11 | .value_parser(["ä"]) 12 | .ignore_case(true), 13 | ) 14 | .try_get_matches_from(vec!["pv", "--option", "Ä"]); 15 | 16 | assert!(m.is_ok(), "{}", m.unwrap_err()); 17 | assert!(m 18 | .unwrap() 19 | .get_one::("option") 20 | .map(|v| v.as_str()) 21 | .is_some()); 22 | } 23 | -------------------------------------------------------------------------------- /tests/builder/unique_args.rs: -------------------------------------------------------------------------------- 1 | #[cfg(debug_assertions)] 2 | #[test] 3 | #[should_panic = "Argument names must be unique, but 'arg1' is in use by more than one argument or group"] 4 | fn unique_arg_names() { 5 | use clap::{Arg, Command}; 6 | 7 | let _ = Command::new("some") 8 | .args([Arg::new("arg1").short('a'), Arg::new("arg1").short('b')]) 9 | .try_get_matches(); 10 | } 11 | 12 | #[cfg(debug_assertions)] 13 | #[test] 14 | #[should_panic = "Short option names must be unique for each argument, but '-a' is in use by both 'arg1' and 'arg2'"] 15 | fn unique_arg_shorts() { 16 | use clap::{Arg, Command}; 17 | 18 | let _ = Command::new("some") 19 | .args([Arg::new("arg1").short('a'), Arg::new("arg2").short('a')]) 20 | .try_get_matches(); 21 | } 22 | 23 | #[cfg(debug_assertions)] 24 | #[test] 25 | #[should_panic = "Long option names must be unique for each argument, but '--long' is in use by both 'arg1' and 'arg2'"] 26 | fn unique_arg_longs() { 27 | use clap::{Arg, Command}; 28 | 29 | let _ = Command::new("some") 30 | .args([Arg::new("arg1").long("long"), Arg::new("arg2").long("long")]) 31 | .try_get_matches(); 32 | } 33 | -------------------------------------------------------------------------------- /tests/derive/boxed.rs: -------------------------------------------------------------------------------- 1 | use clap::{Args, Parser, Subcommand}; 2 | 3 | #[derive(Parser, PartialEq, Debug)] 4 | struct Opt { 5 | #[command(subcommand)] 6 | sub: Box, 7 | } 8 | 9 | #[derive(Subcommand, PartialEq, Debug)] 10 | enum Sub { 11 | Flame { 12 | #[command(flatten)] 13 | arg: Box, 14 | }, 15 | } 16 | 17 | #[derive(Args, PartialEq, Debug)] 18 | struct Ext { 19 | arg: u32, 20 | } 21 | 22 | #[test] 23 | fn boxed_flatten_subcommand() { 24 | assert_eq!( 25 | Opt { 26 | sub: Box::new(Sub::Flame { 27 | arg: Box::new(Ext { arg: 1 }) 28 | }) 29 | }, 30 | Opt::try_parse_from(["test", "flame", "1"]).unwrap() 31 | ); 32 | } 33 | 34 | #[test] 35 | fn update_boxed_flatten_subcommand() { 36 | let mut opt = Opt::try_parse_from(["test", "flame", "1"]).unwrap(); 37 | 38 | opt.try_update_from(["test", "flame", "42"]).unwrap(); 39 | 40 | assert_eq!( 41 | Opt { 42 | sub: Box::new(Sub::Flame { 43 | arg: Box::new(Ext { arg: 42 }) 44 | }) 45 | }, 46 | opt 47 | ); 48 | } 49 | -------------------------------------------------------------------------------- /tests/derive/explicit_name_no_renaming.rs: -------------------------------------------------------------------------------- 1 | use crate::utils; 2 | 3 | use clap::Parser; 4 | 5 | #[test] 6 | fn explicit_short_long_no_rename() { 7 | #[derive(Parser, PartialEq, Debug)] 8 | struct Opt { 9 | #[arg(short = '.', long = ".foo")] 10 | foo: String, 11 | } 12 | 13 | assert_eq!( 14 | Opt { foo: "long".into() }, 15 | Opt::try_parse_from(["test", "--.foo", "long"]).unwrap() 16 | ); 17 | 18 | assert_eq!( 19 | Opt { 20 | foo: "short".into(), 21 | }, 22 | Opt::try_parse_from(["test", "-.", "short"]).unwrap() 23 | ); 24 | } 25 | 26 | #[test] 27 | fn explicit_name_no_rename() { 28 | #[derive(Parser, PartialEq, Debug)] 29 | struct Opt { 30 | #[arg(id = ".options")] 31 | foo: String, 32 | } 33 | 34 | let help = utils::get_long_help::(); 35 | assert!(help.contains("<.options>")); 36 | } 37 | -------------------------------------------------------------------------------- /tests/derive/main.rs: -------------------------------------------------------------------------------- 1 | #![cfg(feature = "derive")] 2 | #![cfg(feature = "help")] 3 | #![cfg(feature = "usage")] 4 | 5 | automod::dir!("tests/derive"); 6 | -------------------------------------------------------------------------------- /tests/derive/privacy.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Guillaume Pinot (@TeXitoi) , 2 | // Kevin Knapp (@kbknapp) , and 3 | // Ana Hobden (@hoverbear) 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | // 11 | // This work was derived from Structopt (https://github.com/TeXitoi/structopt) 12 | // commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the 13 | // MIT/Apache 2.0 license. 14 | 15 | mod options { 16 | use clap::Parser; 17 | 18 | #[derive(Debug, Parser)] 19 | pub(crate) struct Options { 20 | #[command(subcommand)] 21 | pub(crate) subcommand: super::subcommands::SubCommand, 22 | } 23 | } 24 | 25 | mod subcommands { 26 | use clap::Subcommand; 27 | 28 | #[derive(Debug, Subcommand)] 29 | pub(crate) enum SubCommand { 30 | /// foo 31 | Foo { 32 | /// foo 33 | bars: String, 34 | }, 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/derive/raw_bool_literal.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Guillaume Pinot (@TeXitoi) 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | use clap::Parser; 10 | 11 | #[test] 12 | fn raw_bool_literal() { 13 | #[derive(Parser, Debug, PartialEq)] 14 | #[command(name = "raw_bool")] 15 | struct Opt { 16 | #[arg(raw(false))] 17 | a: String, 18 | #[arg(raw(true))] 19 | b: String, 20 | } 21 | 22 | assert_eq!( 23 | Opt { 24 | a: "one".into(), 25 | b: "--help".into() 26 | }, 27 | Opt::try_parse_from(["test", "one", "--", "--help"]).unwrap() 28 | ); 29 | } 30 | -------------------------------------------------------------------------------- /tests/derive/raw_idents.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[test] 4 | fn raw_idents() { 5 | #[derive(Parser, Debug, PartialEq)] 6 | struct Opt { 7 | #[arg(short, long)] 8 | r#type: String, 9 | } 10 | 11 | assert_eq!( 12 | Opt { 13 | r#type: "long".into() 14 | }, 15 | Opt::try_parse_from(["test", "--type", "long"]).unwrap() 16 | ); 17 | 18 | assert_eq!( 19 | Opt { 20 | r#type: "short".into() 21 | }, 22 | Opt::try_parse_from(["test", "-t", "short"]).unwrap() 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /tests/derive/rename_all_env.rs: -------------------------------------------------------------------------------- 1 | #![cfg(feature = "env")] 2 | 3 | use crate::utils; 4 | 5 | use clap::Parser; 6 | 7 | #[test] 8 | fn it_works() { 9 | #[derive(Debug, PartialEq, Parser)] 10 | #[command(rename_all_env = "kebab")] 11 | struct BehaviorModel { 12 | #[arg(env)] 13 | be_nice: String, 14 | } 15 | 16 | let help = utils::get_help::(); 17 | assert!(help.contains("[env: be-nice=]")); 18 | } 19 | 20 | #[test] 21 | fn default_is_screaming() { 22 | #[derive(Debug, PartialEq, Parser)] 23 | struct BehaviorModel { 24 | #[arg(env)] 25 | be_nice: String, 26 | } 27 | 28 | let help = utils::get_help::(); 29 | assert!(help.contains("[env: BE_NICE=]")); 30 | } 31 | 32 | #[test] 33 | fn overridable() { 34 | #[derive(Debug, PartialEq, Parser)] 35 | #[command(rename_all_env = "kebab")] 36 | struct BehaviorModel { 37 | #[arg(env)] 38 | be_nice: String, 39 | 40 | #[arg(rename_all_env = "pascal", env)] 41 | be_aggressive: String, 42 | } 43 | 44 | let help = utils::get_help::(); 45 | assert!(help.contains("[env: be-nice=]")); 46 | assert!(help.contains("[env: BeAggressive=]")); 47 | } 48 | -------------------------------------------------------------------------------- /tests/derive/type_alias_regressions.rs: -------------------------------------------------------------------------------- 1 | //! Regression test to ensure that type aliases do not cause compilation failures. 2 | 3 | use clap::{Parser, Subcommand, ValueEnum}; 4 | 5 | // Result type alias 6 | #[allow(dead_code)] 7 | type Result = std::result::Result>; 8 | 9 | type Option = std::option::Option; 10 | 11 | #[derive(Parser)] 12 | pub(crate) struct Opts { 13 | another_string: String, 14 | #[command(subcommand)] 15 | command: Command, 16 | #[arg(short, long, value_enum)] 17 | choice: ArgChoice, 18 | } 19 | 20 | #[derive(Subcommand, PartialEq, Debug)] 21 | enum Command { 22 | DoSomething { arg: Option }, 23 | } 24 | 25 | #[derive(ValueEnum, PartialEq, Debug, Clone)] 26 | enum ArgChoice { 27 | Foo, 28 | Bar, 29 | } 30 | 31 | #[test] 32 | fn type_alias_regressions() { 33 | Opts::try_parse_from(["test", "value", "--choice=foo", "do-something"]).unwrap(); 34 | } 35 | -------------------------------------------------------------------------------- /tests/derive_ui.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Guillaume Pinot (@TeXitoi) 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | 8 | #![cfg(feature = "unstable-derive-ui-tests")] 9 | 10 | #[cfg(feature = "derive")] 11 | #[rustversion::attr(not(stable(1.87)), ignore)] // STABLE 12 | #[test] 13 | fn ui() { 14 | let t = trybuild::TestCases::new(); 15 | t.compile_fail("tests/derive_ui/*.rs"); 16 | } 17 | -------------------------------------------------------------------------------- /tests/derive_ui/bool_value_enum.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser, Debug)] 4 | #[command(name = "basic")] 5 | struct Opt { 6 | #[arg(short, value_enum, default_value_t)] 7 | opts: bool, 8 | } 9 | 10 | fn main() { 11 | let opt = Opt::parse(); 12 | println!("{opt:?}"); 13 | } 14 | -------------------------------------------------------------------------------- /tests/derive_ui/bool_value_enum.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: the trait bound `bool: ValueEnum` is not satisfied 2 | --> tests/derive_ui/bool_value_enum.rs:6:30 3 | | 4 | 6 | #[arg(short, value_enum, default_value_t)] 5 | | ^^^^^^^^^^^^^^^ the trait `ValueEnum` is not implemented for `bool` 6 | | 7 | = help: the trait `ValueEnum` is implemented for `ColorChoice` 8 | -------------------------------------------------------------------------------- /tests/derive_ui/clap_empty_attr.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser, Debug)] 4 | #[command] 5 | struct Opt {} 6 | 7 | #[derive(Parser, Debug)] 8 | struct Opt1 { 9 | #[arg = "short"] 10 | foo: u32, 11 | } 12 | 13 | fn main() { 14 | let opt = Opt::parse(); 15 | println!("{opt:?}"); 16 | } 17 | -------------------------------------------------------------------------------- /tests/derive_ui/clap_empty_attr.stderr: -------------------------------------------------------------------------------- 1 | error: expected attribute arguments in parentheses: #[command(...)] 2 | --> tests/derive_ui/clap_empty_attr.rs:4:3 3 | | 4 | 4 | #[command] 5 | | ^^^^^^^ 6 | 7 | error: expected parentheses: #[arg(...)] 8 | --> tests/derive_ui/clap_empty_attr.rs:9:11 9 | | 10 | 9 | #[arg = "short"] 11 | | ^ 12 | -------------------------------------------------------------------------------- /tests/derive_ui/default_value_t_invalid.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Guillaume Pinot (@TeXitoi) 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | use clap::Parser; 10 | 11 | #[derive(Parser, Debug)] 12 | #[command(name = "basic")] 13 | struct Opt { 14 | #[arg(default_value_t = -10)] 15 | value: u32, 16 | } 17 | 18 | fn main() { 19 | let opt = Opt::parse(); 20 | println!("{opt:?}"); 21 | } 22 | -------------------------------------------------------------------------------- /tests/derive_ui/default_value_t_invalid.stderr: -------------------------------------------------------------------------------- 1 | error[E0600]: cannot apply unary operator `-` to type `u32` 2 | --> tests/derive_ui/default_value_t_invalid.rs:14:29 3 | | 4 | 14 | #[arg(default_value_t = -10)] 5 | | ^^^ cannot apply unary operator `-` 6 | | 7 | = note: unsigned values cannot be negated 8 | -------------------------------------------------------------------------------- /tests/derive_ui/default_values_t_invalid.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser, Debug)] 4 | #[command(name = "basic")] 5 | struct Opt { 6 | #[arg(default_values_t = [1, 2, 3])] 7 | value: u32, 8 | } 9 | 10 | fn main() { 11 | let opt = Opt::parse(); 12 | println!("{opt:?}"); 13 | } 14 | -------------------------------------------------------------------------------- /tests/derive_ui/default_values_t_invalid.stderr: -------------------------------------------------------------------------------- 1 | error: #[arg(default_values_t)] can be used only on Vec types 2 | 3 | = note: see https://docs.rs/clap/latest/clap/_derive/index.html#arg-attributes 4 | 5 | --> tests/derive_ui/default_values_t_invalid.rs:6:11 6 | | 7 | 6 | #[arg(default_values_t = [1, 2, 3])] 8 | | ^^^^^^^^^^^^^^^^ 9 | -------------------------------------------------------------------------------- /tests/derive_ui/enum_flatten.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Guillaume Pinot (@TeXitoi) 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | use clap::Parser; 10 | 11 | #[derive(Parser, Debug)] 12 | #[command(name = "basic")] 13 | enum Opt { 14 | #[command(flatten)] 15 | Variant1, 16 | } 17 | 18 | fn main() { 19 | let opt = Opt::parse(); 20 | println!("{opt:?}"); 21 | } 22 | -------------------------------------------------------------------------------- /tests/derive_ui/enum_flatten.stderr: -------------------------------------------------------------------------------- 1 | error: `flatten` is usable only with single-typed tuple variants 2 | --> tests/derive_ui/enum_flatten.rs:14:5 3 | | 4 | 14 | / #[command(flatten)] 5 | 15 | | Variant1, 6 | | |____________^ 7 | -------------------------------------------------------------------------------- /tests/derive_ui/enum_variant_not_args.rs: -------------------------------------------------------------------------------- 1 | #[derive(clap::Parser)] 2 | enum Opt { 3 | Sub(SubCmd), 4 | } 5 | 6 | #[derive(clap::Parser)] 7 | enum SubCmd {} 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /tests/derive_ui/enum_variant_not_args.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: the trait bound `SubCmd: clap::Args` is not satisfied 2 | --> tests/derive_ui/enum_variant_not_args.rs:3:9 3 | | 4 | 3 | Sub(SubCmd), 5 | | ^^^^^^ the trait `clap::Args` is not implemented for `SubCmd` 6 | | 7 | = help: the trait `clap::Args` is implemented for `Box` 8 | -------------------------------------------------------------------------------- /tests/derive_ui/external_subcommand_misuse.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser, Debug)] 4 | struct Opt { 5 | #[command(external_subcommand)] 6 | field: String, 7 | } 8 | 9 | fn main() { 10 | let _ = Opt::parse(); 11 | } 12 | -------------------------------------------------------------------------------- /tests/derive_ui/external_subcommand_misuse.stderr: -------------------------------------------------------------------------------- 1 | error: `external_subcommand` cannot be used with `arg` 2 | --> tests/derive_ui/external_subcommand_misuse.rs:5:15 3 | | 4 | 5 | #[command(external_subcommand)] 5 | | ^^^^^^^^^^^^^^^^^^^ 6 | -------------------------------------------------------------------------------- /tests/derive_ui/external_subcommand_wrong_type.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | use std::ffi::CString; 3 | 4 | #[derive(Parser, Debug)] 5 | enum Opt { 6 | #[command(external_subcommand)] 7 | Other(Vec), 8 | } 9 | 10 | #[derive(Parser, Debug)] 11 | enum Opt2 { 12 | #[command(external_subcommand)] 13 | Other(String), 14 | } 15 | 16 | #[derive(Parser, Debug)] 17 | enum Opt3 { 18 | #[command(external_subcommand)] 19 | Other { a: String }, 20 | } 21 | 22 | fn main() { 23 | let _ = Opt::parse(); 24 | let _ = Opt2::parse(); 25 | let _ = Opt3::parse(); 26 | } 27 | -------------------------------------------------------------------------------- /tests/derive_ui/external_subcommand_wrong_type.stderr: -------------------------------------------------------------------------------- 1 | error: The type must be either `Vec` or `Vec` to be used with `external_subcommand`. 2 | --> tests/derive_ui/external_subcommand_wrong_type.rs:7:11 3 | | 4 | 7 | Other(Vec), 5 | | ^^^ 6 | 7 | error: The type must be either `Vec` or `Vec` to be used with `external_subcommand`. 8 | --> tests/derive_ui/external_subcommand_wrong_type.rs:13:11 9 | | 10 | 13 | Other(String), 11 | | ^^^^^^ 12 | 13 | error: The enum variant marked with `external_subcommand` must be a single-typed tuple, and the type must be either `Vec` or `Vec`. 14 | --> tests/derive_ui/external_subcommand_wrong_type.rs:18:5 15 | | 16 | 18 | / #[command(external_subcommand)] 17 | 19 | | Other { a: String }, 18 | | |_______________________^ 19 | -------------------------------------------------------------------------------- /tests/derive_ui/flatten_and_methods.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Guillaume Pinot (@TeXitoi) 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | use clap::Parser; 10 | 11 | #[derive(Parser, Debug)] 12 | struct DaemonOpts { 13 | #[arg(short)] 14 | user: String, 15 | #[arg(short)] 16 | group: String, 17 | } 18 | 19 | #[derive(Parser, Debug)] 20 | #[command(name = "basic")] 21 | struct Opt { 22 | #[command(flatten, version = "foo")] 23 | opts: DaemonOpts, 24 | } 25 | 26 | fn main() { 27 | let opt = Opt::parse(); 28 | println!("{opt:?}"); 29 | } 30 | -------------------------------------------------------------------------------- /tests/derive_ui/flatten_and_methods.stderr: -------------------------------------------------------------------------------- 1 | error: methods are not allowed for flattened entry 2 | --> tests/derive_ui/flatten_and_methods.rs:22:15 3 | | 4 | 22 | #[command(flatten, version = "foo")] 5 | | ^^^^^^^ 6 | -------------------------------------------------------------------------------- /tests/derive_ui/flatten_enum_in_struct.rs: -------------------------------------------------------------------------------- 1 | #[derive(clap::Parser)] 2 | struct Opt { 3 | #[command(flatten)] 4 | sub: SubCmd, 5 | } 6 | 7 | #[derive(clap::Parser)] 8 | enum SubCmd {} 9 | 10 | fn main() {} 11 | -------------------------------------------------------------------------------- /tests/derive_ui/flatten_enum_in_struct.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: the trait bound `SubCmd: clap::Args` is not satisfied 2 | --> tests/derive_ui/flatten_enum_in_struct.rs:4:10 3 | | 4 | 4 | sub: SubCmd, 5 | | ^^^^^^ the trait `clap::Args` is not implemented for `SubCmd` 6 | | 7 | = help: the following other types implement trait `clap::Args`: 8 | Box 9 | Opt 10 | -------------------------------------------------------------------------------- /tests/derive_ui/flatten_struct_in_enum.rs: -------------------------------------------------------------------------------- 1 | #[derive(clap::Parser)] 2 | enum Opt { 3 | #[command(flatten)] 4 | Sub(SubCmd), 5 | } 6 | 7 | #[derive(clap::Parser)] 8 | struct SubCmd {} 9 | 10 | fn main() {} 11 | -------------------------------------------------------------------------------- /tests/derive_ui/flatten_struct_in_enum.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: the trait bound `SubCmd: Subcommand` is not satisfied 2 | --> tests/derive_ui/flatten_struct_in_enum.rs:4:9 3 | | 4 | 4 | Sub(SubCmd), 5 | | ^^^^^^ the trait `Subcommand` is not implemented for `SubCmd` 6 | | 7 | = help: the following other types implement trait `Subcommand`: 8 | Box 9 | Opt 10 | -------------------------------------------------------------------------------- /tests/derive_ui/group_name_attribute.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser, Debug)] 4 | #[command(name = "basic")] 5 | struct Opt { 6 | #[command(flatten)] 7 | source: Source, 8 | } 9 | 10 | #[derive(clap::Args, Debug)] 11 | #[group(required = true, name = "src")] 12 | struct Source { 13 | #[arg(short)] 14 | git: String, 15 | 16 | #[arg(short)] 17 | path: String, 18 | } 19 | 20 | fn main() { 21 | let opt = Opt::parse(); 22 | println!("{opt:?}"); 23 | } 24 | -------------------------------------------------------------------------------- /tests/derive_ui/group_name_attribute.stderr: -------------------------------------------------------------------------------- 1 | error[E0599]: no method named `name` found for struct `ArgGroup` in the current scope 2 | --> tests/derive_ui/group_name_attribute.rs:11:26 3 | | 4 | 11 | #[group(required = true, name = "src")] 5 | | ^^^^ 6 | | 7 | help: there is a method `ne` with a similar name 8 | | 9 | 11 - #[group(required = true, name = "src")] 10 | 11 + #[group(required = true, ne = "src")] 11 | | 12 | -------------------------------------------------------------------------------- /tests/derive_ui/multiple_external_subcommand.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser, Debug)] 4 | struct Opt { 5 | #[command(subcommand)] 6 | cmd: Command, 7 | } 8 | 9 | #[derive(Parser, Debug)] 10 | enum Command { 11 | #[command(external_subcommand)] 12 | Run(Vec), 13 | 14 | #[command(external_subcommand)] 15 | Other(Vec), 16 | } 17 | 18 | fn main() { 19 | let opt = Opt::parse(); 20 | println!("{opt:?}"); 21 | } 22 | -------------------------------------------------------------------------------- /tests/derive_ui/multiple_external_subcommand.stderr: -------------------------------------------------------------------------------- 1 | error: Only one variant can be marked with `external_subcommand`, this is the second 2 | --> tests/derive_ui/multiple_external_subcommand.rs:14:15 3 | | 4 | 14 | #[command(external_subcommand)] 5 | | ^^^^^^^^^^^^^^^^^^^ 6 | -------------------------------------------------------------------------------- /tests/derive_ui/non_existent_attr.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Guillaume Pinot (@TeXitoi) 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | use clap::Parser; 10 | 11 | #[derive(Parser, Debug)] 12 | #[command(name = "basic")] 13 | struct Opt { 14 | #[arg(short, non_existing_attribute = 1)] 15 | debug: bool, 16 | } 17 | 18 | fn main() { 19 | let opt = Opt::parse(); 20 | println!("{opt:?}"); 21 | } 22 | -------------------------------------------------------------------------------- /tests/derive_ui/non_existent_attr.stderr: -------------------------------------------------------------------------------- 1 | error[E0599]: no method named `non_existing_attribute` found for struct `Arg` in the current scope 2 | --> tests/derive_ui/non_existent_attr.rs:14:18 3 | | 4 | 14 | #[arg(short, non_existing_attribute = 1)] 5 | | ^^^^^^^^^^^^^^^^^^^^^^ method not found in `Arg` 6 | -------------------------------------------------------------------------------- /tests/derive_ui/rename_all_wrong_casing.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Guillaume Pinot (@TeXitoi) 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | use clap::Parser; 10 | 11 | #[derive(Parser, Debug)] 12 | #[command(name = "basic", rename_all = "fail")] 13 | struct Opt { 14 | #[arg(short)] 15 | s: String, 16 | } 17 | 18 | fn main() { 19 | let opt = Opt::parse(); 20 | println!("{opt:?}"); 21 | } 22 | -------------------------------------------------------------------------------- /tests/derive_ui/rename_all_wrong_casing.stderr: -------------------------------------------------------------------------------- 1 | error: unsupported casing: `fail` 2 | --> tests/derive_ui/rename_all_wrong_casing.rs:12:40 3 | | 4 | 12 | #[command(name = "basic", rename_all = "fail")] 5 | | ^^^^^^ 6 | -------------------------------------------------------------------------------- /tests/derive_ui/skip_flatten.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Guillaume Pinot (@TeXitoi) 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | use clap::Parser; 10 | 11 | #[derive(Parser, Debug)] 12 | #[command(name = "make-cookie")] 13 | struct MakeCookie { 14 | #[arg(short)] 15 | s: String, 16 | 17 | #[command(skip, flatten)] 18 | cmd: Command, 19 | } 20 | 21 | #[derive(Parser, Debug)] 22 | enum Command { 23 | #[command(name = "pound")] 24 | /// Pound acorns into flour for cookie dough. 25 | Pound { acorns: u32 }, 26 | 27 | Sparkle { 28 | #[arg(short)] 29 | color: String, 30 | }, 31 | } 32 | 33 | impl Default for Command { 34 | fn default() -> Self { 35 | Command::Pound { acorns: 0 } 36 | } 37 | } 38 | 39 | fn main() { 40 | let opt = MakeCookie::parse(); 41 | println!("{opt:?}"); 42 | } 43 | -------------------------------------------------------------------------------- /tests/derive_ui/skip_flatten.stderr: -------------------------------------------------------------------------------- 1 | error: `flatten` cannot be used with `skip` 2 | --> tests/derive_ui/skip_flatten.rs:17:21 3 | | 4 | 17 | #[command(skip, flatten)] 5 | | ^^^^^^^ 6 | -------------------------------------------------------------------------------- /tests/derive_ui/skip_subcommand.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Guillaume Pinot (@TeXitoi) 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | use clap::Parser; 10 | 11 | #[derive(Parser, Debug)] 12 | #[command(name = "make-cookie")] 13 | struct MakeCookie { 14 | #[arg(short)] 15 | s: String, 16 | 17 | #[command(subcommand, skip)] 18 | cmd: Command, 19 | } 20 | 21 | #[derive(Parser, Debug)] 22 | enum Command { 23 | #[command(name = "pound")] 24 | /// Pound acorns into flour for cookie dough. 25 | Pound { acorns: u32 }, 26 | 27 | Sparkle { 28 | #[arg(short)] 29 | color: String, 30 | }, 31 | } 32 | 33 | impl Default for Command { 34 | fn default() -> Self { 35 | Command::Pound { acorns: 0 } 36 | } 37 | } 38 | 39 | fn main() { 40 | let opt = MakeCookie::parse(); 41 | println!("{opt:?}"); 42 | } 43 | -------------------------------------------------------------------------------- /tests/derive_ui/skip_subcommand.stderr: -------------------------------------------------------------------------------- 1 | error: `skip` cannot be used with `subcommand` 2 | --> tests/derive_ui/skip_subcommand.rs:17:27 3 | | 4 | 17 | #[command(subcommand, skip)] 5 | | ^^^^ 6 | -------------------------------------------------------------------------------- /tests/derive_ui/skip_with_other_options.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser, Debug)] 4 | #[command(name = "test")] 5 | pub struct Opt { 6 | #[arg(long)] 7 | a: u32, 8 | #[arg(skip, long)] 9 | b: u32, 10 | } 11 | 12 | fn main() { 13 | let opt = Opt::parse(); 14 | println!("{opt:?}"); 15 | } 16 | -------------------------------------------------------------------------------- /tests/derive_ui/skip_with_other_options.stderr: -------------------------------------------------------------------------------- 1 | error: `long` cannot be used with `#[arg(skip)] 2 | --> tests/derive_ui/skip_with_other_options.rs:8:17 3 | | 4 | 8 | #[arg(skip, long)] 5 | | ^^^^ 6 | -------------------------------------------------------------------------------- /tests/derive_ui/skip_without_default.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Guillaume Pinot (@TeXitoi) 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | use clap::Parser; 10 | 11 | #[derive(Debug)] 12 | enum Kind { 13 | A, 14 | B, 15 | } 16 | 17 | #[derive(Parser, Debug)] 18 | #[command(name = "test")] 19 | pub struct Opt { 20 | #[arg(short)] 21 | number: u32, 22 | #[arg(skip)] 23 | k: Kind, 24 | } 25 | 26 | fn main() { 27 | let opt = Opt::parse(); 28 | println!("{opt:?}"); 29 | } 30 | -------------------------------------------------------------------------------- /tests/derive_ui/skip_without_default.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: the trait bound `Kind: Default` is not satisfied 2 | --> tests/derive_ui/skip_without_default.rs:22:11 3 | | 4 | 22 | #[arg(skip)] 5 | | ^^^^ the trait `Default` is not implemented for `Kind` 6 | -------------------------------------------------------------------------------- /tests/derive_ui/struct_subcommand.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Guillaume Pinot (@TeXitoi) 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | use clap::Parser; 10 | 11 | #[derive(Parser, Debug)] 12 | #[command(name = "basic", subcommand)] 13 | struct Opt { 14 | #[arg(short)] 15 | s: String, 16 | } 17 | 18 | fn main() { 19 | let opt = Opt::parse(); 20 | println!("{opt:?}"); 21 | } 22 | -------------------------------------------------------------------------------- /tests/derive_ui/struct_subcommand.stderr: -------------------------------------------------------------------------------- 1 | error: `subcommand` cannot be used with `command` 2 | --> tests/derive_ui/struct_subcommand.rs:12:27 3 | | 4 | 12 | #[command(name = "basic", subcommand)] 5 | | ^^^^^^^^^^ 6 | -------------------------------------------------------------------------------- /tests/derive_ui/subcommand_and_flatten.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Guillaume Pinot (@TeXitoi) 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | use clap::Parser; 10 | 11 | #[derive(Parser, Debug)] 12 | struct MakeCookie { 13 | #[arg(short)] 14 | s: String, 15 | 16 | #[command(subcommand, flatten)] 17 | cmd: Command, 18 | } 19 | 20 | #[derive(Parser, Debug)] 21 | enum Command { 22 | /// Pound acorns into flour for cookie dough. 23 | Pound { acorns: u32 }, 24 | 25 | Sparkle { 26 | #[arg(short)] 27 | color: String, 28 | }, 29 | } 30 | 31 | fn main() { 32 | let opt = MakeCookie::parse(); 33 | println!("{opt:?}"); 34 | } 35 | -------------------------------------------------------------------------------- /tests/derive_ui/subcommand_and_flatten.stderr: -------------------------------------------------------------------------------- 1 | error: `flatten` cannot be used with `subcommand` 2 | --> tests/derive_ui/subcommand_and_flatten.rs:16:27 3 | | 4 | 16 | #[command(subcommand, flatten)] 5 | | ^^^^^^^ 6 | -------------------------------------------------------------------------------- /tests/derive_ui/subcommand_and_methods.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Guillaume Pinot (@TeXitoi) 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | use clap::Parser; 10 | 11 | #[derive(Parser, Debug)] 12 | struct MakeCookie { 13 | #[arg(short)] 14 | s: String, 15 | 16 | #[command(subcommand, version = "foo")] 17 | cmd: Command, 18 | } 19 | 20 | #[derive(Parser, Debug)] 21 | enum Command { 22 | /// Pound acorns into flour for cookie dough. 23 | Pound { acorns: u32 }, 24 | 25 | Sparkle { 26 | #[arg(short)] 27 | color: String, 28 | }, 29 | } 30 | 31 | fn main() { 32 | let opt = MakeCookie::parse(); 33 | println!("{opt:?}"); 34 | } 35 | -------------------------------------------------------------------------------- /tests/derive_ui/subcommand_and_methods.stderr: -------------------------------------------------------------------------------- 1 | error: methods in attributes are not allowed for subcommand 2 | --> tests/derive_ui/subcommand_and_methods.rs:16:15 3 | | 4 | 16 | #[command(subcommand, version = "foo")] 5 | | ^^^^^^^^^^ 6 | -------------------------------------------------------------------------------- /tests/derive_ui/subcommand_on_struct.rs: -------------------------------------------------------------------------------- 1 | use clap::Subcommand; 2 | 3 | #[derive(Subcommand, Debug)] 4 | struct Opt {} 5 | 6 | fn main() {} 7 | -------------------------------------------------------------------------------- /tests/derive_ui/subcommand_on_struct.stderr: -------------------------------------------------------------------------------- 1 | error: `#[derive(Subcommand)]` only supports enums 2 | --> $DIR/subcommand_on_struct.rs:3:10 3 | | 4 | 3 | #[derive(Subcommand, Debug)] 5 | | ^^^^^^^^^^ 6 | | 7 | = note: this error originates in the derive macro `Subcommand` (in Nightly builds, run with -Z macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/derive_ui/subcommand_opt_opt.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Guillaume Pinot (@TeXitoi) 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | use clap::Parser; 10 | 11 | #[derive(Parser, Debug)] 12 | struct MakeCookie { 13 | #[arg(short)] 14 | s: String, 15 | 16 | #[command(subcommand)] 17 | cmd: Option>, 18 | } 19 | 20 | #[derive(Parser, Debug)] 21 | enum Command { 22 | /// Pound acorns into flour for cookie dough. 23 | Pound { acorns: u32 }, 24 | 25 | Sparkle { 26 | #[arg(short)] 27 | color: String, 28 | }, 29 | } 30 | 31 | fn main() { 32 | let opt = MakeCookie::parse(); 33 | println!("{opt:?}"); 34 | } 35 | -------------------------------------------------------------------------------- /tests/derive_ui/subcommand_opt_opt.stderr: -------------------------------------------------------------------------------- 1 | error: Option> types are not supported for subcommand 2 | --> tests/derive_ui/subcommand_opt_opt.rs:17:10 3 | | 4 | 17 | cmd: Option>, 5 | | ^^^^^^ 6 | -------------------------------------------------------------------------------- /tests/derive_ui/subcommand_opt_vec.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Guillaume Pinot (@TeXitoi) 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | use clap::Parser; 10 | 11 | #[derive(Parser, Debug)] 12 | struct MakeCookie { 13 | #[arg(short)] 14 | s: String, 15 | 16 | #[command(subcommand)] 17 | cmd: Option>, 18 | } 19 | 20 | #[derive(Parser, Debug)] 21 | enum Command { 22 | /// Pound acorns into flour for cookie dough. 23 | Pound { acorns: u32 }, 24 | 25 | Sparkle { 26 | #[arg(short)] 27 | color: String, 28 | }, 29 | } 30 | 31 | fn main() { 32 | let opt = MakeCookie::parse(); 33 | println!("{opt:?}"); 34 | } 35 | -------------------------------------------------------------------------------- /tests/derive_ui/subcommand_opt_vec.stderr: -------------------------------------------------------------------------------- 1 | error: Option> types are not supported for subcommand 2 | --> tests/derive_ui/subcommand_opt_vec.rs:17:10 3 | | 4 | 17 | cmd: Option>, 5 | | ^^^^^^ 6 | -------------------------------------------------------------------------------- /tests/derive_ui/tuple_struct.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Guillaume Pinot (@TeXitoi) 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | use clap::Parser; 10 | 11 | #[derive(Parser, Debug)] 12 | #[command(name = "basic")] 13 | struct Opt(u32); 14 | 15 | fn main() { 16 | let opt = Opt::parse(); 17 | println!("{opt:?}"); 18 | } 19 | -------------------------------------------------------------------------------- /tests/derive_ui/tuple_struct.stderr: -------------------------------------------------------------------------------- 1 | error: `#[derive(Parser)]` only supports non-tuple structs and enums 2 | --> tests/derive_ui/tuple_struct.rs:11:10 3 | | 4 | 11 | #[derive(Parser, Debug)] 5 | | ^^^^^^ 6 | | 7 | = note: this error originates in the derive macro `Parser` (in Nightly builds, run with -Z macro-backtrace for more info) 8 | 9 | error[E0599]: no function or associated item named `parse` found for struct `Opt` in the current scope 10 | --> tests/derive_ui/tuple_struct.rs:16:20 11 | | 12 | 13 | struct Opt(u32); 13 | | ---------- function or associated item `parse` not found for this struct 14 | ... 15 | 16 | let opt = Opt::parse(); 16 | | ^^^^^ function or associated item not found in `Opt` 17 | | 18 | = help: items from traits can only be used if the trait is implemented and in scope 19 | = note: the following traits define an item `parse`, perhaps you need to implement one of them: 20 | candidate #1: `Parser` 21 | candidate #2: `TypedValueParser` 22 | -------------------------------------------------------------------------------- /tests/derive_ui/value_enum_non_unit.rs: -------------------------------------------------------------------------------- 1 | use clap::ValueEnum; 2 | 3 | #[derive(ValueEnum, Clone, Debug)] 4 | enum Opt { 5 | Foo(usize), 6 | } 7 | 8 | fn main() { 9 | println!("{:?}", Opt::Foo(42)); 10 | } 11 | -------------------------------------------------------------------------------- /tests/derive_ui/value_enum_non_unit.stderr: -------------------------------------------------------------------------------- 1 | error: `#[derive(ValueEnum)]` only supports unit variants. Non-unit variants must be skipped 2 | --> tests/derive_ui/value_enum_non_unit.rs:5:5 3 | | 4 | 5 | Foo(usize), 5 | | ^^^ 6 | -------------------------------------------------------------------------------- /tests/derive_ui/value_enum_on_struct.rs: -------------------------------------------------------------------------------- 1 | use clap::ValueEnum; 2 | 3 | #[derive(ValueEnum, Clone, Debug)] 4 | struct Opt {} 5 | 6 | fn main() { 7 | println!("{:?}", Opt::value_variants()); 8 | } 9 | -------------------------------------------------------------------------------- /tests/derive_ui/value_enum_on_struct.stderr: -------------------------------------------------------------------------------- 1 | error: `#[derive(ValueEnum)]` only supports enums 2 | --> tests/derive_ui/value_enum_on_struct.rs:3:10 3 | | 4 | 3 | #[derive(ValueEnum, Clone, Debug)] 5 | | ^^^^^^^^^ 6 | | 7 | = note: this error originates in the derive macro `ValueEnum` (in Nightly builds, run with -Z macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/derive_ui/value_parser_unsupported.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser, Debug)] 4 | struct Cli { 5 | foo: Custom, 6 | } 7 | 8 | #[derive(Clone, Debug)] 9 | struct Custom; 10 | 11 | fn main() { 12 | Cli::parse(); 13 | } 14 | -------------------------------------------------------------------------------- /tests/examples.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | #[cfg(feature = "help")] 3 | #[cfg(feature = "error-context")] 4 | #[cfg(feature = "usage")] 5 | fn example_tests() { 6 | let t = trycmd::TestCases::new(); 7 | let features = [ 8 | // Default 9 | #[cfg(feature = "std")] 10 | "std", 11 | #[cfg(feature = "color")] 12 | "color", 13 | #[cfg(feature = "help")] 14 | "help", 15 | #[cfg(feature = "usage")] 16 | "usage", 17 | #[cfg(feature = "error-context")] 18 | "error-context", 19 | #[cfg(feature = "suggestions")] 20 | "suggestions", 21 | // Optional 22 | #[cfg(feature = "derive")] 23 | "derive", 24 | #[cfg(feature = "cargo")] 25 | "cargo", 26 | #[cfg(feature = "wrap_help")] 27 | "wrap_help", 28 | #[cfg(feature = "env")] 29 | "env", 30 | #[cfg(feature = "unicode")] 31 | "unicode", 32 | #[cfg(feature = "string")] 33 | "string", 34 | // In-work 35 | //#[cfg(feature = "unstable-v5")] // Currently has failures 36 | //"unstable-v5", 37 | ] 38 | .join(" "); 39 | t.register_bins(trycmd::cargo::compile_examples(["--features", &features]).unwrap()); 40 | t.case("examples/**/*.md"); 41 | } 42 | -------------------------------------------------------------------------------- /tests/ui.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | #[cfg(feature = "help")] 3 | #[cfg(feature = "error-context")] 4 | #[cfg(feature = "usage")] 5 | fn ui_tests() { 6 | let t = trycmd::TestCases::new(); 7 | let features = [ 8 | // Default 9 | #[cfg(feature = "std")] 10 | "std", 11 | #[cfg(feature = "color")] 12 | "color", 13 | #[cfg(feature = "help")] 14 | "help", 15 | #[cfg(feature = "usage")] 16 | "usage", 17 | #[cfg(feature = "error-context")] 18 | "error-context", 19 | #[cfg(feature = "suggestions")] 20 | "suggestions", 21 | // Optional 22 | #[cfg(feature = "derive")] 23 | "derive", 24 | #[cfg(feature = "cargo")] 25 | "cargo", 26 | #[cfg(feature = "wrap_help")] 27 | "wrap_help", 28 | #[cfg(feature = "env")] 29 | "env", 30 | #[cfg(feature = "unicode")] 31 | "unicode", 32 | #[cfg(feature = "string")] 33 | "string", 34 | // In-work 35 | //#[cfg(feature = "unstable-v5")] // Currently has failures 36 | //"unstable-v5", 37 | ] 38 | .join(" "); 39 | t.register_bins(trycmd::cargo::compile_examples(["--features", &features]).unwrap()); 40 | t.case("tests/ui/*.toml"); 41 | } 42 | -------------------------------------------------------------------------------- /tests/ui/V_flag_stdout.toml: -------------------------------------------------------------------------------- 1 | bin.name = "stdio-fixture" 2 | args = ["-V"] 3 | status.code = 0 4 | stdout = """ 5 | stdio-fixture 1.0 6 | """ 7 | stderr = "" 8 | -------------------------------------------------------------------------------- /tests/ui/arg_required_else_help_stderr.toml: -------------------------------------------------------------------------------- 1 | bin.name = "stdio-fixture" 2 | args = [] 3 | status.code = 2 4 | stdout = "" 5 | stderr = """ 6 | Usage: stdio-fixture[EXE] [OPTIONS] [COMMAND] 7 | 8 | Commands: 9 | more 10 | help Print this message or the help of the given subcommand(s) 11 | 12 | Options: 13 | --verbose log 14 | -h, --help Print help (see more with '--help') 15 | -V, --version Print version 16 | """ 17 | -------------------------------------------------------------------------------- /tests/ui/error_stderr.toml: -------------------------------------------------------------------------------- 1 | bin.name = "stdio-fixture" 2 | args = ["--unknown-argument"] 3 | status.code = 2 4 | stdout = "" 5 | stderr = """ 6 | error: unexpected argument '--unknown-argument' found 7 | 8 | Usage: stdio-fixture[EXE] [OPTIONS] [COMMAND] 9 | 10 | For more information, try '--help'. 11 | """ 12 | -------------------------------------------------------------------------------- /tests/ui/h_flag_stdout.toml: -------------------------------------------------------------------------------- 1 | bin.name = "stdio-fixture" 2 | args = ["-h"] 3 | status.code = 0 4 | stdout = """ 5 | Usage: stdio-fixture[EXE] [OPTIONS] [COMMAND] 6 | 7 | Commands: 8 | more 9 | help Print this message or the help of the given subcommand(s) 10 | 11 | Options: 12 | --verbose log 13 | -h, --help Print help (see more with '--help') 14 | -V, --version Print version 15 | """ 16 | stderr = "" 17 | -------------------------------------------------------------------------------- /tests/ui/help_cmd_stdout.toml: -------------------------------------------------------------------------------- 1 | bin.name = "stdio-fixture" 2 | args = ["help"] 3 | status.code = 0 4 | stdout = """ 5 | Usage: stdio-fixture[EXE] [OPTIONS] [COMMAND] 6 | 7 | Commands: 8 | more 9 | help Print this message or the help of the given subcommand(s) 10 | 11 | Options: 12 | --verbose 13 | more log 14 | 15 | -h, --help 16 | Print help (see a summary with '-h') 17 | 18 | -V, --version 19 | Print version 20 | """ 21 | stderr = "" 22 | -------------------------------------------------------------------------------- /tests/ui/help_flag_stdout.toml: -------------------------------------------------------------------------------- 1 | bin.name = "stdio-fixture" 2 | args = ["--help"] 3 | status.code = 0 4 | stdout = """ 5 | Usage: stdio-fixture[EXE] [OPTIONS] [COMMAND] 6 | 7 | Commands: 8 | more 9 | help Print this message or the help of the given subcommand(s) 10 | 11 | Options: 12 | --verbose 13 | more log 14 | 15 | -h, --help 16 | Print help (see a summary with '-h') 17 | 18 | -V, --version 19 | Print version 20 | """ 21 | stderr = "" 22 | -------------------------------------------------------------------------------- /tests/ui/version_flag_stdout.toml: -------------------------------------------------------------------------------- 1 | bin.name = "stdio-fixture" 2 | args = ["--version"] 3 | status.code = 0 4 | stdout = """ 5 | stdio-fixture 1.0 - a2132c 6 | """ 7 | stderr = "" 8 | -------------------------------------------------------------------------------- /typos.toml: -------------------------------------------------------------------------------- 1 | files.extend-exclude = [ 2 | "CHANGELOG.md", 3 | "tests", 4 | ] 5 | [default.extend-words] 6 | # Acronyms 7 | als = "als" 8 | lits = "lits" 9 | --------------------------------------------------------------------------------