38 Commits
Author SHA1 Message Date
Ross Goldberg 5b1320e9d6 Make CommandParser.swift import Swift version consistent with other files. (#724) 2025-02-12 19:19:40 -08:00
Rauhul Varma fd8ea096da Remove @_implementationOnly imports (#666)
The `@_implementationOnly` attribute does not work correctly without
library evolution enabled. The only possible client with this enabled is
Apple, however they have updated to the Swift 6 compiler and can use
`internal import` instead of this attribute. Therefore there is no need
for this package to use the attribute anymore.
2025-02-12 13:01:44 -08:00
Rauhul Varma 10d80282e5 Enable swift-format checking (#711)
Adopts the common swift-mmio and swift-argument-parser format and enables CI checking.

Fixes: #702
2025-02-10 14:58:19 -08:00
Rauhul Varma 1248cc4bda Fix concurrency warnings (#705)
Moves static read-only vars behind a mutex so they are currency safe.
Users of the api don't need to worry about this because the mutex is
hidden behind an accessor.
2025-02-06 15:02:53 -08:00
Ross Goldberg 5f48a1614f Add singleton to indicate which shell version is requesting completion candidates (#690)
Create a `String?` singleton named `CompletionShell.requestingVersion` that
indicates which shell version is requesting completion candidates.

It will be set to the correct value while a Swift custom completion function is
executing to offer completions for a word from a command line (e.g., while
`customCompletion` from `@Option(completion: .custom(customCompletion))`
executes). Otherwise, it will be set to `nil`.

The requesting shell version is communicated to the Swift app via an environment
variable named `SAP_SHELL_VERSION`, which is exported by each of the generated
completion scripts.

Improve some nearby DocC.

Resolve #689

Signed-off-by: Ross Goldberg <484615+rgoldberg@users.noreply.github.com>
2025-01-22 09:22:35 -06:00
Ross Goldberg 2edadce25d Add singleton to indicate which shell is requesting completion candidates (#680)
A CompletionShell singleton named CompletionShell.requesting has been created
that indicates which shell is requesting completion candidates.

The singleton is populated when a completion script is generated, so functions
used to generate arguments for CompletionKind creation functions can return
completion candidate syntax / shell commands tailored for that shell.

For the custom(:) CompletionKind creation function, the singleton is populated
at runtime (when a completion script requests completions from the Swift app
after a user types tab while composing a command line to call the app).

The requesting shell is communicated to the Swift app via an environment variable
named SAP_SHELL, which is exported by each of the generated completion scripts.

Resolve #672

Signed-off-by: Ross Goldberg <484615+rgoldberg@users.noreply.github.com>
2025-01-21 23:57:36 -06:00
Craig Siemens d66d015418 Fix zsh/bash completions for arguments in option groups with a custom completion (#648)
* Added conversion for InputKey to/from fullPathString.

* Updated custom completions to use the IndexKey.fullPathString.

This resolves an issue where custom completion for arguments in an OptionGroup would fail to match the argument. It was caused by:
- the completion script only using the name of the argument (instead of the full path)
- the CommandParser looking for the matching argument by comparing a name only IndexKey with the “full” IndexKeys

* Updated BashCompletionsGenerator to use customCompletionCall.

The zsh completions already uses this function. The function’s implementation is the same as what the BashCompletionsGenerator is doing. This removes the duplicated logic.

* Updated completion tests to include nested arguments with custom completions.

* Switched to using the split method from the stdlib.

Prevously was using .components(seperatedBy:) from Foundation.

* Updated the fish completions to include arguments
2024-07-04 00:52:58 -05:00
Danny Canter 2b962934d1 Add aliases support for sub commands (#627)
This adds support for aliases for subcommands via a new parameter to
CommandConfigurations constructors. The aliases are passed as an array
of strings, where the default is just an empty array that signifies there
are no aliases. The aliases are supported regardless of if a different
commandName is chosen or not. This also updates how subcommands show up
in the help text. Any aliases are now displayed to the right of the original
command.

In addition to the functionality itself, this change:

1. Updates some of the EndToEnd parsing tests to make sure they function
while using aliases.
2. Sprinkles mentions where I saw fit in the documentation.
3. Updates the Math example to have aliases for `math stats average`
(`math stats avg`), and `math multiply` (`math mul`).

`math`'s help text now looks like the below:

```
~ math --help
OVERVIEW: A utility for performing maths.

USAGE: math <subcommand>

OPTIONS:
  --version               Show the version.
  -h, --help              Show help information.

SUBCOMMANDS:
  add (default)           Print the sum of the values.
  multiply, mul           Print the product of the values.
  stats                   Calculate descriptive statistics.

  See 'math help <subcommand>' for detailed help.

~ math stats --help
OVERVIEW: Calculate descriptive statistics.

USAGE: math stats <subcommand>

OPTIONS:
  --version               Show the version.
  -h, --help              Show help information.

SUBCOMMANDS:
  average, avg            Print the average of the values.
  stdev                   Print the standard deviation of the values.
  quantiles               Print the quantiles of the values (TBD).

  See 'math help stats <subcommand>' for detailed help.
```

and use of the aliases:

```
~ math mul 10 10
100

~ math stats avg 10 20
15.0
```

This change does NOT add any updates to the shell completion logic for
this feature.

Fixes #248
2024-04-30 18:20:03 -05:00
Nate Cook 6c7ec363da Fix unrecognized -help flag with default command (#612)
When there's a default subcommand that captures pass-through args,
only a standalone help flag should trigger help (since the flag should
otherwise go to the subcommand). This fix makes that true for single-
dash help flag names, which were previously being skipped, due to
single-dash flags being lexed as both one whole flag and as a group of
individual short flags.

Re: https://github.com/apple/swift-package-manager/issues/7218
Re: rdar://120422808
2024-01-04 14:49:48 -06:00
Nate Cook f674173291 Don't let .allUnrecognized consume built-in flags (#550)
Arguments declared with the `.allUnrecognized` parsing strategy
currently capture built-in flags, which isn't intended. This
fixes that issue by looking for built-in flags in the captured
portion of the input before decoding.

Fixes rdar://104990388
2023-02-08 21:02:46 -08:00
Nate Cook a9b9644153 Stop removing underscores from CodingKey names in InputKey (#548)
When a property wrapper is applied to a property, the property's
storage is given a name with a prefixed underscore. That is,
for a property named `x`, the actual storage is named `_x`.

That prefixed storage is what is visible through reflection, so
when building an ArgumentSet from a command type's Mirror, we
need to remove the leading underscore. This is done when creating
an InputKey for each property.

However, InputKeys are also created from CodingKeys during
decoding of a ParsableCommand. These CodingKeys _do not_ have
the leading underscore that is visible, so any underscores
that appear are actually from the declaration of the property
with an underscored name. Removing leading underscores from
CodingKey names results in a mismatch when trying to find
the decoded value.

This change simplifies the InputKey type to use an array
path instead of an indirect enum and removes the leading
underscore dropping when creating an InputKey from a CodingKey.

rdar://104928743
2023-02-02 08:33:51 -06:00
David Peterson 587d26a2aa Fixes incorrect value copying when ParseArguments has the same field name+type as the ParseCommand (Issue #322) (#495)
* Contains fixes and test cases for #322
2022-09-22 09:43:48 -05:00
Nate Cook 6f30db08e6 Don't trigger help for unconditional remaining commands (#417) 2022-03-12 12:33:19 -06:00
Rauhul Varma e7765e1f39 Replace createHelp and includeHidden (#405)
- Replaces `ArgumentSet.init(_:creatingHelp:includeHidden:)` with
  `ArgumentSet.init(_:visibility:)`. `visibility` intentionally does not
  have a default value to ensure that callers only have the correct
  arguments. As part of this change `includeHidden` has been replaced
  throughout the codebase with `visibility`. This change also fixes a
  bug where arguments with hidden `visibility` were being displayed in the
  generated command usage string.
2022-02-14 23:54:57 -06:00
Rauhul Varma 63e6c57b63 Provide non-experimental help-hidden flags (#409) 2022-02-12 16:50:09 -06:00
Rauhul Varma 185b45fa06 Combine HelpCommand and HelpHiddenCommand (#408) 2022-02-12 16:35:31 -06:00
Keith Smiley b547374049 Add --help-hidden for use with _hiddenFromHelp (#366)
Swift Package Manager adopted _hiddenFromHelp, the resulting help is
much more approachable for basic usage, but leaves no way to view
all the advanced options it accepts. This takes from swiftc's + clang's
playbook and adds a hidden `--help-hidden` flag that prints all help,
including those using `_hiddenFromHelp`
2022-02-11 14:25:22 -06:00
Nate Cook 1a5b1b3c03 Fix issue with unconditional remaining properties in subcommands (#397)
* Propagate unconditional remaining arguments to higher commands

This changes the behavior of parsing when a subcommand includes an
argument array with an unconditionalRemaining parsing strategy, such
that parsing options stops when the subcommand is encountered, so
that the subcommand can pick up those additional options.
2022-01-31 14:55:19 -06:00
Nate Cook 9b6827d348 Mark the dump help feature as experimental for now (#350)
* Mark `--dump-help` as experimental
* Mark the dumpHelp method as underscored
2021-09-01 16:42:17 -05:00
Nate Cook 685341f629 Use standard path for --dump-help help/completions, remove completions (#339) 2021-07-20 12:59:36 -05:00
Kotaro Suto cfcb9cb0cd Add new built-in flag --dump-help (#310)
This commit will add a new builtin option named `--dump-help-info` which
outputs help information in JSON.
2021-07-07 13:09:21 -05:00
Md Abir Hasan Zoha d80c0172d8 Add custom helpNames support for Subcommand (#251)
If helpNames is not modified, Subcommand will inherit helpNames from its immediate parent.
The helpNames is generated from `commandStack: [ParsableCommand.Type]`.
`getHelpNames()` extension method of `Array` is order sensitive and assumes that the element of `commandStack`  at indexed `i` is the parent of the element at indexed `i+1`
2021-01-15 23:53:39 -06:00
Elliott Williams c17e00a3bf Store mutations made by validate() (#239) 2020-09-18 11:55:07 -05:00
Nate Cook db24cb1275 Improve parsing performance (#234)
* Convert some linear operations to constant time

* Temporary test command for performance testing

* Improve SplitArguments docs

* Re-enable split arguments unit test

* Restore repeat example
2020-09-01 09:31:42 -05:00
Nate Cook 280700d361 Add completion script generation (#123)
Support for generating shell completion scripts for `ParsableCommand`
types, with customization points for `ExpressibleByArgument` types and
individual arguments and options. Zsh and Bash are supported in this
initial release.
2020-07-29 17:58:44 -05:00
Niccolò Fontana 2092075249 Add a precondition to prevent the parsing of a command that has itself as its subcommand (#197)
* Add a precondition to prevent the parsing of a command that has itself as its subcommand.

This avoids the infinite recursion that causes a crash and shows the user a meaningful error message.

Fixes: https://github.com/apple/swift-argument-parser/issues/192

* Fix the detection of a command that has itself as its subcommand

- The recursion detection now works for both the root command and its subcommands
- Add a test to shows that the fix works

* Fix typo in TreeTests
2020-06-29 14:53:49 -05:00
Nate Cook 1fa25574f8 Show option-based errors before unexpected positional errors (#187)
This pushes any errors indicated by unexpected arguments after parsing
out to the same late position. We were previously stopping immediately
when the command is a leaf node; that isn't necessary and created an
awkward second error path.
2020-06-15 14:32:36 -05:00
Nate Cook 8883f06b4e Don't consume the terminator during parsing. (#168)
Fixes #130.
2020-05-28 01:13:15 -05:00
ibrahim oktayandibrahim oktay ca89041e56 Fix showing help message when “-h” is given as an input for an array type argument (#149) (#166)
When argument is an array and no input is given but “-h”, if you throw an Error in Validate function, it prints error and short usage instead of help message.
This patch checks built-in flags before throwing a validation error.

Solves #149

Co-authored-by: ibrahim oktay <ibrahim.oktay@aktifbank.com.tr>
2020-05-27 17:05:47 -05:00
John Mueller 501bf60536 Display help when no arguments results in error (#140)
If a command cannot successfully run with zero arguments, print the error and the full help message instead of the short usage message.

This closes #134.
2020-05-14 09:08:19 -05:00
Kenny YorkandKenny York 42c9d4a02c Call validate on the entire command stack, instead of just the final subcommand (#104)
Co-authored-by: Kenny York <kenny_york@apple.com>
2020-04-08 13:00:57 -05:00
Nate Cook 31799bc1b4 Add built-in support for --version flag (#102)
* Add built-in support for --version flag

* Test that command-defined --version overrides the built-in.

* Document the `version:` parameter in CommandConfiguration

* Include --version in the generated help.
2020-03-30 12:36:21 -05:00
Nate Cook 72fb0b168c Enforce that options must be used by command before matching a subcommand (#96)
We were incorrectly skipping over dash-prefixed inputs when looking for the next
subcommand. This means that input like `command sub1 --foo sub2` would match the
sub1 and sub2 subcommands, even if `--foo` wasn't defined by sub1. This manifested
in issues where a value expected by `--foo` would be eaten by the subcommand matcher.

Fixes #92.
2020-03-22 13:27:13 -05:00
Nate Cook c526370906 Fix a missed parameter rename 2020-03-12 11:36:03 -05:00
Nate Cook ebb9a45751 Fix ParsableArguments sharing between cmds & subcommands (#78)
Previously, we were only storing full-decoded ParsableCommand instances
for subcommands to pick up with the @OptionGroup() wrapper. This change
stores all decoded @OptionGroup() values as well, so that they can be
shared from super- to subcommand.
2020-03-12 11:33:25 -05:00
Klaas Pieter Annema fd5b49c8dc Provide suggestions for unknown options (#10)
* Add String#editDistance(to:)

Uses levenshtein distance to determine how much two strings differ.

See: https://en.wikipedia.org/wiki/Levenshtein_distance

* Simplify unknownOptionMessage

The logic of Name#synopsisString was repeated in unknownOptionMessage.
This change sit so that unknownOptionMessage defer to Name's
implementation instead.

* Provide suggestions for unknown options
2020-03-02 11:21:03 -06:00
Wildchild9 6f58e68a6a Fixed Various Grammar & Spelling Mistakes (#17)
* Corrected grammatical and spelling errors in files in Documentation.

* Correct various spelling, grammar, and formatting mistakes in code documentation.
2020-03-02 10:54:10 -06:00
Nate Cook f6ac7b8118 Initial import of ArgumentParser 2020-02-27 15:45:22 -06:00