mafw.scripts.doc_versioning

Helper tool for the generation of versioned documentation files.

Build Sphinx docs for every stable tag (excluding rc/alpha/beta), label highest tag as “stable”, optionally label current branch as “dev” if it’s ahead. Generates a versions.json and creates redirect index pages for stable/dev. Now with optional PDF generation!

Requirements:
  • Git with worktree support

  • sphinx-build available on PATH (install Sphinx in the env)

  • For PDF: latexmk and pdflatex (TeX Live or similar)

multiversion-doc

Build and manage versioned documentation.

Usage

multiversion-doc [OPTIONS] COMMAND [ARGS]...

build

Build multiversion documentation.

param outdir:

Output directory for built documentation

type outdir:

Path

param include_dev:

Whether to include dev alias if current branch is ahead

type include_dev:

bool

param min_vers:

Minimum version to consider

type min_vers:

str

param keep_temp:

Whether to keep temporary files

type keep_temp:

bool

param use_latest_conf:

Whether to use latest conf.py for all builds

type use_latest_conf:

bool

param build_pdf:

Whether to also build PDF versions

type build_pdf:

bool

param project_name:

Project name for PDF index page

type project_name:

str

param use_symlinks:

Whether to use symlinks instead of copying

type use_symlinks:

bool

param max_size:

Maximum artifact size in MB (0 = no limit)

type max_size:

int

Usage

multiversion-doc build [OPTIONS]

Options

-o, --outdir <outdir>

Output directory (docs/build/doc)

--include-dev, --no-include-dev

If true and current branch is ahead of stable, create dev redirect. (True)

--min-vers <min_vers>

Minimum version to consider (default: v1.0.0).

--keep-temp, --no-keep-temp

Do not remove temp dir (for debugging).

--use-latest-conf, --no-use-latest-conf

Use the latest conf.py for all builds. (True)

--build-pdf, --no-build-pdf

Also build PDF versions. (False)

--project-name <project_name>

Project name for PDF index page.

Use symlinks for stable/dev aliases instead of copying. (True)

-s, --max-size <max_size>

Maximum artifact size in MB. If exceeded, prune old versions (0 = no limit)

clean

Clean the output directory. TARGET can be ‘all’ (remove everything) or ‘latest’ (remove only latest folder).

param target:

What to clean - ‘all’ or ‘latest’

type target:

str

param outdir:

Output directory to clean

type outdir:

Path

Usage

multiversion-doc clean [OPTIONS] [[all|latest]]

Options

-o, --outdir <outdir>

Output directory to clean

Arguments

TARGET

Optional argument

current

Build documentation only for the current working tree (no git worktrees). Places output in the ‘latest’ folder.

param outdir:

Output directory for built documentation

type outdir:

Path

param build_pdf:

Whether to also build PDF version

type build_pdf:

bool

param project_name:

Project name for PDF

type project_name:

str

Usage

multiversion-doc current [OPTIONS]

Options

-o, --outdir <outdir>

Output directory (docs/build/doc)

--build-pdf, --no-build-pdf

Also build PDF versions. (False)

landing

Generate root landing page for project.

param build_root:

Build root directory

type build_root:

Path

param project_name:

Project name

type project_name:

str

Usage

multiversion-doc landing [OPTIONS]

Options

-b, --build-root <build_root>

Build root directory containing doc/ subdirectory

--project-name <project_name>

Project name for the landing page

prune

Prune old documentation versions to stay within size limit.

This command removes the oldest version directories (keeping stable, latest, dev) until the total size is below the specified threshold.

param outdir:

Output directory to prune

type outdir:

Path

param max_size:

Maximum size in megabytes

type max_size:

int

param dry_run:

Whether to do a dry run

type dry_run:

bool

param auto_prune:

Whether to prune automatically without confirmation

type auto_prune:

bool

Usage

multiversion-doc prune [OPTIONS]

Options

-o, --outdir <outdir>

Output directory to check

-s, --max-size <max_size>

Maximum size in MB (default: 100)

--dry-run, --no-dry-run

Show what would be removed without actually removing

--auto-prune, --no-auto-prune

Automatically prune without confirmation

redirects

Generate _redirects file for GitLab Pages.

param outdir:

Output directory for _redirects file

type outdir:

Path

param old_pdf_path:

Old PDF URL path to redirect from

type old_pdf_path:

Path

param new_pdf_path:

New PDF downloads page to redirect to

type new_pdf_path:

Path

param redirect_root:

Whether to redirect /doc/ root to stable

type redirect_root:

bool

Usage

multiversion-doc redirects [OPTIONS]

Options

-o, --outdir <outdir>

Output directory for _redirects file

--old-pdf-path <old_pdf_path>

Old PDF URL path to redirect from

--new-pdf-path <new_pdf_path>

New PDF downloads page to redirect to

--redirect-root, --no-redirect-root

Redirect /doc/ root to stable

Functions

build_for_tag(tag, outdir, tmproot[, ...])

Create worktree for tag, run sphinx-build, save log.

build_pdf_for_tag(tag, html_tag_dir, tmproot)

Create worktree for tag, run sphinx-build with latex builder, then make PDF.

check_multiversion_structure(outdir)

Check if multiversion structure exists (other version directories).

copy_patch_files(docs_src)

Copy patch files needed for older versions.

ensure_versions_json_exists(outdir)

Ensure versions.json exists in outdir.

filter_latest_micro(versions)

Keep only the latest micro version per minor (major.minor).

filter_stable_tags(tags, regex)

Filter tags based on a regular expression pattern.

format_size(bytes_size)

Format bytes to human-readable size.

generate_pdf_index_page(html_outdir, pdf_info)

Generate an HTML page listing all available PDFs.

get_current_branch()

Get the name of the currently checked out branch.

get_directory_size(path)

Calculate total size of a directory in bytes.

get_git_tags([min_version])

Return list of (Version, tag) tuples sorted ascending.

git_rev_of(ref)

Get the git revision hash for a given reference.

is_ancestor(a, b)

Return True if commit a is ancestor of commit b (git merge-base --is-ancestor).

mirror_version(outdir, src_tag, target_tag)

Mirror a version directory from one tag to another.

parse_sphinx_log(log_content)

Parse Sphinx build log to extract warning and error counts, and warning messages.

parse_version_tuple(tag)

Parse vX.Y.Z(.W) into tuple of ints for sorting.

prune_old_versions(outdir[, max_size_mb, ...])

Remove oldest version directories until total size is below threshold.

regenerate_versions_json_after_pruning(...)

Regenerate versions.json after pruning, excluding removed versions.

report_build_status(tag, success, log[, ...])

Report build status with warning/error summary.

run(cmd[, cwd])

Helper to run commands with consistent behavior.

sort_tags_semver(tags)

Sort tags using semantic versioning comparison.

write_legacy_redirect_page(outdir)

Create a legacy redirect page at the root of the output directory.

write_redirect_page(outdir, name, target_tag)

Create a redirect page for a version alias.

write_redirects_file(outdir)

Create a _redirects file for GitLab Pages.

write_root_landing_page(build_root[, ...])

Create a landing page for the project root with links to documentation and coverage.

write_versions_json(outdir, versions)

Write versions information to a JSON file.

mafw.scripts.doc_versioning.build_for_tag(tag: str, outdir: Path, tmproot: Path, use_latest_conf: bool = False, keep_tmp: bool = False) Tuple[bool, str][source]

Create worktree for tag, run sphinx-build, save log. Returns (success, log_contents).

Parameters:
  • tag (str) – Git tag to build documentation for

  • outdir (Path) – Output directory for built documentation

  • tmproot (Path) – Root temporary directory

  • use_latest_conf (bool) – Whether to use latest conf.py, defaults to False

  • keep_tmp (bool) – Whether to keep temporary files, defaults to False

Returns:

Tuple of (success, log_contents)

Return type:

Tuple[bool, str]

mafw.scripts.doc_versioning.build_pdf_for_tag(tag: str, html_tag_dir: Path, tmproot: Path, use_latest_conf: bool = False, keep_tmp: bool = False) Tuple[bool, str, Path | None][source]

Create worktree for tag, run sphinx-build with latex builder, then make PDF. Places PDF in the same directory as the HTML output for that tag. Returns (success, log_contents, pdf_path).

Parameters:
  • tag (str) – Git tag to build PDF for

  • html_tag_dir (Path) – Directory containing HTML output for the tag

  • tmproot (Path) – Root temporary directory

  • use_latest_conf (bool) – Whether to use latest conf.py, defaults to False

  • keep_tmp (bool) – Whether to keep temporary files, defaults to False

Returns:

Tuple of (success, log_contents, pdf_path)

Return type:

Tuple[bool, str, Path | None]

mafw.scripts.doc_versioning.check_multiversion_structure(outdir: Path) bool[source]

Check if multiversion structure exists (other version directories).

Parameters:

outdir (Path) – Output directory to check

Returns:

True if other versions exist

Return type:

bool

mafw.scripts.doc_versioning.copy_patch_files(docs_src: Path) None[source]

Copy patch files needed for older versions.

Parameters:

docs_src (Path) – Path to documentation source directory

mafw.scripts.doc_versioning.ensure_versions_json_exists(outdir: Path) bool[source]

Ensure versions.json exists in outdir. If not, try to copy from another version.

Parameters:

outdir (Path) – Output directory that should contain versions.json

Returns:

True if versions.json exists or was successfully copied

Return type:

bool

mafw.scripts.doc_versioning.filter_latest_micro(versions: List[Tuple[Version, Any]]) List[Tuple[Version, Any]][source]

Keep only the latest micro version per minor (major.minor).

Parameters:

versions (List[Tuple[Version, Any]]) – List of (Version, tag) tuples

Returns:

Filtered list of (Version, tag) tuples

Return type:

List[Tuple[Version, Any]]

mafw.scripts.doc_versioning.filter_stable_tags(tags: List[str], regex: str) List[str][source]

Filter tags based on a regular expression pattern.

Parameters:
  • tags (List[str]) – List of tag strings to filter

  • regex (str) – Regular expression pattern to match against

Returns:

Filtered list of matching tags

Return type:

List[str]

mafw.scripts.doc_versioning.format_size(bytes_size: float) str[source]

Format bytes to human-readable size.

Parameters:

bytes_size (int) – Size in bytes

Returns:

Formatted size string

Return type:

str

mafw.scripts.doc_versioning.generate_pdf_index_page(html_outdir: Path, pdf_info: List[dict[str, str]], project_name: str = 'Documentation') None[source]

Generate an HTML page listing all available PDFs. This page will be placed in the root html_versions directory. Order: stable first, then latest, then other releases sorted by version (newest first).

Parameters:
  • html_outdir (Path) – Output directory for HTML files

  • pdf_info (List[dict[str, str]]) – List of dictionaries containing PDF information

  • project_name (str) – Name of the project for the page title, defaults to ‘Documentation’

mafw.scripts.doc_versioning.get_current_branch() str[source]

Get the name of the currently checked out branch.

Returns:

Name of the current branch

Return type:

str

mafw.scripts.doc_versioning.get_directory_size(path: Path) int[source]

Calculate total size of a directory in bytes.

Parameters:

path (Path) – Directory path

Returns:

Total size in bytes

Return type:

int

mafw.scripts.doc_versioning.get_git_tags(min_version: str | None = None) List[Tuple[Version, Any]][source]

Return list of (Version, tag) tuples sorted ascending.

Parameters:

min_version (str | None) – Minimum version to consider, defaults to None

Returns:

List of (Version, tag) tuples

Return type:

List[Tuple[Version, Any]]

mafw.scripts.doc_versioning.git_rev_of(ref: str) str[source]

Get the git revision hash for a given reference.

Parameters:

ref (str) – Git reference (tag, branch, commit hash)

Returns:

Git revision hash

Return type:

str

Raises:

RuntimeError – If git rev-list fails

mafw.scripts.doc_versioning.is_ancestor(a: str, b: str) bool[source]

Return True if commit a is ancestor of commit b (git merge-base –is-ancestor).

Parameters:
  • a (str) – First commit reference

  • b (str) – Second commit reference

Returns:

True if a is ancestor of b

Return type:

bool

mafw.scripts.doc_versioning.mirror_version(outdir: Path, src_tag: str, target_tag: str, use_symlink: bool = True) None[source]

Mirror a version directory from one tag to another. Can use symlinks for efficiency or copy for compatibility.

Parameters:
  • outdir (Path) – Output directory containing version directories

  • src_tag (str) – Source tag directory name

  • target_tag (str) – Target tag directory name

  • use_symlink (bool) – Whether to use symlink instead of copying, defaults to True

mafw.scripts.doc_versioning.parse_sphinx_log(log_content: str) Tuple[int, int, List[str]][source]

Parse Sphinx build log to extract warning and error counts, and warning messages.

Only three warnings are reported

Parameters:

log_content (str) – Sphinx build log

Returns:

Tuple of warning, error count, warning messages

Return type:

Tuple[int, int, List[str]]

mafw.scripts.doc_versioning.parse_version_tuple(tag: str) Tuple[int, ...][source]

Parse vX.Y.Z(.W) into tuple of ints for sorting.

Parameters:

tag (str) – Version tag string

Returns:

Tuple of integers representing the version

Return type:

Tuple[int, …]

mafw.scripts.doc_versioning.prune_old_versions(outdir: Path, max_size_mb: int = 100, dry_run: bool = False) Tuple[List[str], int][source]

Remove oldest version directories until total size is below threshold. Always keeps ‘stable’, ‘latest’, and ‘dev’ (if present).

Parameters:
  • outdir (Path) – Output directory containing version directories

  • max_size_mb (int) – Maximum size in megabytes

  • dry_run (bool) – If True, only report what would be deleted

Returns:

Tuple of (list of removed versions, final size in bytes)

Return type:

Tuple[List[str], int]

mafw.scripts.doc_versioning.regenerate_versions_json_after_pruning(outdir: Path, removed_versions: List[str]) None[source]

Regenerate versions.json after pruning, excluding removed versions.

Parameters:
  • outdir (Path) – Output directory containing version directories

  • removed_versions (List[str]) – List of version names that were removed

mafw.scripts.doc_versioning.report_build_status(tag: str, success: bool, log: str, build_type: str = 'HTML') None[source]

Report build status with warning/error summary.

Parameters:
  • tag (str) – Version tag being built

  • success (bool) – Whether build succeeded

  • log (str) – Build log content

  • build_type (str) – Type of build (HTML or PDF)

mafw.scripts.doc_versioning.run(cmd: List[str], cwd: Path | None = None) CompletedProcess[str][source]

Helper to run commands with consistent behavior.

Parameters:
  • cmd (List[str]) – Command to execute as a list of strings

  • cwd (Path | None) – Working directory for command execution, defaults to None

Returns:

Completed process result

Return type:

subprocess.CompletedProcess[str]

mafw.scripts.doc_versioning.sort_tags_semver(tags: List[str]) List[str][source]

Sort tags using semantic versioning comparison.

Parameters:

tags (List[str]) – List of tag strings to sort

Returns:

Sorted list of tag strings

Return type:

List[str]

mafw.scripts.doc_versioning.write_legacy_redirect_page(outdir: Path) None[source]

Create a legacy redirect page at the root of the output directory.

Parameters:

outdir (Path) – Output directory for the redirect page

mafw.scripts.doc_versioning.write_redirect_page(outdir: Path, name: str, target_tag: str) None[source]

Create a redirect page for a version alias.

Parameters:
  • outdir (Path) – Output directory for the redirect page

  • name (str) – Name of the redirect alias (e.g., ‘stable’, ‘dev’)

  • target_tag (str) – Tag that the redirect should point to

mafw.scripts.doc_versioning.write_redirects_file(outdir: Path) None[source]

Create a _redirects file for GitLab Pages.

Parameters:

outdir (Path) – Output directory for the redirects file

mafw.scripts.doc_versioning.write_root_landing_page(build_root: Path, project_name: str = 'MAFw') None[source]

Create a landing page for the project root with links to documentation and coverage.

Parameters:
  • build_root (Path) – Root build directory (should contain ‘doc’ subdirectory)

  • project_name (str) – Project name for the page title

mafw.scripts.doc_versioning.write_versions_json(outdir: Path, versions: List[dict[str, str]]) None[source]

Write versions information to a JSON file.

Parameters:
  • outdir (Path) – Output directory for the JSON file

  • versions (List[dict[str, str]]) – List of version information dictionaries