praiskup / argparse-manpage

Automatically build man-pages for your Python project
Apache License 2.0
40 stars 22 forks source link

Manpages are not reproducible #26

Closed eli-schwartz closed 2 years ago

eli-schwartz commented 4 years ago

optparse.HelpFormatter is set up with width=None, thus causing optparse to produce output which guesses at the $COLUMNS of the current terminal. The resulting manpages might look something like this:

--- man-old/dsidm.8 2020-05-21 16:34:15.301597779 -0400
+++ man-new/dsidm.8 2020-05-21 16:34:48.441852944 -0400
@@ -38,7 +38,9 @@
 Manage generic roles, with tasks
 like modify, locking and unlocking.
 .SH OPTIONS 'dsidm account'
-usage: dsidm instance account [-h] {list,get-by-dn,modify-by-dn,delete,lock,unlock,entry-status,subtree-status,reset_password,change_password} ...
+usage: dsidm instance account [-h]
+                              {list,get-by-dn,modify-by-dn,delete,lock,unlock,entry-status,subtree-status,reset_password,change_password}
+                              ...

 .SS
 \fBSub-commands\fR
@@ -133,7 +135,9 @@
 Print more account policy details about the entry

 .SH OPTIONS 'dsidm account subtree-status'
-usage: dsidm instance account subtree-status [-h] [-V] [-f FILTER] [-s {one,sub}] [-i] [-o BECOME_INACTIVE_ON] basedn
+usage: dsidm instance account subtree-status [-h] [-V] [-f FILTER] [-s {one,sub}] [-i]
+                                             [-o BECOME_INACTIVE_ON]
+                                             basedn

 .TP
 \fBbasedn\fR
@@ -189,7 +193,8 @@

 .SH OPTIONS 'dsidm group'
-usage: dsidm instance group [-h] {list,get,get_dn,create,delete,modify,members,add_member,remove_member} ...
+usage: dsidm instance group [-h]
+                            {list,get,get_dn,create,delete,modify,members,add_member,remove_member} ...

 .SS
 \fBSub-commands\fR
@@ -514,7 +519,8 @@

 .SH OPTIONS 'dsidm user create'
-usage: dsidm instance user create [-h] [--uid [UID]] [--cn [CN]] [--displayName [DISPLAYNAME]] [--uidNumber [UIDNUMBER]] [--gidNumber [GIDNUMBER]]
+usage: dsidm instance user create [-h] [--uid [UID]] [--cn [CN]] [--displayName [DISPLAYNAME]]
+                                  [--uidNumber [UIDNUMBER]] [--gidNumber [GIDNUMBER]]
                                   [--homeDirectory [HOMEDIRECTORY]]

@@ -621,7 +627,9 @@

 .SH OPTIONS 'dsidm role'
-usage: dsidm instance role [-h] {list,get-by-dn,modify-by-dn,delete,lock,unlock,entry-status,subtree-status} ...
+usage: dsidm instance role [-h]
+                           {list,get-by-dn,modify-by-dn,delete,lock,unlock,entry-status,subtree-status}
+                           ...

 .SS
 \fBSub-commands\fR

Every rebuild of the manpages might produce a completely different binary artifact, based simply on the size of the terminal the build was done in.

See https://reproducible-builds.org/ for why this matters.

...

Please set the width to one value which is used everywhere. Manpage troff formatting codes don't need to respect terminal width.

eli-schwartz commented 4 years ago

I do not understand what optparse is doing! but changing this locally did not fix things for me actually... only running setup.py build_manpages with $COLUMNS set. o_0 Maybe this just needs to be exported to os.environ

praiskup commented 4 years ago

Good idea, thanks for the report! I can see that argparse respects COLUMNS env var... so we just need to set it at appropriate time. Patches are welcome!

mgorny commented 2 years ago

Hit this one today too.

praiskup commented 2 years ago

Can anyone take a look at writing the patch? What would be the default number for COLUMNS?

praiskup commented 2 years ago

This happens because we use the built-in ArgparseManpage parsers's "format_usage()". It would be ideal to built the usage string from scratch, with colors - env agnostic.

https://github.com/praiskup/argparse-manpage/blob/22506de87adc13bb82bca36c50b6d416bdbb6582/build_manpages/manpage.py#L140

praiskup commented 2 years ago

Hopefully fixed, or worked-around by 456bc2db7501be582ba8ca7eda4e5d6e15527cdc