altman — extract ALT Sisyphus man pages into a static site (Go)
  • Go 89.3%
  • JavaScript 6.9%
  • CSS 3.4%
  • Shell 0.4%
Find a file
shaba 7c428a4ace
Some checks failed
ci / test (push) Successful in 1m10s
release / release (push) Failing after 1m6s
perf: compress the NDJSON export with zstd instead of gzip
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.)
2026-07-08 13:28:35 +03:00
.forgejo/workflows ci: add a scheduled govulncheck workflow (#37) 2026-07-07 14:30:37 +03:00
cmd/altman feat: publish multiple ALT branches under per-branch URL prefixes 2026-07-03 22:30:42 +03:00
deploy fix: correct config path in altman.service (was %h/altman, is %h/alt-manpages) 2026-07-03 15:14:33 +03:00
etc chore: point example source remote at manpages/man-source 2026-07-02 19:08:09 +03:00
internal perf: compress the NDJSON export with zstd instead of gzip 2026-07-08 13:28:35 +03:00
testdata feat: read man pages from RPM payloads (rpmpkg, decompress, manpath, mandesc, planner, manifest) 2026-07-02 17:15:46 +03:00
vendor fix: transcode legacy 8-bit man sources to UTF-8 before mandoc (TASK4 P6) 2026-07-07 14:53:47 +03:00
.gitignore chore: project scaffold, Go module, vendored deps, Apache-2.0 license 2026-07-02 17:15:46 +03:00
go.mod perf: compress the NDJSON export with zstd instead of gzip 2026-07-08 13:28:35 +03:00
go.sum fix: transcode legacy 8-bit man sources to UTF-8 before mandoc (TASK4 P6) 2026-07-07 14:53:47 +03:00
LICENSE chore: project scaffold, Go module, vendored deps, Apache-2.0 license 2026-07-02 17:15:46 +03:00
README.md chore: project scaffold, Go module, vendored deps, Apache-2.0 license 2026-07-02 17:15:46 +03:00

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 a manifest.json state 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 service
  • deploy/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.