apple / apple/swift-argument-parser

Proposal: Add allowedValues to Option and Argument, surface in --help

Open
#151 9 comments 3 reactions 0 assignees View on GitHub
enhancement
Dominant language
Swift
Stars
3.8k
Forks
411
Avg merge
7d 14h
Merged PRs (30d)
15

Description

## Problem Statement

Given the following command:

```swift
struct List: ParsableCommand {
private enum Filter: String, ExpressibleByArgument {
case all
case devices
case deviceTypes
case runtimes
case pairs
}

@Option(default: .all, help: "Allows filtering of list output.")
private var list: Filter
}
```

When I call `swift run list --help`, I only see the following:

```
OVERVIEW: Lists all simulator devices, device types, and runtimes available.

USAGE: list [--mode ]

OPTIONS:
--filter Allows filtering of specific list output. (default: all)
```

## Proposed Solution

We could add the property `allowedValues: [Value]?` to the `Option` and `Argument` property wrappers, simply referenced as `allowed` in the initializer. Based on the previous example, it could be declarable like so:

```swift
@Option(default: .all, allowed: [.all, .devices, .deviceTypes], help: "Allows filtering of list output.")
```

If `@Option` happens to be applied to value that implements `CaseIterable`, we could default to `.allCases` for the value as well if it is left `nil`. That would further simplify the declaration.

The output of `swift run list --help` would now look something like:

```
--filter Allows filtering of specific list output. (default: all) (allowed: devices, deviceTypes, pairs, runtimes)
```

Notice also that it excludes the default value, so as to reduce unnecessary detail. I'm not sure if doing so would have any negative effects. I'm not really sold on adding it to the end versus surfacing it some other way that commands might (simple array syntax, showing it under the option, etc.).

## Additional Thoughts

I'm torn on whether or not we should specifically validate against this list--my gut says that if someone wants that functionality, they could simple use an enum-backed `Option`. I would also find it beneficial to continue to have "secret" options available--the `allowedValues` are the ones shown to the user, but the _actual_ validated values are still triggered when the command is sent and handled.

Contributor guide

Open the contributing guide

Research direction

Start by reviewing the Option and Argument property wrappers and the help-generation path described in the issue. Resolve the proposed allowed-values API, CaseIterable behavior, default-value display, and validation semantics; done means the design is settled and help output reflects the agreed behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift
Domain
cli
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.