- Go 89.3%
- JavaScript 6.9%
- CSS 3.4%
- Shell 0.4%
Replace the gzip export compression with Zstandard (github.com/klauspost/compress, already vendored — now a direct dependency). Pure Go, no external binary, and ~20% smaller than gzip on real data (man5.en: 6.16 MB -> ~4.96 MB at the best level) while compressing the whole export in seconds. zstd multi-threads within each encoder; the concurrency is bounded (half the cores, capped) so klauspost's GOMAXPROCS default does not grab all of a 100+-core host. Buckets are compressed one at a time (zstd handles the parallelism), so the previous file-level worker pool is gone. Exports are now exports/man<sec>.<lang>.ndjson.zst; the manifest, home-page links, Russian copy and prune set are updated, and stale .gz/.xz shards are pruned on the first run. NOTE: the export consumer must decompress zstd (the dify-datasource-ndjson plugin). (An interim xz switch in 0.4.2 gave only ~11% because the pure-Go xz encoder's fast matcher is weak and its strong matcher is unusably slow; zstd is the pure-Go sweet spot. The full ~30% would need the xz CLI binary, deliberately avoided.) |
||
|---|---|---|
| .forgejo/workflows | ||
| cmd/altman | ||
| deploy | ||
| etc | ||
| internal | ||
| testdata | ||
| vendor | ||
| .gitignore | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| README.md | ||
altman
altman extracts man pages from ALT Linux Sisyphus RPM packages and renders
them into a static, searchable HTML site — the ALT counterpart of Debian's
debiman and openSUSE's
rpm2docserv.
It reads man sources directly from binary RPM payloads (no unpacking to disk),
decompresses them, renders each page with mandoc, cross-links SEE ALSO
references, builds a client-side Pagefind search index,
and publishes the result to Forgejo pages.
Layout
The project is split into three repositories under the manpages organization:
| Repo | Contents |
|---|---|
manpages/altman |
this Go code + CI + releases |
manpages/sisyphus |
decompressed troff man sources (pushed by the source stage) |
manpages/pages |
rendered HTML site, served by pages-server |
Pipeline
altman runs in two stages (independently or together):
- source — scan
rpm_roots, extract new/changed man pages from RPM payloads, decompress to troff, write the corpus +catalog.json, and push to the source repo. Incremental: unchanged packages are skipped via amanifest.jsonstate file. - build — render the troff corpus to HTML (shared header, dark/light theme, RU/EN localization), cross-link references, run Pagefind, create human-friendly short URLs and alias symlinks, and push the site to the pages repo.
usage: altman {source|build|all} [--no-push] -config <path>
Building
# statically linked binary (recommended for deployment)
CGO_ENABLED=0 go build -o altman ./cmd/altman
Released binaries are attached to each git tag on the releases page.
Running
cp etc/config.example.toml etc/config.toml # then edit it
./altman all -config etc/config.toml # source + build
./altman build --no-push -config etc/config.toml # render only, no git push (CI)
--no-push uses the working directories as-is (no clone/commit/push) — suitable
for CI that renders and lets a later step publish.
Deployment
Production runs on team.altlinux.org as a systemd user timer, driven by the
maintainer. Artifacts in deploy/:
deploy/altman.service— oneshot user servicedeploy/altman.timer— user timer (hourly, randomized delay)deploy/build-and-deploy.sh— build + upload helper
Install the units into ~/.config/systemd/user/, enable lingering
(loginctl enable-linger "$USER"), then systemctl --user enable --now altman.timer.
Dependencies
mandoc— man → HTML rendering (external binary).pagefind— static-site search index (external binary, optional).- Go modules:
sassoftware/go-rpmutils(RPM payloads),ulikunitz/xz,BurntSushi/toml.
Testing
go test ./...
License
Licensed under the Apache License 2.0.