apple / apple/swift-argument-parser

Bug: Inconsistent visibility string interpolation in `generateHelpNames` for `.longWithSingleDash` vs `.long` names

Open Beginner friendly
#901 1 comment 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.