apple / apple/swift-argument-parser
Bug: Inconsistent visibility string interpolation in `generateHelpNames` for `.longWithSingleDash` vs `.long` names
- Dominant language
- Swift
- Stars
- 3.8k
- Forks
- 411
- Avg merge
- 7d 13h
- Merged PRs (30d)
- 17
Description
## Bug Report
### Description
In `Sources/ArgumentParser/Usage/HelpGenerator.swift`, the `generateHelpNames(visibility:)` method on `NameSpecification` handles the `.long` and `.longWithSingleDash` cases inconsistently when generating non-default visibility help flag names.
**Affected file:** `Sources/ArgumentParser/Usage/HelpGenerator.swift`
### The Inconsistency
```swift
fileprivate func generateHelpNames(visibility: ArgumentVisibility) -> [Name] {
self
.makeNames(InputKey(name: "help", parent: nil))
.compactMap { name in
guard visibility.base != .default else { return name }
switch name {
case .long(let helpName):
return .long("\(helpName)-\(visibility.base)") // ✅ uses visibility.base
case .longWithSingleDash(let helpName):
return .longWithSingleDash("\(helpName)-\(visibility)") // ❌ uses visibility (full), not visibility.base
case .short:
return nil
}
}
.sorted(by: >)
}
```
- The `.long` case correctly appends `visibility.base` (e.g., `"hidden"`)
- The `.longWithSingleDash` case appends the full `visibility` description instead of `visibility.base`
This means if a command uses single-dash long names (e.g., `-help`), the generated hidden/private help flag name would be different from what the double-dash variant generates, causing **inconsistent CLI behavior** where `-help-hidden` does not behave the same as `--help-hidden`.
### Steps to Reproduce
1. Create a command that uses `.longWithSingleDash` in its `helpNames` configuration
2. Call the command with a non-default visibility help flag
3. Observe the appended suffix differs from the `.long` variant
### Expected Behavior
Both `.long` and `.longWithSingleDash` cases should use `visibility.base` for consistent flag name generation:
```swift
case .longWithSingleDash(let helpName):
return .longWithSingleDash("\(helpName)-\(visibility.base)") // ✅ fix: use .base
```
### Environment
- **swift-argument-parser version:** main branch (commit `af51a49`)
- **Swift version:** 5.9+
- **Platform:** All platforms
### Impact
Low-to-medium. Affects only commands that configure `helpNames` with `.longWithSingleDash` at non-default visibility levels, but the inconsistency is a latent bug that could surface in toolchains and developer tools built on top of this library.
---
*Reported after manual code review of `HelpGenerator.swift`.*
Contributor guide
Research direction
Start in Sources/ArgumentParser/Usage/HelpGenerator.swift at NameSpecification.generateHelpNames(visibility:) and compare the .long and .longWithSingleDash branches. Verify the non-default visibility reproduction described in the issue, then confirm both generated names use the same visibility-base suffix for consistent help flag behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 1/5
- Estimated time
- Under an hour
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 75/100