# Generate a man page for a Swift command-line tool

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`](https://github.com/MarcoEidinger/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

![manual page for swiftplantuml](https://user-images.githubusercontent.com/4176826/187481252-d6100a7c-1f6e-4589-9361-c4ab3cca4e42.png)

# Generate a man page

Apple's [`ArgumentParser`](https://github.com/apple/swift-argument-parser) includes a SwiftPM plugin for generating man pages with **version 1.1.4**.

%[https://github.com/apple/swift-argument-parser/releases/tag/1.1.4]

Make sure you are declaring 1.1.4 in your `Package.swift` manifest as dependency:

``` Swift
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`](https://github.com/MarcoEidinger/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:

```text
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](https://github.com/MarcoEidinger/SwiftPlantUML/blob/main/Makefile) I install not only the tools binary but also the man page. Below I share a snippet out of my Makefile:

```text
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 ⬇️

%[https://forums.swift.org/t/when-to-use-swiftpm-plugin-for-generating-man-pages/59010]

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.



