apple / apple/swift-argument-parser
Using `main` instead of `run` in subcommands leads to unexpected behavior
- Dominant language
- Swift
- Stars
- 3.8k
- Forks
- 411
- Avg merge
- 7d 14h
- Merged PRs (30d)
- 15
Description
When accidentally defining `main` instead of `run` in subcommands, no warning or error is shown, but the subcommand itself either displays a help message or swallows all arguments with no output.
**ArgumentParser version:** `1.2.0` and `1.3.0` or the `main` branch, for example.
**Swift version:** Apple Swift version 6.0-dev (LLVM ce41a43bba95b2b, Swift 1a840948a0905df), also reproducible with Swift 5.10.0 from Xcode 15.3.0
### Checklist
- [x] If possible, I've reproduced the issue using the `main` branch of this package
- [x] I've searched for [existing GitHub issues](https://github.com/apple/swift-argument-parser/issues)
### Steps to Reproduce
Build and run an executable that has only this code:
```swift
import ArgumentParser
@main
struct Entrypoint: ParsableCommand {
static let configuration = CommandConfiguration(
subcommands: [Client.self, Server.self]
)
}
struct Client: ParsableCommand {
static func main() throws {
print("Client!")
}
}
struct Server: ParsableCommand {
static func main() throws {
print("Server!")
}
}
```
### Expected behavior
I realize that I should've defined `run` instead of main, but defining `main` in `Entrypoint` does work, that function is called, albeit with no argument parsing done IIUC. The actual behavior for subcommands is unexpected. The default implementation of `ParsableCommand` and `AsyncParsableCommand` should at least issue a warning, if possible, that no custom implementaiton of `run` is provided. Otherwise it's very easy to spend a long time debugging this issue.
I'd assume this can also be a very frustrating experience for first-time users who try to convert their existing `@main` entrypoint to `ParsableCommand` but don't realize they have to rename `static func main()` to `func run()`.
### Actual behavior
When running `server` or `client` subcommands on their own, a help message is shown, but not other output is produced:
```
USAGE: entrypoint server
OPTIONS:
-h, --help Show help information.
```
When passing any arguments like `server foo bar`, no output is produced whatsoever.
Contributor guide
Research direction
Start by reproducing the minimal ParsableCommand example and then inspect the default behavior of ParsableCommand and AsyncParsableCommand when subcommands define main instead of run. Done means the mistaken implementation produces a clear warning or error rather than showing help or silently swallowing arguments.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100