Skip to content

Commit 054814f

Browse files
authored
Generate sphinx docs from help pages (#110)
* Generate sphinx docs from help pages * Fix prebuild steps in .readthedocs.yaml
1 parent 32b6057 commit 054814f

File tree

8 files changed

+221
-0
lines changed

8 files changed

+221
-0
lines changed

.github/workflows/test.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,41 @@ jobs:
9898
files: coverage.lcov
9999
token: ${{ secrets.CODECOV_TOKEN }}
100100
verbose: true
101+
102+
docs:
103+
name: 'Build docs'
104+
runs-on: ubuntu-latest
105+
steps:
106+
- name: Checkout source
107+
uses: actions/checkout@v6
108+
with:
109+
fetch-depth: 0
110+
111+
- name: Create micromamba environment
112+
uses: mamba-org/setup-micromamba@main
113+
with:
114+
environment-file: dev-environment.yml
115+
cache-environment: true
116+
117+
- name: Configure CMake
118+
run: |
119+
cmake -Bbuild -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX
120+
121+
- name: Build with CMake
122+
working-directory: build
123+
run: cmake --build . --parallel 8
124+
125+
- name: Install docs dependencies
126+
run: |
127+
python -m pip install myst-parser sphinx sphinx-book-theme
128+
129+
- name: Build docs
130+
working-directory: docs
131+
run: |
132+
make html
133+
134+
- name: Upload built docs
135+
uses: actions/upload-artifact@v6
136+
with:
137+
name: git2cpp-docs
138+
path: docs/_build/html

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@ __pycache__/
44
compile_commands.json
55
serve.log
66
test/test-results/
7+
8+
docs/_build/
9+
docs/created/

.readthedocs.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
version: 2
2+
3+
build:
4+
os: ubuntu-24.04
5+
tools:
6+
python: mambaforge-23.11
7+
jobs:
8+
post_install:
9+
- cmake -Bbuild -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX
10+
- cd build && make
11+
- python -m pip install myst-parser sphinx sphinx-book-theme
12+
pre_build:
13+
- cd docs && python create_markdown.py
14+
15+
conda:
16+
environment: dev-environment.yml
17+
18+
sphinx:
19+
builder: html
20+
configuration: docs/conf.py
21+
fail_on_warning: true

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,22 @@ See the `README.md` in the `wasm` directory for further details.
3838

3939
The latest `cockle` and JupyterLite `terminal` deployments using `git2cpp` are available at
4040
[https://quantstack.net/git2cpp](https://quantstack.net/git2cpp)
41+
42+
# Documentation
43+
44+
The project documentation is generated from the `git2cpp` help pages. To build the documentation
45+
locally first build `git2cpp` as usual as described above, then install the documentation
46+
dependencies:
47+
48+
```bash
49+
micromamba install myst-parser sphinx sphinx-book-theme
50+
```
51+
52+
and build the documentation:
53+
54+
```bash
55+
cd docs
56+
make html
57+
```
58+
59+
The top-level documentation page will be `docs/_build/html/index.html`

docs/Makefile

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# You can set these variables from the command line, and also
2+
# from the environment for the first two.
3+
SPHINXOPTS ?=
4+
SPHINXBUILD ?= sphinx-build
5+
SOURCEDIR = .
6+
BUILDDIR = _build
7+
8+
# Put it first so that "make" without argument is like "make help".
9+
help:
10+
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
11+
12+
.PHONY: help Makefile
13+
14+
# Catch-all target: route all unknown targets to Sphinx using the new
15+
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
16+
%: Makefile
17+
python create_markdown.py
18+
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

docs/conf.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from datetime import date
2+
3+
project = "git2cpp"
4+
author = "QuantStack"
5+
copyright = f"2025-{date.today().year}"
6+
7+
extensions = [
8+
"myst_parser",
9+
]
10+
11+
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
12+
13+
html_static_path = []
14+
html_theme = "sphinx_book_theme"
15+
html_theme_options = {
16+
"github_url": "https://github.com/QuantStack/git2cpp",
17+
"home_page_in_toc": True,
18+
"show_navbar_depth": 2,
19+
}
20+
html_title = "git2cpp documentation"

docs/create_markdown.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import os
2+
from pathlib import Path
3+
import re
4+
import subprocess
5+
6+
7+
def get_filename(args):
8+
directory = Path("created").joinpath(*args[:-1])
9+
filename = args[-1] + ".md"
10+
return directory / filename
11+
12+
13+
def sanitise_line(line):
14+
# Remove trailing whitespace otherwise the markdown parser can insert an extra \n
15+
line = line.rstrip()
16+
17+
# Replace angular brackets with HTML equivalents.
18+
line = line.replace(r"&", r"&")
19+
line = line.replace(r"<", r"&lt;")
20+
line = line.replace(r">", r"&gt;")
21+
22+
# If there are whitespace characters at the start of the line, replace the first with an &nbsp
23+
# so that it is not discarded by the markdown parser used by the parsed-literal directive.
24+
line = re.sub(r"^\s", r"&nbsp;", line)
25+
26+
return line
27+
28+
29+
# Process a single subcommand, adding new subcommands found to to_process.
30+
def process(args, to_process):
31+
cmd = args + ["--help"]
32+
cmd_string = " ".join(cmd)
33+
filename = get_filename(args)
34+
filename.parent.mkdir(parents=True, exist_ok=True)
35+
36+
print(f"Writing '{cmd_string}' to file {filename}")
37+
p = subprocess.run(cmd, capture_output=True, text=True, check=True)
38+
39+
# Write output markdown file, identifying subcommands at the same time to provide
40+
# links to the subcommand markdown files.
41+
subcommands = []
42+
with open(filename, "w") as f:
43+
f.write(f"({filename})=\n") # Target for links.
44+
f.write(f"# {' '.join(args)}\n")
45+
f.write("\n")
46+
f.write("```{parsed-literal}\n")
47+
48+
in_subcommand_section = False
49+
for line in p.stdout.splitlines():
50+
if in_subcommand_section:
51+
match = re.match(r"^( )([\w\-_]+)(\s+.*)$", line)
52+
if match:
53+
subcommand = match.group(2)
54+
subcommand_filename = get_filename(args + [subcommand])
55+
line = match.group(1) + f"[{subcommand}]({subcommand_filename})" + match.group(3)
56+
subcommands.append(subcommand)
57+
elif line.startswith("SUBCOMMANDS:"):
58+
in_subcommand_section = True
59+
60+
f.write(sanitise_line(line) + "\n")
61+
f.write("```\n")
62+
63+
subcommands.sort()
64+
to_process.extend(args + [subcommand] for subcommand in subcommands)
65+
66+
if len(subcommands) > 0:
67+
# Hidden table of contents for subcommands of this command/subcommand.
68+
f.write("\n")
69+
f.write("```{toctree}\n")
70+
f.write(":hidden:\n")
71+
for subcommand in subcommands:
72+
f.write(f"{args[-1]}/{subcommand}\n")
73+
f.write("```\n")
74+
75+
76+
if __name__ == "__main__":
77+
# Modify the PATH so that git2cpp is found by name, as using a full path will cause the help
78+
# pages to write that full path.
79+
git2cpp_dir = Path(__file__).parent.parent / 'build'
80+
os.environ["PATH"] = f'{git2cpp_dir}{os.pathsep}{os.environ["PATH"]}'
81+
82+
to_process = [["git2cpp"]]
83+
while len(to_process) > 0:
84+
subcommand = to_process.pop(0)
85+
process(subcommand, to_process)

docs/index.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Overview
2+
3+
`git2cpp` is a C++ wrapper of [libgit2](https://libgit2.org/) to provide a command-line interface
4+
(CLI) to `git` functionality. The intended use is in WebAssembly in-browser terminals (the
5+
[cockle](https://github.com/jupyterlite/cockle) and
6+
[JupyterLite terminal](https://github.com/jupyterlite/terminal) projects) but it can be compiled and
7+
used on any POSIX-compliant system.
8+
9+
The Help pages here are generated from the `git2cpp` command and subcommands to show the
10+
functionality that is currently supported. If there are features missing that you would like to use,
11+
please create an issue in the [git2cpp github repository](https://github.com/QuantStack/git2cpp).
12+
13+
```{toctree}
14+
:caption: Help pages
15+
:hidden:
16+
created/git2cpp
17+
```

0 commit comments

Comments
 (0)