Skip to content

Generate labgrid-client subcommand and option documentation from argparse #1707

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

jonrebm
Copy link
Contributor

@jonrebm jonrebm commented Jul 25, 2025

Manage the documentation with sphinx and auto-document labgrid-client arguments and subcommands from source using sphinx-argparse.

Sections from the original man/labgrid-client.rst which are not obsoleted by the autogenerated reference are migrated into sphinx. Sphinx generates both the manpages as well as their html documentation counterpart.

I believe the result of this is much more useful than the current manpages we have that just don't sufficiently document usage of the subcommands.

See the readthedocs builds for results.

@jonrebm jonrebm marked this pull request as draft July 25, 2025 13:32
@jonrebm jonrebm force-pushed the argparse-manpage branch from 44cf057 to 4f7a030 Compare July 25, 2025 15:40
Copy link

codecov bot commented Jul 25, 2025

Codecov Report

❌ Patch coverage is 94.11765% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 55.6%. Comparing base (e380181) to head (d2f2131).
⚠️ Report is 10 commits behind head on master.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
labgrid/remote/client.py 94.1% 2 Missing ⚠️
Additional details and impacted files
@@          Coverage Diff           @@
##           master   #1707   +/-   ##
======================================
  Coverage    55.6%   55.6%           
======================================
  Files         172     172           
  Lines       13471   13477    +6     
======================================
+ Hits         7500    7506    +6     
  Misses       5971    5971           
Flag Coverage Δ
3.10 55.6% <94.1%> (+<0.1%) ⬆️
3.11 55.6% <94.1%> (+<0.1%) ⬆️
3.12 55.6% <94.1%> (+<0.1%) ⬆️
3.13 55.6% <94.1%> (+<0.1%) ⬆️
3.9 55.7% <94.1%> (+<0.1%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@jonrebm jonrebm force-pushed the argparse-manpage branch 5 times, most recently from 67059d8 to 148752f Compare July 28, 2025 15:12
@jonrebm jonrebm closed this Jul 28, 2025
@jonrebm jonrebm deleted the argparse-manpage branch July 28, 2025 15:13
@jonrebm jonrebm restored the argparse-manpage branch July 28, 2025 15:17
@jonrebm jonrebm reopened this Jul 28, 2025
@jonrebm jonrebm force-pushed the argparse-manpage branch from 148752f to d77c83d Compare July 28, 2025 15:18
@jonrebm jonrebm requested review from Emantor and jluebbe July 28, 2025 15:18
@jonrebm jonrebm marked this pull request as ready for review July 28, 2025 15:19
@jonrebm jonrebm force-pushed the argparse-manpage branch 2 times, most recently from 285f4f7 to fcd8e2f Compare July 28, 2025 20:31
jonrebm added 2 commits July 28, 2025 22:37
As sphinx supports generating manpages, use it to simplify the process
and drop the dependency on rst2man.

All manpages are now tracked in doc/man.

The Makefile in man/ remains for forward compatibility.

Stop tracking manpages themselves in troff format.

Signed-off-by: Jonas Rebmann <[email protected]>
This is an idiomatic way of setting up argument parsers and allows the
parser to be re-used for manpage/documentation generation.

Signed-off-by: Jonas Rebmann <[email protected]>
@jonrebm jonrebm force-pushed the argparse-manpage branch from fcd8e2f to 68e1a01 Compare July 28, 2025 20:46
@jonrebm jonrebm force-pushed the argparse-manpage branch 2 times, most recently from 6d1576b to af588b0 Compare July 29, 2025 12:53
@jonrebm jonrebm requested a review from Bastian-Krause July 29, 2025 13:36
@jonrebm jonrebm force-pushed the argparse-manpage branch from 42897f8 to 012df6b Compare July 29, 2025 13:58
@Bastian-Krause
Copy link
Member

Can we get rid of the "Default: " lines? Most of them are either misleading (expose internal implementation details) or redundant. Ideally the defaults should be part of the help strings where useful.

Here's what I mean:

labgrid-client
Labgrid is a scalable infrastructure and test architecture for embedded (linux) systems.

This is the client to control a boards status and interface with it on remote machines.

usage: labgrid-client [-h] [-x ADDRESS] [-c CONFIG] [-p PLACE] [-s STATE]
[-i INITIAL_STATE] [-d] [-v] [-P PROXY]
COMMAND ...
Named Arguments
-x, --coordinator
coordinator HOST[:PORT] (default: value from env variable LG_COORDINATOR, otherwise 127.0.0.1:20408)

-c, --config
env config file (default: value from env variable LG_ENV)

-p, --place
place name/alias (default: value from env variable LG_PLACE)

-s, --state
strategy state to switch into before command (default: value from env varibale LG_STATE)

-i, --initial-state
strategy state to force into before switching to desired state

-d, --debug
enable debug mode (show python tracebacks)

Default: False

Here.

-v, --verbose
Default: 0

Here.

-P, --proxy
proxy connections via given ssh host

Sub-commands
monitor
monitor events from the coordinator

labgrid-client monitor [-h]
resources (r)
list available resources

labgrid-client resources [-h] [-a] [-e EXPORTER]
[--sort-by-matched-place-change]
[match]
Positional Arguments
match
Named Arguments
-a, --acquired
Default: False

Here.

-e, --exporter
--sort-by-matched-place-change
sort by matched place’s changed date (oldest first) and show place and date

Default: False

Here.

places (p)
list available places

labgrid-client places [-h] [-a] [-r] [--sort-last-changed]
Named Arguments
-a, --acquired
Default: False

Here.

-r, --released
Default: False

Here.

--sort-last-changed
sort by last changed date (oldest first)

Default: False

Here.

who
list acquired places by user

labgrid-client who [-h] [-e]
Named Arguments
-e, --show-exporters
show exporters currently used by each place

Default: False

Here.

show
show a place and related resources

[...]

labgrid-client acquire [-h] [--allow-unmatched]
Named Arguments
--allow-unmatched
allow missing resources for matches when locking the place

Default: False

Here.

release (unlock)
release a place

labgrid-client release [-h] [-k]
Named Arguments
-k, --kick
release a place even if it is acquired by a different user

Default: False

Here.

[...]

labgrid-client console [-h] [-l] [-o] [--logfile FILE] [name]
Positional Arguments
name
optional resource name

Named Arguments
-l, --loop
keep trying to connect if the console is unavailable

Default: False

Here.

-o, --listenonly
do not modify local terminal, do not send input from stdin

Default: False

Here.

[...]

labgrid-client forward [-h] [--name NAME] [--local [LOCAL:]REMOTE]
[--remote REMOTE:LOCAL]
Named Arguments
--name, -n
optional resource name

--local, -L
Forward local port LOCAL to remote port REMOTE. If LOCAL is unspecified, an arbitrary port will be chosen

Default: []

Here.

--remote, -R
Forward remote port REMOTE to local port LOCAL

Default: []

Here.

[...]

write-files
copy files onto mass storage device

labgrid-client write-files [OPTION]... -T SOURCE DEST
labgrid-client write-files [OPTION]... [-t DIRECTORY] SOURCE...
Positional Arguments
SOURCE
source file(s) to copy

DEST
destination file name for SOURCE

Named Arguments
-w, --wait
storage poll timeout in seconds

Default: 10.0

-p, --partition
partition number to mount or 0 to mount whole disk (default: 1)

Default: 1

Redundant.

-t, --target-directory
copy all SOURCE files into DIRECTORY (default: partition root)

Default: /

Redundant.

-T
copy SOURCE file and rename to DEST

Default: False

Here.

--name, -n
optional resource name

write-image
write an image onto mass storage

labgrid-client write-image [-h] [-w WAIT] [-p PARTITION] [--skip SKIP]
[--seek SEEK] [--mode {dd,bmaptool}] [--name NAME]
filename
Positional Arguments
filename
filename to boot on the target

Named Arguments
-w, --wait
Default: 10.0

-p, --partition
partition number to write to

--skip
skip n 512-sized blocks at start of input

Default: 0

Here.

--seek
skip n 512-sized blocks at start of output

Default: 0

Here.

--mode
Possible choices: dd, bmaptool

Choose tool for writing images (default: dd)

Default: dd

Redundant.

--name, -n
optional resource name

reserve
create a reservation

labgrid-client reserve [-h] [--wait] [--shell] [--prio PRIO]
KEY=VALUE [KEY=VALUE ...]
Positional Arguments
KEY=VALUE
required tags

Named Arguments
--wait
wait until the reservation is allocated

Default: False

Here.

--shell
format output as shell variables

Default: False

Here.

--prio
priority relative to other reservations (default 0)

Default: 0.0

Redundant.

[...]

labgrid-client export [-h] [--format {shell,shell-export,json}] filename
Positional Arguments
filename
output filename

Named Arguments
--format
Possible choices: shell, shell-export, json

output format (default: shell-export)

Default: shell-export

Redundant.

version
show version

labgrid-client version [-h]

The old process was to manually duplicate information between the
argparse struct in labgrid/remote/client.py and man/labgrid-client.rst
which would then be translated to a manpage in man/labgrid-client.1
using rst2man and also tracked in version control.

The man/labgrid-client.rst file was also sourced in doc/man/client.rst
for sphinx to build html documentation of the labgrid-client cli
documentation.

Due to this duplication, labgrid-client command documentation was
incomplete and inconsistend with argparse documentation accessible via
the -h switch.

Use sphinx-argparse to generate usage info from the argparse struct
returned by get_parser() in labgrid/remote/client.py as part of
doc/man/client.rst. Move documentation missing from the argparse struct
from man/labgrid-client.1 to doc/man/client.rst. Generate both html cli
documentation as well as the manpage from that.

Future changes in subcommands and arguments of labgrid-client need only
be documented in the argparse struct but more expansive documentation
that includes markup can be added to the manpage, even to specific
subcommands via the rst in doc/man.

Signed-off-by: Jonas Rebmann <[email protected]>
jonrebm added 4 commits July 29, 2025 16:12
Doesn't look good if every Arguments list of every subcommand of every
command is listed here for the manpages generated from argparse.

Signed-off-by: Jonas Rebmann <[email protected]>
The subcommands descriptions for create, release-from and flashscript
had some extra details in the old rst manpages, not available in the
argparse/cli help. Migrate these descriptions from the old to the new
manpage by overwriting the subcommand descriptions.

Keep the argparse help texts short and concise.

Signed-off-by: Jonas Rebmann <[email protected]>
Hide intentionally undocumented subcommands and overlong lists of
choices.

PRs to fix the ineffective @Skip we have for those sections and to
display ranges properly are open and these workarounds should be removed
once the fixes made it into a release.

Signed-off-by: Jonas Rebmann <[email protected]>
Since the defaults are mentioned in the help text where they're
relevant, don't let sphinx-argparse print them again.

Signed-off-by: Jonas Rebmann <[email protected]>
@jonrebm jonrebm force-pushed the argparse-manpage branch from c02f952 to d2f2131 Compare July 29, 2025 14:12
@Bastian-Krause
Copy link
Member

One more observation: In "Named Arguments" there is no distinction between flags (e.g. -v, --verbose) and options expecting a value (e.g. -x, --coordinator). The usage contains these information. Is there an easy way of adding that?

@jonrebm
Copy link
Contributor Author

jonrebm commented Jul 30, 2025

@Bastian-Krause sadly, no. Generally I prefer the manpage format of autoprogram over that of sphinx-argparse, as it is more compact, idiomatic and does show option parameters:

LABGRID-CLIENT
usage: labgrid-client [-h] [-x ADDRESS] [-c CONFIG] [-p PLACE] [-s STATE] [-i INITIAL_STATE] [-d] [-v] [-P PROXY] COMMAND ...

-h, --help
        show this help message and exit

-x <address>, --coordinator <address>
        coordinator HOST[:PORT] (default: value from env variable LG_COORDINATOR, otherwise 127.0.0.1:20408)

We opted for sphinx-argparse for now in order to be able to replace subcommand descriptions. Maybe we keep an eye on progress of both alternatives.

That said, shpinx-argparse is fairly simple and it would be easy for us to add missing functionality at a later time if necessary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants