Swift package --generate-manual - Bad output

I noticed that the "Man page" tab of the "ArgumentParser in use" section of the Swift.org page contains an error. This is important because this page should be perfect. It is Swift's "hello world".

If you copy the content of the "Man page" tab, paste it in a file, and open the file with man, you see this:

The last two lines before EXIT STATUS should not be there. Repeat has no subcommands.

[I] release> ./repeat -h
USAGE: repeat [--count <count>] [--include-counter] <phrase>

ARGUMENTS:
  <phrase>                The phrase to repeat.

OPTIONS:
  --count <count>         How many times to repeat 'phrase'.
  --include-counter       Include a counter with each repetition.
  -h, --help              Show help information.

Also, it appears that the JSON output has a corresponding error. (Perhaps this is why the man page is bad).

I made a separate package for SAP's repeat example and ran swift package generate-manual to see if this had been fixed. It's still a bug:

[I] repeat> cat ./repeat.1
.\" "Generated by swift-argument-parser"
.Dd February 21, 2026
.Dt REPEAT 1
.Os
.Sh NAME
.Nm repeat
.Sh SYNOPSIS
.Nm
.Ar subcommand
.Op Fl -count Ar count
.Op Fl -include-counter
.Ar phrase
.Op Fl -help
.Sh DESCRIPTION
.Bl -tag -width 6n
.It Fl -count Ar count
How many times to repeat 'phrase'.
.It Fl -include-counter
Include a counter with each repetition.
.It Ar phrase
The phrase to repeat.
.It Fl h , -help
Show help information.
.It Em help
Show subcommand help information.
.Bl -tag -width 6n
.It Ar subcommands...
.El
.El
.Sh "EXIT STATUS"
.Ex -std⏎                  

Have you filed an issue with the repository? This is great detail, and that's the ideal place to capture it. Sounds like this even might be a great "good first issue" kind of report.

2 Likes

That "subcommands..." field is the argument to the built-in mycommand help subcommand.

This is a place where I haven't been happy with the current man generation, and what you're seeing is "working as intended" where what should be intended is up for debate :sweat_smile:.

Another thing I haven't been happy with is that we emit -h --help and --version at every level of the command hierarchy in the man page.

If you have a better idea on how the man page should represent this, i'm fairly confident implementing it should be straightforward.

1 Like

Interesting - I didn't know that the repeat example provided by SAP had a built-in help command. But then again, the ParsableCommand protocol has a plethora of features. That
said, I ran the following, and contrary to what the generated man page said, this did not show help info:

[I] release> ./repeat help
help
help

IMO, there is no room for debate. That help line should not be there. If you insist, then the help screen should also show a help command. The help screen and manual page should not contradict each other.

The plug-in has two cases:

  • default - all the commands are recursively shown with all options in one man page
  • multi-page - each command in the hierarch has its own man page

I tried both with SAP's math example.

Default

At the bottom we have help shown as a command at the proper level.

Here I would suggest leaving the first line and dropping the last three. The last three are incorrect because they suggests that help has subcommands and that help has a version flag.

As an aside, personally, I greatly prefer multi-page because the hierarchy can get really messy, especially if you have a lot of text in the description sections, or have example sections, etc. If all you have is list of the options - then fine.

Multi-page

Here is the top level in muti-page mode. It looks really good.

I would, however, suggest that you show the subcommands, with a short description somewhere on the man page. (I would keep the SEE ALSO section as is). E.g., like the help screen.

[I] release> ./math --help
OVERVIEW: A utility for performing maths.

USAGE: math <subcommand>

OPTIONS:
  --version               Show the version.
  -h, --help              Show help information.

SUBCOMMANDS:
  add (default)           Print the sum of the values.
  multiply, mul           Print the product of the values.
  stats                   Calculate descriptive statistics.

  See 'math help <subcommand>' for detailed help.

The man page should just say what the tool does. If the tool, line SAP's math example, has --help and --version at each level. the so should the man page. If it doesn't (i.e., version string is empty in the configuration at given level)
, then neither should the man page. As far as I can tell you have this just right already.

I agree, especially when the command hierarchy is viewed as a single program. That program should only have a version flag at the top level. I am ok with --help at each level .

Here is an example of how a manual page can show its subcommands. I thought it might be helpful when you fix Argument Parser's manual page generator plug-in.

First, for context, the help screen:

Parent Help Screen
> calpm -h
DESCRIPTION
  Initialize and install packages that depend on cmd-arg-lib.

USAGE
  calpm [-fzmtvh] <subcommand>

OPTIONS
  -f/--generate-fish-completion-script   Print a fish completion script (for calpm).
  -z/--generate-zsh-completion-script    Print a zsh completion script (for calpm).
  -m/--generate-manpage                  Generate a manual page.
  -t/--tree                              Show the command tree.
  -v/--version                           Show the version.
  -h/--help                              Show this help screen.

SUBCOMMANDS
  init      Initialize a new package.
  install   Install executable products.

Here is the corresponding manual page.

Parent Manual Page

Apologies for the tiny print, manual pages are meant to be viewed using, say less, not crammed onto a single page.

Just for the record, here is the help screen for the init subcommand. It has a --help option and does not have a --version option.

Subcommand Help Screen
> calpm init -h
DESCRIPTION
  Initialize a package with an executable product.

USAGE
  calpm init [-chm] [-d <directory>] [-n <product_name>] -t <template>

OPTIONS
  -m/--minimize               Populate the template with less example parameters.
  -d/--directory <directory>  The directory that will contain the package (default: the current directory).
  -n/--name <product_name>    The name of the product (default: the package name, lowercased and snaked).
  -t/--template <template>    The template to use.
  -c/--with-completion        Add shell completion script generation for zsh and fish.
  --generate-manpage          Generate a manpage (for calpm init).
  -h/--help                   Show this help screen.

TEMPLATES
  opaque                      A product without a help screen.
  basic                       A product with a help screen.
  testing                     A product with unit testing.
  manpage                     A product with a manual page.
  simple-tree                 A product with commands and subcommands.
  stateful-tree               A product with stateful commands and subcommands.

NOTES
  The package name is the last component of the specified directory's path.

  If <directory> is specified and does not exist, it will be created.

  The "manpage", "simple-tree" and "stateful-tree" templates are always populated.

Here is the subcommand's manual page.

Subcommand Manual Page

If you would like to try out generating the help screens and manual pages and/or see how they are laid out in code, you can download Command Argument Library Package Manager. If you do, it is recommended that you take a look at Command Argument Library which is the library used by Command Argument Library Package Manager.