This blog post will teach you how to generate a manual page for your Swift command-line tool using Apple's swift-argument-parser. I will also teach you how to ensure that the man page will be installed along your command-line tool.
I'll use my command-line tool swiftplantuml
as a concrete example.
What is a man page
A man page (short for manual page) is a form of software documentation usually found on a Unix or Unix-like operating system. Topics covered include computer programs (including library and system calls), formal standards and conventions, and even abstract concepts. A user may invoke a man page by issuing the man command.
Example
Generate a man page
Apple's ArgumentParser
includes a SwiftPM plugin for generating man pages with version 1.1.4.
Make sure you are declaring 1.1.4 in your Package.swift
manifest as dependency:
dependencies: [
.package(
name: "swift-argument-parser",
url: "https://github.com/Apple/swift-argument-parser.git",
from: "1.1.4"
),
],
You can create a single main page including all subcommands:
swift package plugin generate-manual
Or you create multiple man pages, one per subcommand:
swift package plugin generate-manual --multi-page
The generated man page(s) can be found in folder .build/plugins/GenerateManualPlugin/outputs
When running the command for my command-line tool swiftplantuml
then the file swiftplantuml.1
gets generated in .build/plugins/GenerateManualPlugin/outputs/swiftplantuml
Viewing a man page
The man
command to view a man page will search in various directories.
man swiftplantuml
If the requested man page was not found then you will see a message like this:
No manual entry for swiftplantuml
Installing a man page
I recommend you copy the generated man page to /usr/local/share/man/man1/
as /usr/local/share/man
is part of the search path for man pages on Mac.
Note: You might have to create this directory. You can do so with mkdir -p /usr/local/share/man/man1
You can automate and make this step part of your tool installation.
For example, SwiftPlantUML offers a Makefile
which can be used by tools like Homebrew to streamline the installation process. In SwiftPlantUML's Makefile I install not only the tools binary but also the man page. Below I share a snippet out of my Makefile:
install-man-files: $(SOURCES)
mkdir -p ${DESTDIR}${mandir}/man1
cp $(REPODIR)/man/swiftplantuml.1 ${DESTDIR}${mandir}/man1/swiftplantuml.1
build-swiftplantuml: $(SOURCES)
@swift build \
-c release \
--disable-sandbox \
--build-path "$(BUILDDIR)"
.PHONY: install
install: build-swiftplantuml
@install -d "$(bindir)"
@install "$(wildcard $(BUILDDIR)/**/release/swiftplantuml)" "$(bindir)"
@make install-man-files
You may notice that I don't generate the man page with the SPM plugin during make install
. I previously generated and then checked-in the file, in a folder named man
, in Git. Why? Because I don't want to make Xcode 13.3 (= Swift 5.6 in which SPM introduced plugins) a requirement for installation.
I even revert to a dependency < 1.1.0 as ArgumentParser@1.1.0 and higher will require Swift 5.5. (Xcode 13 => macOS 11.3) and SwiftPlantUML shall be buildable from source from lower OS versions.
Man page vs help
You might ask: "What is the advantage of man pages over the generated help option?"
I raised the raise question in Swift Forums β¬οΈ
I leave you with the following answer:
Overall, man pages are simply the standard, conventional way of providing documentation for command line tools. Sticking to that convention makes your docs more easily accessible and useful, even if they have the same content as a --help.
Did you find this article valuable?
Support Marco Eidinger by becoming a sponsor. Any amount is appreciated!