BusKill / buskill-app

BusKill's main CLI/GUI app for arming/disarming/configuring the BusKill laptop kill cord
https://www.buskill.in
GNU General Public License v3.0
152 stars 22 forks source link

Write man page #48

Closed maltfield closed 1 year ago

maltfield commented 1 year ago

This ticket will track the effort to write a manpage for the BusKill app that will be displayed when running man buskill on *nix systems.

This is a prerequisite to getting BusKill added to the official Debian repos in #31

maltfield commented 1 year ago

The example given by @fmarier was this repo they hand-wrote for the pip-check-reqs package:

The format it's written-in is called "Nroff"

The GNU tool for parsing nroff files is "Groff"

maltfield commented 1 year ago

I poked around on a Debian system and found the man page for bzip2 in /usr/share/man/man1/

user@buskill:~$ zcat /usr/share/man/man1/bzip2.1.gz | head -n30
.TH bzip2 1
.SH NAME
bzip2, bunzip2 \- a block-sorting file compressor, v1.0.8
.br
bzcat \- decompresses files to stdout
.br
bzip2recover \- recovers data from damaged bzip2 files

.SH SYNOPSIS
.ll +8
.B bzip2
.RB [ " \-cdfkqstvzVL123456789 " ]
[
.I "filenames \&..."
]
.br
.B bzip2
.RB [ " \-h|\-\-help " ]
.ll -8
.br
.B bunzip2
.RB [ " \-fkvsVL " ]
[
.I "filenames \&..."
]
.br
.B bunzip2
.RB [ " \-h|\-\-help " ]
.br
.B bzcat
user@buskill:~$

I couldn't get it to be rendered using groff, but I found that if I use groffer then it magically opens the man page in evince (like a PDF)

user@buskill:~$ groffer /usr/share/man/man1/bzip2.1.gz
user@buskill:~$

woah, groffer has some awesome output modes!

       groffer mode options

               [--auto] [--default] [--default-modes mode1,mode2,...] [--dvi] [--groff] [--html] [--latin1]
               [--mode display_mode] [--pdf] [--pdf2] [--ps] [--source] [--text] [--to-stdout] [--tty] [--utf8]
               [--viewer prog] [--www] [--xhtml] [--x | --X]

Here's the 'text' mode

user@buskill:~$ groffer --text /usr/share/man/man1/bzip2.1.gz | head -n30
bzip2(1)                    General Commands Manual                   bzip2(1)

NAME
       bzip2, bunzip2 - a block-sorting file compressor, v1.0.8
       bzcat - decompresses files to stdout
       bzip2recover - recovers data from damaged bzip2 files

SYNOPSIS
       bzip2 [ -cdfkqstvzVL123456789 ] [ filenames ...  ]
       bzip2 [ -h|--help ]
       bunzip2 [ -fkvsVL ] [ filenames ...  ]
       bunzip2 [ -h|--help ]
       bzcat [ -s ] [ filenames ...  ]
       bzcat [ -h|--help ]
       bzip2recover filename

DESCRIPTION
       bzip2  compresses  files  using  the Burrows-Wheeler block sorting text
       compression algorithm, and Huffman coding.   Compression  is  generally
       considerably   better   than   that   achieved   by  more  conventional
       LZ77/LZ78-based compressors, and approaches the performance of the  PPM
       family of statistical compressors.

       The  command-line options are deliberately very similar to those of GNU
       gzip, but they are not identical.

user@buskill:~$

Anyway, so this is pretty dope. But what's the best way to actually write a man page?

There's pandoc that converts between many different input & output formats (eg csv, epub, html, json, latex, markdown, mediawiki, man, odt, rst, etc) https://pandoc.org/MANUAL.html

(It also looks like Kramdown can convert markdown to roff)

This is probably not what I want, but I was able to convert my existing .rst documentation to the man page format. Here's the source

user@buskill:~$ pandoc sandbox/buskill-app/docs/software_usr/cli.rst -s -t man | head -n30
.\" Automatically generated by Pandoc 2.9.2.1
.\"
.TH "BusKill App: Command-Line Interface" "" "" "" ""
.hy
.PP
This page will describe how to use the BusKill app in CLI mode.
.PP
To control BusKill via the CLI, use the same executable with arguments
(executing \f[C]buskill\f[R] without arguments opens it in GUI mode).
.SH Help
.PP
You can print a list of allowable arguments by passing the
\f[C]buskill\f[R] app \f[C]-h\f[R] or \f[C]--help\f[R]
.IP
.nf
\f[C]
user\[at]disp2781:\[ti]/Downloads/dist$ ./buskill.AppImage --help
\&...
usage: buskill [-h] [--version] [--list-triggers] [-v] [-t] [-T] [-a] [-U]

App for arming and configuring BusKill. For help, see https://docs.buskill.in

optional arguments:
  -h, --help         show this help message and exit
  --version          print version and exit.
  --list-triggers    List all available triggers.
  -v, --verbose      increase output verbosity
  -t , --trigger     Choose trigger to execute. See --list-triggers for all
                     possible values.
  -T, --run-trigger  Immediately execute the trigger on start
user@buskill:~$

And here's it rendered with man

user@buskill:~$ pandoc sandbox/buskill-app/docs/software_usr/cli.rst -s -t man | /usr/bin/man -l - | head -n30
BusKill App: Command-Line Interface()                                          BusKill App: Command-Line Interface()

       This page will describe how to use the BusKill app in CLI mode.

       To  control  BusKill via the CLI, use the same executable with arguments (executing buskill without arguments
       opens it in GUI mode).

Help
       You can print a list of allowable arguments by passing the buskill app -h or --help

              user@disp2781:~/Downloads/dist$ ./buskill.AppImage --help
              ...
              usage: buskill [-h] [--version] [--list-triggers] [-v] [-t] [-T] [-a] [-U]

              App for arming and configuring BusKill. For help, see https://docs.buskill.in

              optional arguments:
                -h, --help         show this help message and exit
                --version          print version and exit.
                --list-triggers    List all available triggers.
                -v, --verbose      increase output verbosity
                -t , --trigger     Choose trigger to execute. See --list-triggers for all
                                   possible values.
                -T, --run-trigger  Immediately execute the trigger on start
                -a, --arm          Arms BusKill
                -U, --upgrade      Download & upgrade latest version of BusKill
              user@disp2781:~/Downloads/dist$

Arming
       To arm BusKill, execute it with the -a or --arm argument
user@buskill:~$
fmarier commented 1 year ago

Sorry, I should have mentioned this too in my original note. There's a very easy way to render your man page (assuming it's called buskill.1):

man ./buskill.1
maltfield commented 1 year ago

Thanks :) I'm currently just trying to figure out the best-practice of:

  1. Where to store the manpage in this repo
  2. Whether to store it in this repo in [a] native-manpage's groff format or [b] reStructuredText like the rest of this project's documentation (and convert to groff format at build-time) or [c] some other pythonic best-practice for dynamically producing the manpage at build time
maltfield commented 1 year ago

I spent some time looking at other projects to see how they build and where they store their man pages

maltfield commented 1 year ago

I think the best short-term solution is to manually write our own man page in a .rst file somewhere in our docs/ directory. That way:

  1. We can include the man page in our sphinx documentation, similar to how we do with LICENSE
  2. We can use pandoc to spit-out the man-page in groff format, while keeping all this project's docs in rst format

A couple things I'm not currently going to do, but things we should consider long-term:

  1. We could probably autogenerate sections of the man page directly from our sourcecode, such as the arguments section. But I'll skip that for now..
  2. We should automatically produce/update a buskill.1 file in groff-format that lives in this repo as part of the CI pipeline

Note: the file "extension" .1 is used because it's the manpage for the general "user". Here's the different types of manpages (excerpt taken from man man)

       1   Executable programs or shell commands
       2   System calls (functions provided by the kernel)
       3   Library calls (functions within program libraries)
       4   Special files (usually found in /dev)
       5   File formats and conventions, e.g. /etc/passwd
       6   Games
       7   Miscellaneous (including macro packages and conventions),  e.g.  man(7),
           groff(7)
       8   System administration commands (usually only for root)
       9   Kernel routines [Non standard]
maltfield commented 1 year ago

Here's some examples of some .rst (source files written in reStructuredText) that are used to generate manpages in groff-format

  1. https://gist.github.com/rlaager/0881883d66b45fae9cc145fa92203c69
  2. https://docutils.sourceforge.io/sandbox/manpage-writer/rst2man.txt
maltfield commented 1 year ago

See also https://en.wikipedia.org/wiki/Comparison_of_documentation_generators

I guess the most common method of auto-generating manpages from the sample of other FOSS projects above was to use Doxygen

maltfield commented 1 year ago

See also:

maltfield commented 1 year ago

I created a new branch named manpage where this work is taking place:

fmarier commented 1 year ago

This is some pretty in-depth research! It would almost be worth putting into a blog post so that it doesn't disappear into the issue tracker :)

maltfield commented 1 year ago

I managed to fix the issue where pandoc spat-out the groff file without the .TH section by merely adding the -s = --standalone to its execution. Now I get the desired start/end on the first-line, but it's still missing the short description in the middle for some reason.

user@buskill:~$ head -n10 sandbox/buskill-app/docs/software_usr/manpage.rst
.. _manpage:

============
 buskill(1)
============

-------------------------------------------------------------------------
Lock or shutdown if your device is stolen (for use with laptop kill cord)
-------------------------------------------------------------------------

user@buskill:~$ 
...
user@buskill:~$ pandoc -s sandbox/buskill-app/docs/software_usr/manpage.rst -t man | groffer --text | head -n10
buskill(1)                                                          buskill(1)

SYNOPSIS
              buskill --trigger soft-shutdown --arm

DESCRIPTION
       buskill  is  a cross-platform CLI and GUI app that can lock or shutdown
       your computer when a USB hotplug removal event occurs.
user@buskill:~$ 

See also https://stackoverflow.com/questions/74776173/how-to-set-all-arguments-of-the-title-line-in-manpage-written-in-restructuredtex

maltfield commented 1 year ago

From the pandoc manual, I found that you could ouput the "template" for the man output as follows

user@buskill:~$ pandoc -D man
$if(has-tables)$
.\"t
$endif$
$if(pandoc-version)$
.\" Automatically generated by Pandoc $pandoc-version$
.\"
$endif$
$if(adjusting)$
.ad $adjusting$
$endif$
.TH "$title/nowrap$" "$section/nowrap$" "$date/nowrap$" "$footer/nowrap$" "$header/nowrap$"
$if(hyphenate)$
.hy
$else$
.nh
$endif$
$for(header-includes)$
$header-includes$
$endfor$
$for(include-before)$
$include-before$
$endfor$
$body$
$for(include-after)$
$include-after$
$endfor$
$if(author)$
.SH AUTHORS
$for(author)$$author$$sep$; $endfor$.
$endif$
user@buskill:~$ 
maltfield commented 1 year ago

To add all the variable to populate the manpage template via pandoc, I had to specify some variables directly on the command-line when doing the conversion between the .rst file to the groff file.

So I hacked-up a simple script to wrap this command:

maltfield commented 1 year ago

I've merged the manpage branch into dev, so it's now possible to create this project's manpage with the following commands

git clone https://github.com/BusKill/buskill-app.git
cd buskill-app
git checkout dev
docs/buildManpage.sh
man ./docs/buskill.1

I've confirmed this to be working on Debian 11. Here's an example execution

user@disp8329:~$ cat /etc/issue
Debian GNU/Linux 11 \n \l

user@disp8329:~$ git clone https://github.com/BusKill/buskill-app.git
Cloning into 'buskill-app'...
remote: Enumerating objects: 6422, done.
remote: Counting objects: 100% (647/647), done.
remote: Compressing objects: 100% (147/147), done.
remote: Total 6422 (delta 494), reused 635 (delta 487), pack-reused 5775
Receiving objects: 100% (6422/6422), 214.32 MiB | 2.36 MiB/s, done.
Resolving deltas: 100% (3655/3655), done.
user@disp8329:~$ 
user@disp8329:~$ cd buskill-app
user@disp8329:~/buskill-app$ 
user@disp8329:~/buskill-app$ git checkout dev
Branch 'dev' set up to track remote branch 'dev' from 'origin'.
Switched to a new branch 'dev'
user@disp8329:~/buskill-app$ 

user@disp8329:~/buskill-app$ docs/buildManpage.sh
++ which sudo
+ SUDO=/usr/bin/sudo
+ pwd
/home/user/buskill-app
+ env
SHELL=/bin/bash
QT_ACCESSIBILITY=1
COLORTERM=truecolor
GNOME_DESKTOP_SESSION_ID=c1
VMTYPE=AppVM
SSH_AUTH_SOCK=/tmp/ssh-DIoDTrHdLrT1/agent.973
QREXEC_AGENT_PID=11203
SSH_AGENT_PID=1039
XDG_SEAT=seat0
PWD=/home/user/buskill-app
LOGNAME=user
XDG_SESSION_TYPE=x11
GPG_AGENT_INFO=/run/user/1000/gnupg/S.gpg-agent:0:1
QREXEC_REQUESTED_TARGET_TYPE=
WINDOWPATH=7
HOME=/home/user
LANG=en_US.UTF-8
_JAVA_AWT_WM_NONREPARENTING=1
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:
VTE_VERSION=6203
QREXEC_SERVICE_FULL_NAME=qubes.StartApp+qubes-run-terminal
GNOME_TERMINAL_SCREEN=/org/gnome/Terminal/screen/bc59e1c6_55c1_45cc_944a_8f241d4c3635
QREXEC_SERVICE_ARGUMENT=qubes-run-terminal
UPDTYPE=NonUpdateableVM
XDG_SESSION_CLASS=user
TERM=xterm-256color
QUBES_ENV_SOURCED=1
QREXEC_REMOTE_DOMAIN=dom0
USER=user
GNOME_TERMINAL_SERVICE=:1.22
DISPLAY=:0
SHLVL=3
XDG_VTNR=7
XDG_SESSION_ID=c1
XDG_RUNTIME_DIR=/run/user/1000
XDG_DATA_DIRS=/home/user/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share
PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
QT_X11_NO_MITSHM=1
OLDPWD=/home/user
_=/usr/bin/env
+ ls -lah
total 172K
drwxr-xr-x  8 user user 4.0K Dec 12 19:52 .
drwx------ 17 user user 4.0K Dec 12 19:50 ..
drwxr-xr-x  7 user user 4.0K Dec 12 19:52 build
-rw-r--r--  1 user user  957 Dec 12 19:52 CHANGELOG
drwxr-xr-x 13 user user 4.0K Dec 12 19:59 docs
drwxr-xr-x  8 user user 4.0K Dec 12 19:59 .git
drwxr-xr-x  4 user user 4.0K Dec 12 19:52 .github
-rw-r--r--  1 user user   40 Dec 12 19:52 .gitignore
-rw-r--r--  1 user user  86K Dec 12 19:52 KEYS
-rw-r--r--  1 user user  35K Dec 12 19:52 LICENSE
-rw-r--r--  1 user user 4.2K Dec 12 19:52 README.md
drwxr-xr-x  5 user user 4.0K Dec 12 19:52 src
drwxr-xr-x  3 user user 4.0K Dec 12 19:52 updates
++ git log -1 --pretty=%ct
+ export SOURCE_DATE_EPOCH=1670896703
+ SOURCE_DATE_EPOCH=1670896703
++ date '+%b %Y' --date=@1670896703
+ DATE='Dec 2022'
+ HEADER='Laptop Kill Cord'
++ pwd
++ basename docs/buildManpage.sh
+ '[' '!' -e /home/user/buskill-app/docs/buildManpage.sh ']'
+ /usr/bin/sudo apt-get update
Hit:1 https://deb.debian.org/debian bullseye InRelease                               
Hit:2 https://deb.qubes-os.org/r4.1/vm bullseye InRelease                            
Get:3 https://deb.debian.org/debian-security bullseye-security InRelease [48.4 kB]
Get:4 https://deb.debian.org/debian-security bullseye-security/main amd64 Packages [210 kB]
Get:5 https://deb.debian.org/debian-security bullseye-security/main Translation-en [136 kB]
Fetched 394 kB in 2s (232 kB/s)     
Reading package lists... Done
+ /usr/bin/sudo apt-get -y install pandoc
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages were automatically installed and are no longer required:
  ethtool libbotan-2-17 libtspi1 linux-image-5.10.0-10-amd64
  linux-image-5.10.0-13-amd64 linux-image-5.10.0-14-amd64
  linux-image-5.10.0-15-amd64 linux-image-5.10.0-16-amd64
  linux-image-5.10.0-17-amd64 net-tools sse3-support
Use 'sudo apt autoremove' to remove them.
The following additional packages will be installed:
  libcmark-gfm-extensions0 libcmark-gfm0 pandoc-data
Suggested packages:
  texlive-xetex texlive-luatex pandoc-citeproc context wkhtmltopdf ghc nodejs php
  python r-base-core libjs-mathjax node-katex citation-style-language-styles
The following NEW packages will be installed:
  libcmark-gfm-extensions0 libcmark-gfm0 pandoc pandoc-data
0 upgraded, 4 newly installed, 0 to remove and 17 not upgraded.
Need to get 19.0 MB of archives.
After this operation, 157 MB of additional disk space will be used.
Get:1 https://deb.debian.org/debian bullseye/main amd64 libcmark-gfm0 amd64 0.29.0.gfm.0-6 [117 kB]
Get:2 https://deb.debian.org/debian bullseye/main amd64 libcmark-gfm-extensions0 amd64 0.29.0.gfm.0-6 [46.1 kB]
Get:3 https://deb.debian.org/debian bullseye/main amd64 pandoc-data all 2.9.2.1-1 [376 kB]
Get:4 https://deb.debian.org/debian bullseye/main amd64 pandoc amd64 2.9.2.1-1+b1 [18.5 MB]
Fetched 19.0 MB in 5s (4,013 kB/s) 
Selecting previously unselected package libcmark-gfm0:amd64.
(Reading database ... 405423 files and directories currently installed.)
Preparing to unpack .../libcmark-gfm0_0.29.0.gfm.0-6_amd64.deb ...
Unpacking libcmark-gfm0:amd64 (0.29.0.gfm.0-6) ...
Selecting previously unselected package libcmark-gfm-extensions0:amd64.
Preparing to unpack .../libcmark-gfm-extensions0_0.29.0.gfm.0-6_amd64.deb ...
Unpacking libcmark-gfm-extensions0:amd64 (0.29.0.gfm.0-6) ...
Selecting previously unselected package pandoc-data.
Preparing to unpack .../pandoc-data_2.9.2.1-1_all.deb ...
Unpacking pandoc-data (2.9.2.1-1) ...
Selecting previously unselected package pandoc.
Preparing to unpack .../pandoc_2.9.2.1-1+b1_amd64.deb ...
Unpacking pandoc (2.9.2.1-1+b1) ...
Setting up libcmark-gfm0:amd64 (0.29.0.gfm.0-6) ...
Setting up pandoc-data (2.9.2.1-1) ...
Setting up libcmark-gfm-extensions0:amd64 (0.29.0.gfm.0-6) ...
Setting up pandoc (2.9.2.1-1+b1) ...
Processing triggers for man-db (2.9.4-2) ...
Processing triggers for libc-bin (2.31-13+deb11u4) ...
Scanning processes...                                                                 
Scanning linux images...                                                              

No services need to be restarted.

No containers need to be restarted.

No user sessions are running outdated binaries.
++ which pandoc
+ PANDOC=/usr/bin/pandoc
+ /usr/bin/pandoc -s -t man --variable 'header=Laptop Kill Cord' --variable 'date=Dec 2022' --variable footer= docs/software_usr/manpage.rst -o docs/buskill.1
+ exit 0
user@disp8329:~/buskill-app$ 

user@disp8329:~/buskill-app$ man docs/buskill.1 
user@disp8329:~/buskill-app$
maltfield commented 1 year ago

@fmarier can you please confirm if this man page meet's Debian's needs?

.\" Automatically generated by Pandoc 2.9.2.1
.\"
.TH "buskill" "1" "Dec 2022" "" "Laptop Kill Cord"
.hy
.SH NAME
.PP
buskill - Lock or shutdown if your device is stolen (for use with laptop
kill cord)
.SH SYNOPSIS
.PP
buskill [options]
.SH DESCRIPTION
.PP
buskill is a cross-platform CLI and GUI app that can lock or shutdown
your computer when a USB hotplug removal event occurs.
.PP
It\[aq]s designed to work with the BusKill laptop kill cord, which is a
hardware dead man switch that tethers a user to their computer via a USB
cable with an integrated magnetic breakaway.
If the cable is disconnected (eg by a snatch-and-run thief stealing the
user\[aq]s machine), then this software can trigger the computer to lock
or shutdown -- thus protecting encrypted files (eg bitcoin private keys)
or current login sessions (eg online banking) from theft.
.SH OPTIONS
.IP
.nf
\f[C]
-h, --help         show this help message and exit
--version          print version and exit.
--list-triggers    List all available triggers.
-v, --verbose      increase output verbosity
-t , --trigger     Choose trigger to execute. See --list-triggers for all
                   possible values.
-T, --run-trigger  Immediately execute the trigger on start
-a, --arm          Arms BusKill
\f[R]
.fi
.SH EXAMPLES
.PP
\f[B]buskill --list-triggers\f[R] : Display all possible triggers, then
exits.
.PP
\f[B]buskill --trigger lock-screen --arm\f[R] : Arm the buskill app with
the \[aq]lock-screen\[aq] trigger so that a USB hotplug removal event
will lock the device\[aq]s screen
.PP
\f[B]buskill --trigger soft-shutdown --arm\f[R] : Arm the buskill app
with the \[aq]soft-shutdown\[aq] trigger so that a USB hotplug removal
event will cause the device to shutdown
.SH SEE ALSO
.PP
This manpage is limited in scope.
The BusKill project\[aq]s main documentation (complete with images and
videos) is available at docs.buskill.in (https://docs.buskill.in)
.IP \[bu] 2
Full Documentation (https://docs.buskill.in)
.IP \[bu] 2
Official BusKill Project Website (https://buskill.in)
.SH AUTHORS
Michael Altfield (<michael@michaelaltfield.net>) and The BusKill Team
(<https://buskill.in/contact>).
fmarier commented 1 year ago

@maltfield That looks good to me.

I filed https://github.com/BusKill/buskill-app/pull/50 for a few nits, but even without it would be good.

maltfield commented 1 year ago

Merged PR #50. Thank you!

I'm marking this ticket as complete, and now #31 is unblocked.

fmarier commented 1 year ago

Just to add to your list of manpage resources, here's a very good guide I had forgotten about: https://liw.fi/manpages/