I recently ran into this same problem as well, and for anyone looking for help, here's what worked for me:
The main command struct:
@main struct Cosmic: AsyncParsableCommand {
static var configuration = CommandConfiguration(
abstract: "A package manager for macOS.",
subcommands: [Setup.self, Add.self])
struct Options: ParsableArguments {
@Flag(name: [.long, .customShort("v")]) var verbose: Bool = false
}
}
The subcommand structure:
extension Cosmic {
struct Setup: AsyncParsableCommand {
static var configuration = CommandConfiguration(abstract: "Setup the Cosmic package manager.")
@OptionGroup var options: Cosmic.Options
...
}
}
Constructing a command manually somewhere:
@Test("Set up Cosmic")
func setUpCosmic() async throws {
var setupCommand = Cosmic.Setup()
setupCommand.options = try .parse(["--verbose"])
...
}
The root cause is as @natecook1000 mentioned in this thread on GitHub, - automatically-generated empty initializers for subcommands do not provide an initial value for these OptionGroups. Therefore, we must set them, and I think the most straightforward way to do that is the parse function, not an initializer.