From 084a3da5ce5295fe3566f7788e957c5d16b004d5 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Sun, 17 Mar 2024 08:25:33 -0600 Subject: Give more control to docs build [skip appveyor] The documentation build can now selectively disable doing the APIdocs build (which is slow, and requires Sphinx and some extensions to be installed); and skip building pdf versions of docs (which requires fop or equivalent to be installed). Both can be disabled by using a csv: scons doc SKIP_DOCS=pdf,api TODO: pdf disabling is only partly working. It does not build the pdf version of the api docs, but does build pdf manpages and user guide. The latter are not "installed": there is no build/doc/PDF, but there are pdfs in the build directory, build/doc/man and build/doc/user. This is part two of the doc build change (begun in #4492) Signed-off-by: Mats Wichmann --- CHANGES.txt | 3 + RELEASE.txt | 3 + doc/SConscript | 152 +++++++++++++++++++++++++++-------------- site_scons/BuildCommandLine.py | 4 +- 4 files changed, 109 insertions(+), 53 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index c4aea7f..9f9a5ac 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -111,6 +111,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER Sphinx build. - Add locking around creation of CacheDir config file. Fixes #4489. - Clarify MergeFlags usage of a dict argument. + - SCons documentation build can now be controlled through SKIP_DOC + variable - rather than just true/false can now specifiy + skip none, skip all, skip pdf docs, skip api docs. RELEASE 4.6.0 - Sun, 19 Nov 2023 17:22:20 -0700 diff --git a/RELEASE.txt b/RELEASE.txt index 5c68970..1fd72d8 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -88,6 +88,9 @@ PACKAGING --------- - Remove unecessary dependencies on pypi packages from setup.cfg +- SCons documentation build can now be controlled through SKIP_DOC + variable - rather than just true/false can now specifiy + skip none, skip all, skip pdf docs, skip api docs. DOCUMENTATION ------------- diff --git a/doc/SConscript b/doc/SConscript index 60831bc..29f2bbf 100644 --- a/doc/SConscript +++ b/doc/SConscript @@ -35,43 +35,78 @@ import SCons.Util Import('command_line', 'env', 'whereis', 'revaction') +# Check prerequisites and flags for building the documentation. There are +# several combinations in play. Conceptually there are five builds: +# - manpage and user guide output in html (and manpage in roff-style "source") +# - manpage and user guide output in pdf +# - API docs with Sphinx output in html +# - API docs with Sphinx output in pdf +# - Bundle up the built bits into the tarball for upload to the website. # -# -- Check prerequisites for building the documentation --- +# These are sometimes a bit in tension. For example, we shouldn't need any +# doc bits to build the wheel for testing or uploading, except that the +# manpages (.1 format) are built and dropped into the top directory for +# use by distribution packagers - even though that's not really a suitable +# place for them. And since we're often building the wheel to make a release, +# we actually may end up wanting the docs anyway. # -skip_doc = False - -try: - import SConsDoc - import SConsExamples -except ImportError as exc: - print("doc: SConsDoc failed to import, the error was:") - print(f" ImportError: {exc}") - print(" Please make sure that python-lxml is installed.") - skip_doc = True - -fop = whereis('fop') -xep = whereis('xep') - -if not fop and not xep: - print("doc: No PDF renderer found (fop|xep)!") - skip_doc = True - -skip_doc_arg = ARGUMENTS.get('SKIP_DOC') -if skip_doc_arg is not None: - skip_doc = skip_doc_arg in ['True', '1', 'true'] +# We want to be able to have some choice in combinations, so that for example +# there's a command to build just the manpages for distros without having +# to have the whole fop (for pdf) and Sphinx (for API docs) chains setup +# just to do a successful build, since those won't be part of those +# packages anyway. + +skip_doc_build = False +skip_pdf_build = False +skip_api_build = False + +# SKIP_DOC is a csv with various options. It doesn't seem necessary +# to do a very sophisticated decode of it, but could add that later. +skip_doc_args = ARGUMENTS.get('SKIP_DOC', 'none').split(',') +if 'none' not in skip_doc_args: + if 'all' in skip_doc_args: + skip_doc_build = skip_pdf_build = skip_api_build = True + if 'api' in skip_doc_args: + skip_api_build = True + if 'pdf' in skip_doc_args: + skip_pdf_build = True + +if not skip_doc_build: + try: + import SConsDoc + import SConsExamples + except ImportError as exc: + print("doc: SConsDoc failed to import, the error was:") + print(f" ImportError: {exc}") + print(" Please make sure the Python lxml package is installed.") + print(" Skipping documentation build.") + skip_doc_build = skip_pdf_build = skip_api_build = True + +if not skip_pdf_build: + fop = whereis('fop') + xep = whereis('xep') + + if not fop and not xep: + print("doc: No PDF renderer found (fop|xep)!") + print(" Skipping PDF generation.") + skip_pdf_build = True + +if not skip_api_build: + ctx = env.Configure() + sphinx = ctx.CheckProg("sphinx-build") + if sphinx is None: + print("doc: Configure did not find sphinx-build") + print(" Skipping API docs generation.") + skip_api_build = True + ctx.Finish() # # --- Configure build # -env = env.Clone() - build = os.path.join(command_line.build_dir, 'doc') - gs = whereis('gs') lynx = whereis('lynx') - dist_doc_tar_gz = '$DISTDIR/scons-doc-${VERSION}.tar.gz' - tar_deps = [] tar_list = [] @@ -105,7 +140,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. man_page_list = ['scons.1', 'scons-time.1', 'sconsign.1'] # Template for the MAN page texts when we can't properly -# create them because the skip_doc flag is set (required +# create them because the skip_doc_build flag is set (required # modules/tools aren't installed in the current system) man_replace_tpl = r""".TH "%(uctitle)s" "1" "%(today)s" "SCons %(version)s" "SCons %(version)s" .ie \n(.g .ds Aq \(aq @@ -121,7 +156,7 @@ update the system and try running the build again. # # --- Processing --- # -if skip_doc: +if skip_doc_build: print("doc: ...skipping building User Guide.") print(" ...creating fake MAN pages.") @@ -138,6 +173,7 @@ if skip_doc: version = env.subst('$VERSION') for m in man_page_list: man, _ = os.path.splitext(m) + # TODO: add these to Alias? with open(os.path.join(scdir, m), "w") as fman: fman.write( man_replace_tpl @@ -158,6 +194,7 @@ else: # Always create a version.xml file containing the version information # for this run. Ignore it for dependency purposes so we don't # rebuild all the docs every time just because the date changes. + # TODO: couldn't we use Textfile + Ignore? date, ver, rev, copyright_years = env.Dictionary( 'DATE', 'VERSION', 'REVISION', 'COPYRIGHT_YEARS' ) @@ -439,16 +476,18 @@ else: sctargets.append( env.File(os.path.join(scdir, f'scons-{doc}', 'index.html')) ) - if 'pdf' in targets: + if 'pdf' in targets and not skip_pdf_build: sctargets.append(env.File(os.path.join(scdir, f'scons-{doc}.pdf'))) if 'epub' in targets: sctargets.append(env.File(os.path.join(scdir, f'scons-{doc}.epub'))) if 'man' in targets: for m in man_page_list: + # TODO: add targets to an alias? sctargets.append(os.path.join(scdir, m)) man, _1 = os.path.splitext(m) - sctargets.append(os.path.join(scdir, f'scons-{man}.pdf')) + if not skip_pdf_build: + sctargets.append(os.path.join(scdir, f'scons-{man}.pdf')) sctargets.append(os.path.join(scdir, f'scons-{man}.html')) nodes.extend( @@ -489,13 +528,13 @@ else: target=env.File(html), source=env.File(os.path.join(build, doc, 'index.html')), ) - tar_deps.extend([html]) - tar_list.extend([html]) + tar_deps.append(html) + tar_list.append(html) Local(html) env.Ignore(html, version_xml) install_css = True - if 'pdf' in targets: + if 'pdf' in targets and not skip_pdf_build: env.InstallAs( target=env.File(pdf), source=env.File(os.path.join(build, doc, f'scons-{doc}.pdf')), @@ -546,17 +585,21 @@ else: pdf = os.path.join(build, 'PDF', f'{man}-man.pdf') html = os.path.join(build, 'HTML', f'{man}-man.html') - env.InstallAs( - target=env.File(pdf), - source=env.File(os.path.join(build, 'man', f'scons-{man}.pdf')), - ) + if not skip_pdf_build: + env.InstallAs( + target=env.File(pdf), + source=env.File(os.path.join(build, 'man', f'scons-{man}.pdf')), + ) env.InstallAs( target=env.File(html), source=env.File(os.path.join(build, 'man', f'scons-{man}.html')), ) - tar_deps.extend([pdf, html]) - tar_list.extend([pdf, html]) + tar_deps.append(html) + tar_list.append(html) + if not skip_pdf_build: + tar_deps.append(pdf) + tar_list.append(pdf) # Install CSS file, common to all single HTMLs if install_css: @@ -565,22 +608,26 @@ else: target=env.File(css_file), source=env.File(os.path.join(build, 'user', 'scons.css')), ) - tar_deps.extend([css_file]) - tar_list.extend([css_file]) + tar_deps.append(css_file) + tar_list.append(css_file) Local(css_file) -if not skip_doc: +if skip_api_build: + Alias("apidoc") +else: # Build API DOCS # TODO: Better specify dependencies on source files - pdf_file = env.Command( - target='#/build/doc/api/scons-api.pdf', - source=env.Glob('#/SCons/*'), - action=[Delete("#/build/doc/api"), "cd doc && make pdf"], - ) - pdf_install = os.path.join(build, 'PDF', 'scons-api.pdf') - env.InstallAs(target=pdf_install, source=pdf_file) - tar_deps.append(pdf_install) - tar_list.append(pdf_install) + if not skip_pdf_build: + pdf_file = env.Command( + target='#/build/doc/api/scons-api.pdf', + source=env.Glob('#/SCons/*'), + action=[Delete("#/build/doc/api"), "cd doc && make pdf"], + ) + pdf_install = os.path.join(build, 'PDF', 'scons-api.pdf') + env.InstallAs(target=pdf_install, source=pdf_file) + tar_deps.append(pdf_install) + tar_list.append(pdf_install) + Alias('apidoc', pdf_file) htmldir = os.path.join(build, 'HTML', 'scons-api') html_files = env.Command( @@ -591,6 +638,7 @@ if not skip_doc: ) tar_deps.append(htmldir) tar_list.append(htmldir) + Alias('apidoc', html_files) # # Now actually create the tar file of the documentation, diff --git a/site_scons/BuildCommandLine.py b/site_scons/BuildCommandLine.py index d401aed..32e62f3 100644 --- a/site_scons/BuildCommandLine.py +++ b/site_scons/BuildCommandLine.py @@ -77,7 +77,9 @@ class BuildCommandLine: ), ( "SKIP_DOC=", - "Skip building all documents. The default is False (build docs)" + "Skip building documents. The value can be 'pdf', 'api', " + "''all' or 'none'. A comma-separated list is also allowed. " + "The default is 'none' (build all docs)" ), ] -- cgit v0.12