Merge pull request #188032 from mweinelt/sphinx-hook-builders

This commit is contained in:
Martin Weinelt 2022-08-24 23:54:52 +02:00 committed by GitHub
commit faef00229e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 94 additions and 36 deletions

View file

@ -744,6 +744,53 @@ with the exception of `other` (see `format` in
unittestFlags = [ "-s" "tests" "-v" ]; unittestFlags = [ "-s" "tests" "-v" ];
``` ```
##### Using sphinxHook {#using-sphinxhook}
The `sphinxHook` is a helpful tool to build documentation and manpages
using the popular Sphinx documentation generator.
It is setup to automatically find common documentation source paths and
render them using the default `html` style.
```
outputs = [
"out"
"doc"
];
nativeBuildInputs = [
sphinxHook
];
```
The hook will automatically build and install the artifact into the
`doc` output, if it exists. It also provides an automatic diversion
for the artifacts of the `man` builder into the `man` target.
```
outputs = [
"out"
"doc"
"man"
];
# Use multiple builders
sphinxBuilders = [
"singlehtml"
"man"
];
```
Overwrite `sphinxRoot` when the hook is unable to find your
documentation source root.
```
# Configure sphinxRoot for uncommon paths
sphinxRoot = "weird/docs/path";
```
The hook is also available to packages outside the python ecosystem by
referencing it using `python3.pkgs.sphinxHook`.
### Develop local package {#develop-local-package} ### Develop local package {#develop-local-package}
As a Python developer you're likely aware of [development mode](http://setuptools.readthedocs.io/en/latest/setuptools.html#development-mode) As a Python developer you're likely aware of [development mode](http://setuptools.readthedocs.io/en/latest/setuptools.html#development-mode)
@ -1270,16 +1317,17 @@ are used in `buildPythonPackage`.
- `pytestCheckHook` to run tests with `pytest`. See [example usage](#using-pytestcheckhook). - `pytestCheckHook` to run tests with `pytest`. See [example usage](#using-pytestcheckhook).
- `pythonCatchConflictsHook` to check whether a Python package is not already existing. - `pythonCatchConflictsHook` to check whether a Python package is not already existing.
- `pythonImportsCheckHook` to check whether importing the listed modules works. - `pythonImportsCheckHook` to check whether importing the listed modules works.
- `pythonRelaxDepsHook` will relax Python dependencies restrictions for the package.
See [example usage](#using-pythonrelaxdepshook).
- `pythonRemoveBinBytecode` to remove bytecode from the `/bin` folder. - `pythonRemoveBinBytecode` to remove bytecode from the `/bin` folder.
- `setuptoolsBuildHook` to build a wheel using `setuptools`. - `setuptoolsBuildHook` to build a wheel using `setuptools`.
- `setuptoolsCheckHook` to run tests with `python setup.py test`. - `setuptoolsCheckHook` to run tests with `python setup.py test`.
- `sphinxHook` to build documentation and manpages using Sphinx.
- `venvShellHook` to source a Python 3 `venv` at the `venvDir` location. A - `venvShellHook` to source a Python 3 `venv` at the `venvDir` location. A
`venv` is created if it does not yet exist. `postVenvCreation` can be used to `venv` is created if it does not yet exist. `postVenvCreation` can be used to
to run commands only after venv is first created. to run commands only after venv is first created.
- `wheelUnpackHook` to move a wheel to the correct folder so it can be installed - `wheelUnpackHook` to move a wheel to the correct folder so it can be installed
with the `pipInstallHook`. with the `pipInstallHook`.
- `pythonRelaxDepsHook` will relax Python dependencies restrictions for the package.
See [example usage](#using-pythonrelaxdepshook).
- `unittestCheckHook` will run tests with `python -m unittest discover`. See [example usage](#using-unittestcheckhook). - `unittestCheckHook` will run tests with `python -m unittest discover`. See [example usage](#using-unittestcheckhook).
### Development mode {#development-mode} ### Development mode {#development-mode}

View file

@ -6,6 +6,7 @@
, isPy3k , isPy3k
, ensureNewerSourcesForZipFilesHook , ensureNewerSourcesForZipFilesHook
, findutils , findutils
, installShellFiles
}: }:
let let
@ -190,6 +191,6 @@ in rec {
sphinxHook = callPackage ({ sphinx }: sphinxHook = callPackage ({ sphinx }:
makeSetupHook { makeSetupHook {
name = "python${python.pythonVersion}-sphinx-hook"; name = "python${python.pythonVersion}-sphinx-hook";
deps = [ sphinx ]; deps = [ sphinx installShellFiles ];
} ./sphinx-hook.sh) {}; } ./sphinx-hook.sh) {};
} }

View file

@ -1,20 +1,14 @@
# This hook automatically finds Sphinx documentation, builds it in html format # shellcheck shell=bash
# and installs it. echo "Sourcing sphinx-hook"
#
# This hook knows about several popular locations in which subdirectory declare -a __sphinxBuilders
# documentation may be, but in very unusual cases $sphinxRoot directory can be
# set explicitly.
#
# Name of the directory relative to ${doc:-$out}/share/doc is normally also
# deduced automatically, but can be overridden with $sphinxOutdir variable.
#
# Sphinx build system can depend on arbitrary amount of python modules, client
# code is responsible for ensuring that all dependencies are present.
buildSphinxPhase() { buildSphinxPhase() {
local __sphinxRoot="" o echo "Executing buildSphinxPhase"
local __sphinxRoot=""
runHook preBuildSphinx runHook preBuildSphinx
if [[ -n "${sphinxRoot:-}" ]] ; then # explicit root if [[ -n "${sphinxRoot:-}" ]] ; then # explicit root
if ! [[ -f "${sphinxRoot}/conf.py" ]] ; then if ! [[ -f "${sphinxRoot}/conf.py" ]] ; then
echo 2>&1 "$sphinxRoot/conf.py: no such file" echo 2>&1 "$sphinxRoot/conf.py: no such file"
@ -22,10 +16,10 @@ buildSphinxPhase() {
fi fi
__sphinxRoot=$sphinxRoot __sphinxRoot=$sphinxRoot
else else
for o in doc docs doc/source docs/source ; do for candidate in doc docs doc/source docs/source ; do
if [[ -f "$o/conf.py" ]] ; then if [[ -f "$candidate/conf.py" ]] ; then
echo "Sphinx documentation found in $o" echo "Sphinx documentation found in $candidate"
__sphinxRoot=$o __sphinxRoot=$candidate
break break
fi fi
done done
@ -35,23 +29,44 @@ buildSphinxPhase() {
echo 2>&1 "Sphinx documentation not found, use 'sphinxRoot' variable" echo 2>&1 "Sphinx documentation not found, use 'sphinxRoot' variable"
exit 1 exit 1
fi fi
sphinx-build -M html "${__sphinxRoot}" ".sphinx/html" -v
if [ -n "${sphinxBuilders-}" ]; then
eval "__sphinxBuilders=($sphinxBuilders)"
else
__sphinxBuilders=(html)
fi
for __builder in "${__sphinxBuilders[@]}"; do
echo "Executing sphinx-build with ${__builder} builder"
sphinx-build -M "${__builder}" "${__sphinxRoot}" ".sphinx/${__builder}" -v
done
runHook postBuildSphinx runHook postBuildSphinx
} }
installSphinxPhase() { installSphinxPhase() {
echo "Executing installSphinxPhase"
local docdir="" local docdir=""
runHook preInstallSphinx runHook preInstallSphinx
docdir="${doc:-$out}/share/doc/${sphinxOutdir:-$name}" for __builder in "${__sphinxBuilders[@]}"; do
mkdir -p "$docdir" # divert output for man builder
if [ "$__builder" == "man" ]; then
installManPage .sphinx/man/man/*
cp -r .sphinx/html/html "$docdir/" else
rm -fr "${docdir}/html/_sources" "${docdir}/html/.buildinfo" # shellcheck disable=2154
docdir="${doc:-$out}/share/doc/${pname}"
mkdir -p "$docdir"
cp -r ".sphinx/${__builder}/${__builder}" "$docdir/"
rm -fr "${docdir}/${__builder}/_sources" "${docdir}/${__builder}/.buildinfo"
fi
done
runHook postInstallSphinx runHook postInstallSphinx
} }
preDistPhases+=" buildSphinxPhase" preDistPhases+=" buildSphinxPhase installSphinxPhase"
postPhases+=" installSphinxPhase"

View file

@ -33,13 +33,15 @@ python3.pkgs.buildPythonApplication rec {
setuptools-scm setuptools-scm
# docs # docs
sphinx sphinxHook
guzzle_sphinx_theme guzzle_sphinx_theme
# shell completions # shell completions
installShellFiles installShellFiles
]; ];
sphinxBuilders = [ "singlehtml" "man" ];
buildInputs = [ buildInputs = [
libb2 libb2
lz4 lz4
@ -67,14 +69,6 @@ python3.pkgs.buildPythonApplication rec {
]; ];
postInstall = '' postInstall = ''
make -C docs singlehtml
mkdir -p $out/share/doc/borg
cp -R docs/_build/singlehtml $out/share/doc/borg/html
make -C docs man
mkdir -p $out/share/man
cp -R docs/_build/man $out/share/man/man1
installShellCompletion --cmd borg \ installShellCompletion --cmd borg \
--bash scripts/shell_completions/bash/borg \ --bash scripts/shell_completions/bash/borg \
--fish scripts/shell_completions/fish/borg.fish \ --fish scripts/shell_completions/fish/borg.fish \