2022-02-04 12:23:53 -03:00
#!/usr/bin/env python3
# Copyright (c) 2022 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
import os
import subprocess
import sys
import tempfile
2024-11-14 01:15:00 -03:00
import argparse
2022-02-04 12:23:53 -03:00
BINARIES = [
' src/bitcoind ' ,
' src/bitcoin-cli ' ,
' src/bitcoin-tx ' ,
' src/bitcoin-wallet ' ,
' src/bitcoin-util ' ,
' src/qt/bitcoin-qt ' ,
]
2024-11-14 01:15:00 -03:00
parser = argparse . ArgumentParser (
formatter_class = argparse . RawDescriptionHelpFormatter ,
)
parser . add_argument (
" -s " ,
" --skip-missing-binaries " ,
action = " store_true " ,
default = False ,
help = " skip generation for binaries that are not found in the build path " ,
)
args = parser . parse_args ( )
2022-02-04 12:23:53 -03:00
# Paths to external utilities.
git = os . getenv ( ' GIT ' , ' git ' )
help2man = os . getenv ( ' HELP2MAN ' , ' help2man ' )
# If not otherwise specified, get top directory from git.
topdir = os . getenv ( ' TOPDIR ' )
if not topdir :
2023-01-17 17:46:35 -03:00
r = subprocess . run ( [ git , ' rev-parse ' , ' --show-toplevel ' ] , stdout = subprocess . PIPE , check = True , text = True )
2022-02-04 12:23:53 -03:00
topdir = r . stdout . rstrip ( )
# Get input and output directories.
builddir = os . getenv ( ' BUILDDIR ' , topdir )
mandir = os . getenv ( ' MANDIR ' , os . path . join ( topdir , ' doc/man ' ) )
# Verify that all the required binaries are usable, and extract copyright
# message in a first pass.
versions = [ ]
for relpath in BINARIES :
abspath = os . path . join ( builddir , relpath )
try :
2023-01-17 17:46:35 -03:00
r = subprocess . run ( [ abspath , " --version " ] , stdout = subprocess . PIPE , check = True , text = True )
2022-02-04 12:23:53 -03:00
except IOError :
2024-11-14 01:15:00 -03:00
if ( args . skip_missing_binaries ) :
print ( f ' { abspath } not found or not an executable. Skipping... ' , file = sys . stderr )
continue
else :
print ( f ' { abspath } not found or not an executable ' , file = sys . stderr )
sys . exit ( 1 )
2022-02-04 12:23:53 -03:00
# take first line (which must contain version)
2022-02-21 11:18:59 -03:00
verstr = r . stdout . splitlines ( ) [ 0 ]
2022-02-04 12:23:53 -03:00
# last word of line is the actual version e.g. v22.99.0-5c6b3d5b3508
verstr = verstr . split ( ) [ - 1 ]
assert verstr . startswith ( ' v ' )
2022-02-21 11:18:59 -03:00
# remaining lines are copyright
copyright = r . stdout . split ( ' \n ' ) [ 1 : ]
assert copyright [ 0 ] . startswith ( ' Copyright (C) ' )
2022-02-04 12:23:53 -03:00
2022-02-21 11:18:59 -03:00
versions . append ( ( abspath , verstr , copyright ) )
2022-02-04 12:23:53 -03:00
2024-11-26 21:35:50 -03:00
if not versions :
print ( f ' No binaries found in { builddir } . Please ensure the binaries are present in { builddir } , or set another build path using the BUILDDIR env variable. ' )
sys . exit ( 1 )
2022-02-21 11:18:59 -03:00
if any ( verstr . endswith ( ' -dirty ' ) for ( _ , verstr , _ ) in versions ) :
2022-02-04 12:23:53 -03:00
print ( " WARNING: Binaries were built from a dirty tree. " )
print ( ' man pages generated from dirty binaries should NOT be committed. ' )
print ( ' To properly generate man pages, please commit your changes (or discard them), rebuild, then run this script again. ' )
print ( )
with tempfile . NamedTemporaryFile ( ' w ' , suffix = ' .h2m ' ) as footer :
# Create copyright footer, and write it to a temporary include file.
2022-02-21 11:18:59 -03:00
# Copyright is the same for all binaries, so just use the first.
2022-02-04 12:23:53 -03:00
footer . write ( ' [COPYRIGHT] \n ' )
2022-02-21 11:18:59 -03:00
footer . write ( ' \n ' . join ( versions [ 0 ] [ 2 ] ) . strip ( ) )
2024-03-07 08:27:07 -03:00
# Create SEE ALSO section
footer . write ( ' \n [SEE ALSO] \n ' )
footer . write ( ' , ' . join ( s . rpartition ( ' / ' ) [ 2 ] + ' (1) ' for s in BINARIES ) )
footer . write ( ' \n ' )
2022-02-04 12:23:53 -03:00
footer . flush ( )
# Call the binaries through help2man to produce a manual page for each of them.
2022-02-21 11:18:59 -03:00
for ( abspath , verstr , _ ) in versions :
2022-02-04 12:23:53 -03:00
outname = os . path . join ( mandir , os . path . basename ( abspath ) + ' .1 ' )
print ( f ' Generating { outname } … ' )
subprocess . run ( [ help2man , ' -N ' , ' --version-string= ' + verstr , ' --include= ' + footer . name , ' -o ' , outname , abspath ] , check = True )