96 Commits
Author SHA1 Message Date
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 b551ec8c04 Add completion kind and help command to ToolInfo (#697)
Updates ToolInfo to include the built-in `help` subcommand and also
include details on each argument's completion method if any.
2025-02-06 08:55:56 -08:00
Rauhul Varma 25db036b71 Refactor serialization of dump help descriptions (#693)
Cleans up some lingering odds and ends from #647. Specifically switches
CommandInfoV0 to use the old style description and updates
ArgumentInfoV0 to emit value descriptions as a separate dictionary.
2025-02-04 17:04:42 -08:00
Joseph Heck 72bf21248f extend ToolInfoV0 with command visibility (#669)
- resolves https://github.com/apple/swift-argument-parser/issues/668
  by extending the ToolInfoV0 (help dump) struct to include visibility
  information for commands (already exists for arguments).
- updates test output to verify existing examples extend with the
  additional key.
2024-10-07 13:03:07 -05:00
Bri Peticca 83c5134a24 Add ability to provide descriptions for CaseEnumerable @Option values (#647)
Since `ExpressibleByArgument` already maintains a list of
enumerable values for an argument, we can extend this to serve
as an ordered list for a new dictionary property that maps the
value name to its description, if applicable. The new property
is a static variable on `ExpressibleByArgument` labelled
`allValueDescriptions`.

If the description string for a value is the same as the value
string, it's assumed that the description is not implemented.

The new value strings are used in the help screen, in the 
dump-help JSON output, and in the generated manual.
2024-09-30 14:17:48 -05:00
Doug Gregor 516c2f80f7 Introduce subcommand grouping into the command configuration to improve help (#644)
* Introduce subcommand grouping into the command configuration to improve help

Add optional support for grouping subcommands into named groups, to
help bring order to commands with many subcommands without requiring
additional structure. For example, here's the help for a
"subgroupings" command that has an ungrouped subcommand (m), and two
groups of subcommands ("broken" and "complicated").

    USAGE: subgroupings <subcommand>

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

    SUBCOMMANDS:
      m

    BROKEN SUBCOMMANDS:
      foo                     Perform some foo
      bar                     Perform bar operations

    COMPLICATED SUBCOMMANDS:
      n

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

To be able freely mix subcommands and subcommand groups, CommandConfiguration
has a new initializer that takes a result builder. The help output
above is created like this:

    struct WithSubgroups: ParsableCommand {
      static let configuration = CommandConfiguration(
        commandName: "subgroupings"
      ) {
        CommandGroup(name: "Broken") {
          Foo.self
          Bar.self
        }

        M.self

        CommandGroup(name: "Complicated") {
          N.self
        }
      }
    }

Each `CommandGroup` names a new group and is given commands (there are
no groups within groups). The other entries are arbitrary
ParsableCommands.

This structure is only cosmetic, and only affects help generation by
providing more structure for the reader. It doesn't impact existing
clients, who can still reason about the flattened list of subcommands
if they prefer.

* Add an optional abstract to command groups

* Expand subcommand group result builders to handle all result-builder syntax

Adds support for if, if-else, if #available, and for..in loops.

* Revert "Add an optional abstract to command groups"

This reverts commit ab563a22c0.

* Eliminate result builders in favor of a second "groupedSubcommands" array

Introduce subcommand groups with a more modest extension to the API that
adds another array of subcommand groups alongside the (ungrouped)
subcommands array. We can consider introducing result builders as a
separate step later, if there's more to be gained from it.

* Drop the (ungrouped) "subcommands" heading when there are none.
2024-06-04 14:33:42 -07: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
Cœur 1c8215f18a Prefer let for private configurations (#617) 2024-02-28 11:29:01 -06:00
Keith Smiley c4138099b4 Remove @_implementationOnly annotations (#616)
These annotations produce warnings when compiling swift-syntax without library evolution using Swift ≥5.10.

Replace them by `private import` when compiling using Swift ≥5.11.

Mirrors https://github.com/apple/swift-syntax/pull/2429
2024-02-24 13:12:52 -06:00
Nate Cook ac615d40c2 Workarounds for remaining concurrency warnings (#601) 2023-11-18 22:05:20 -06:00
Lev Walkin 511a72aea8 Add Sendable conformance (#582)
This change adds conditional `Sendable` conformance to all
property wrapper types when their `Value` is `Sendable`, enabling
commands to be used in concurrent contexts. Some notes on
the implementation:

* Fix flag exclusivity issues

This derives the `hasUpdated` check from the parsed values data type,
rather than storing it in the closure (which breaks sendability) or
passing it through the closure invocation (which wasn't finished
enough to actually work).

* Mark all `transform` methods as `@Sendable`

This allows for a stronger, compiler-supported guarantee of
sendability when a compound `ParsableArguments` or `ParsableCommand`
type is marked `Sendable`. Most transformations shouldn't be a
problem, since the general case is that these are pure string ->
value transformations.

In cases where making such a transformation sendable is impossible,
an author can always change the property to be just a string and
perform the transformation within the context of the command's
execution, in either the `run()` or `validate()` methods.

* Add `@preconcurrency` to Sendable closure APIs

This adds the `@preconcurrency` attribute to all public APIs that
have changed to take a `@Sendable` closure. This will ease the
migration path for sendable adoption for ArgumentParser users, since
a warning will only appear for using these APIs (like the `transform`
parameter in an @Option or @Argument) once they've turned on strict
concurrency checking.

I'm also backing out changes that avoided those warnings in the tests
and examples, since in most cases those warnings are spurious;
unapplied functions don't capture state. See
https://forums.swift.org/t/pitch-inferring-sendable-for-methods-and-key-path-literals/68011
for more on this and hopefully an upcoming fix for these issues.

* Raise minimum Swift version to 5.7

In order to provide `@preconcurrency` support, the package needs to
have a minimum Swift requirement of 5.7. This makes that change and
updates the README to indicate this for the next version.
2023-11-17 10:06:47 -06:00
Gwynne Raskind c10af98655 Respect the COLUMNS and LINES environment variables when present (#596)
* Respect the `COLUMNS` and `LINES` environment variables, if set, when determining screen size.
* Add test for COLUMNS environment override
* Make columns test idempotent against there being a COLUMNS value already set in the environment
* Make help tests be more explicit about screen widths.
2023-11-14 21:17:06 -08:00
Rauhul Varma 75dae3dfd0 Display possible option values in help (#594)
Updates HelpGenerator to print possible value options as a suffix to the
user defined help string. In practice this looks like:

> Set diagnostic level to report public declarations without an
> availability attribute. (values: error, warn, ignore; default: warn)
2023-11-14 09:30:31 -08:00
Rauhul Varma e2dd9edaa7 Rename allValues to allValueStrings (#593)
Renames an internal property of argument parser to simplify tracking
values through the code base. Should have no functional changes.
2023-11-07 13:35:42 -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
Tiago Lopes 3b6f81459b Fix .postTerminator usage message (#542)
* Fix synopsis for .postTerminator parsing strategy

* Add test for .postTerminator usage message generation
2023-01-13 08:23:44 -06:00
Rauhul Varma e7f312e06e Cleanup Foundation usage (#528)
- Changes uses of import Foundation in ArgumentParser to only expose the
  symbols needed to avoid growing unintentional dependencies.
- Replaces direct usage of EXIT_FAILURE in MessageInfo with ExitCode,
  exposed as a result of the above change.
2022-11-21 22:27:42 -08:00
Nate Cook 3d6df7cf37 [NFC] Sequester platform-specific code (#504) 2022-10-10 17:50:20 -05:00
Nate Cook b80fb05f45 Add API for titling an option group (#492)
This change lets you provide a title for option groups, which is used
when generating the help screen. Titled option groups, when they exist,
are placed between the ARGUMENTS and OPTIONS section of the help.
Multiple option groups with the same title are coalesced into a single
group.

For example, this command declaration:

    struct Extras: ParsableArguments {
      @Flag(help: "Print extra output while processing.")
      var verbose: Bool = false

      @Flag(help: "Include details no one asked for.")
      var oversharing: Bool = false
    }

    @main
    struct Example: ParsableCommand {
      @OptionGroup(title: "Extras")
      var extras: Extras

      @Argument var name: String?
      @Option var title: String?
    }

yields this help screen:

    USAGE: example [--verbose] [--oversharing] [<name>] [--title <title>]

    ARGUMENTS:
      <name>

    EXTRAS:
      --verbose               Print extra output while processing.
      --oversharing           Include details no one asked for.

    OPTIONS:
      --title <title>
      -h, --help              Show help information.
2022-09-26 18:47:40 -05: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
Rauhul Varma 607021b737 Unify @Argument and @Option initialization paths (#477)
- Fixes #466.
- Adds initializers to ArgumentDefinition generic over a Container type.
  The Container type must conform to a new internal protocol
  ArgumentDefinitionContainer which describes functionality like default
  set of help options for the argument defined by the property wrapper,
  etc.
- Adds overloads for Optional @Arguments and @Options with default
  values which emit deprecation warning to guide users towards using the
  non-Optional versions.
2022-09-10 18:40:31 -05:00
Rauhul Varma f1c6afd175 Fixup help options for built-in flags (#474)
- Fixes a bug where built-in flags such as --help and --version were not
  properly marked with isOptional which resulted in them appearing in
  generated content (such as completion scripts and manuals) as required
  arguments.
2022-08-26 00:13:12 -07:00
Nate Cook 4de228195c Show hidden args/opts/flags with --help-hidden (#412)
- Make ArgumentSet(_:visibility:) filter correctly
  The ArgumentSet initializer was previously only filtering out option
  groups with visibility lower than requested. With this change, the
  resulting ArgumentSet only includes values that are valid for display.
  In addition, this moves the visibility parameter out of
  UsageGenerator.synopsis(); that type needs to have the correct
  visibility level at initialization.

- Mark non-parsed properties as private
  This applies to properties that are defined without a property
  wrapper. This kind of property should never be included in the help,
  since they aren't included in the command-line tool's UI.
2022-02-15 14:57:43 -06:00
Rauhul Varma 88af18f986 Change ArgumentVisibility into a struct (#413)
- Changes ArgumentVisibility from an enum to a struct. This will allow
  ArgumentParser to add cases in the future without breaking clients
  that could have been exhaustively switching across all cases. It also
  allows us to implement protocol conformances on the internal type and
  avoid exposing them on the public type.
2022-02-15 12:55:27 -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 e344426b07 Add documentation comments to generateHelpNames (#411) 2022-02-14 13:17:06 -06:00
Rauhul Varma e3673688cf Add abillity to generate hidden help (#410)
- Updates helpMessage(columns:) and helpMessage(for:columns:) with an
  includeHidden argument defaulted to false to allow for clients to
  programmatically generate hidden help.
2022-02-12 16:11:07 -08: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
Rauhul Varma 1e6cf8bf25 Forward ArgumentVisibility to ArgumentDefinition (#406)
- Renames ArgumentHelp.Visibility to ArgumentVisibility.
- Replaces ArgumentDefinition.shouldDisplay with a visibility property
  whose value is derived from ArgumentHelp.visibility.
2022-02-12 00:54:20 -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 5540737e97 Add customization point for command usage text (#400) 2022-02-11 13:41:27 -06:00
Matt Zanchelli 9e14482156 Correct Typos (#388) 2022-01-11 16:47:13 -06:00
Rauhul Varma 00a86771ca Clean up help generation (#385)
- Adds check to ensure that `wrapped(to:wrappingIndent:)` doesn't
  attempt to retrieve a negative prefix.
- The Usage struct was composed of an array of strings which always
  contained exact one string at runtime. This struct has been removed
  and replaced with a single usage string.
- Removes HelpGenerator._screenWidthOverride in favor of explicitly
  setting the screen width in generateHelp calls.
2022-01-10 16:02:50 -06:00
Rauhul Varma df75d7009e Fix dump help crash (#387)
- Fixes #375
- Fixes a bug with the experimental dump help generator which would
  occur when a ParsableCommand has non-Argument properties.
2022-01-10 15:58:49 -06:00
Rauhul Varma 020800d75c Handle failures getting terminal size on windows (#386)
- Fixes #369
- Adds an error check for the return value of GetConsoleScreenBufferInfo
  Windows. If GetConsoleScreenBufferInfo a default size of 80 by 25 is
  used.
2022-01-10 15:18:52 -06:00
yonihemi cca8f80939 Add SwiftWasm support (#363) 2022-01-06 09:56:44 -06:00
Daniel Duan 90f76c14b4 List valid options in error messages (#382)
When an option value fails to parse, no custom error message is
provided, and a list of valid candidate values is available, include the
list as part of the error message.

Addresses #344.
2022-01-05 11:02:31 -06:00
Yi Xie afe0b9588e Fix compile failure on iOS for Mac Catalyst support (#356)
* Fix compile failure on iOS

* Add sortedKeys API check for tvOS and watchOS
2021-09-13 16:24:33 -05: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
Rauhul Varma b3bef58985 Improvements to --dump-help (#335)
- Removes `HelpInfo` in favor of a recursively defined `CommandInfo`
  which contains more raw metadata about the source command.
  Additionally, introduces a top level `ToolInfo` type with a
  serialization version to aid future tooling.

- Updates tests to match the new serialized format.

- Renames `DumpHelpInfoGenerator` to `DumpHelpGenerator` to align the
  type with the `--dump-help` flag.
2021-08-26 14:21:45 -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
Gonzalo RH 530a754555 Included help message when a required value is missing. (#324) 2021-06-09 11:28:00 -05:00
Rauhul Varma f4353dbe3a Simplify synopsis string generation (#316)
- Removes unused codepaths.
- Simplifies synopsis string codepaths by removing optionality. This
  complexity is moved to the caller who is now responsible for filtering
  out hidden arguments and options. This change is desirable as it
  allows the caller to determine if the argument should be hidden. For
  example, while it makes sense to hide arguments in help text, it may
  not make sense to hide them when dumping the arguments for another
  tool to consume.
2021-05-22 10:59:37 -05:00
Rauhul Varma 860afdad31 Clean up internal property nesting (#315)
- Removes one layer of help properties by directly including the members
  of ArgumentHelp in ArgumentDefinition.Help. This also results in the
  discussion field which previously existed in both structures, now
  having a single source of truth. Adds helper method for setting each
  of these members using an instance of ArgumentHelp. Makes previously
  optional Strings into plain Strings and updates points of use to check
  for the empty string case.
2021-05-20 19:03:19 -05:00
Nate Cook 992a7451d5 Convert all public enums to structs (#299) 2021-05-15 10:30:48 -05:00
Nate Cook 167704f261 Ignore extra help flags when given with the 'help' subcommand (#309) 2021-05-14 17:28:32 -05:00
Nate Cook 267f707294 Use custom help flags in completion scripts (#308)
* Standardize the help and version flag generation
* Simplify some help generation code
* Support custom help flags in completion scripts
2021-05-14 10:27:05 -05:00