apple / apple/swift-argument-parser

Passing state from root to subcommands

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

Description

Working on a tool with a handful of subcommands, I find myself wanting to handle common work in the root command, and then pass some state to the subcommand. I’m not sure what might be possible, but something like this is what I’d like to be able to do:

```bash
% raise3d --addr 192.168.1.23 monitor --notify
```

```swift
@main
struct RootCommand : AsyncParsableCommand {
static
var
configuration = CommandConfiguration(commandName: "raise3d",
abstract: "A utility to interact witih Raise3D printers.",
subcommands: [Monitor.self])

@Option(help: "The printer’s local address.")
var addr: String

@Option(help: "The printer’s password.")
var password: String?

mutating
func run() async throws -> Raise3DAPI {
let password = self.password ?? { /* prompt user for password */ }()
let api = Raise3DAPI(host: self.options.addr, password: self.options.password)
try await api.login()
return api
}
}

struct Monitor : AsyncParsableCommand {
static
var configuration = CommandConfiguration(commandName: "monitor",
abstract: "Monitor the printer and optionally notify of errors.")

@Option(help: "Notify if error.")
var notify: Bool = false

mutating
func run(state inAPI: Raise3DAPI) async throws
{
while (true) {
let jobInfo = try await inAPI.getJobInfo()

if self.notify && jobInfo.status == .error {
// Send notification
}

Task.sleep(for: .seconds(1))
}
}
}

class Raise3DAPI
{
// …
}
```

This lets subcommands be a little cleaner, because they don't have to redundantly declare the global options, and all the common work is done in the parent command. The desired state is generic.

Contributor guide

Open the contributing guide

Research direction

Start with the AsyncParsableCommand declarations and the parent and subcommand run methods shown in the issue, then inspect how command execution currently passes context. Done means a generic mechanism lets the root command perform setup and provide resulting state to subcommands without redeclaring global options; no tests or files are named in the issue.

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
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.