diff options
| author | Dawid Rycerz <dawid@rycerz.xyz> | 2026-01-22 22:07:32 +0100 |
|---|---|---|
| committer | Dawid Rycerz <dawid@rycerz.xyz> | 2026-02-10 18:44:26 +0100 |
| commit | 064a1d01c5c14f5ecc032fa9b8346a4a88b893f6 (patch) | |
| tree | a2023f9ccd297ed8a41a3a0cc5699c2add09244d /build.rs | |
witryna 0.1.0 — initial releasev0.1.0
Minimalist Git-based static site deployment orchestrator.
Webhook-triggered builds in Podman/Docker containers with atomic
symlink publishing, SIGHUP hot-reload, and zero-downtime deploys.
See README.md for usage, CHANGELOG.md for details.
Diffstat (limited to 'build.rs')
| -rw-r--r-- | build.rs | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..287f7fb --- /dev/null +++ b/build.rs @@ -0,0 +1,150 @@ +#[path = "src/cli.rs"] +mod cli; + +use clap::CommandFactory as _; +use std::io::Write as _; + +fn main() -> std::io::Result<()> { + println!("cargo:rerun-if-changed=src/cli.rs"); + + #[allow(clippy::expect_used)] // OUT_DIR is always set by cargo during build scripts + let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR is set by cargo"); + let out_path = std::path::Path::new(&out_dir).join("witryna.1"); + + let cmd = cli::Cli::command(); + let man = clap_mangen::Man::new(cmd).date(build_date()); + + let mut buf: Vec<u8> = Vec::new(); + + // Standard clap-generated sections + man.render_title(&mut buf)?; + man.render_name_section(&mut buf)?; + man.render_synopsis_section(&mut buf)?; + man.render_description_section(&mut buf)?; + buf.write_all(SUBCOMMANDS)?; + man.render_options_section(&mut buf)?; + + // Custom roff sections + buf.write_all(SIGNALS)?; + buf.write_all(EXIT_STATUS)?; + buf.write_all(INSTALLATION)?; + buf.write_all(FILES)?; + buf.write_all(SEE_ALSO)?; + + man.render_version_section(&mut buf)?; + man.render_authors_section(&mut buf)?; + + std::fs::write(&out_path, &buf)?; + + // Copy to stable path so cargo-deb and Justfile always find it + let target_dir = std::path::Path::new("target/man"); + std::fs::create_dir_all(target_dir)?; + std::fs::copy(&out_path, target_dir.join("witryna.1"))?; + + Ok(()) +} + +const SUBCOMMANDS: &[u8] = br#".SH "SUBCOMMANDS" +.TP +\fBserve\fR +Start the deployment server (foreground). +.TP +\fBvalidate\fR +Validate configuration file and print summary. +.TP +\fBrun\fR \fIsite\fR +Trigger a one\-off build for a site (synchronous, no server). +.TP +\fBstatus\fR +Show deployment status for configured sites. +"#; + +const SIGNALS: &[u8] = br#".SH "SIGNALS" +.TP +\fBSIGHUP\fR +Reload configuration from \fIwitryna.toml\fR without restarting the server. +Sites can be added, removed, or modified on the fly. +Changes to \fBlisten_address\fR, \fBbase_dir\fR, \fBlog_dir\fR, +and \fBlog_level\fR are detected but require a full restart to take effect; +a warning is logged when these fields differ. +.TP +\fBSIGTERM\fR, \fBSIGINT\fR +Initiate graceful shutdown. +In\-progress builds are allowed to finish before the process exits. +"#; + +const EXIT_STATUS: &[u8] = br#".SH "EXIT STATUS" +.TP +\fB0\fR +Clean shutdown after SIGTERM/SIGINT (\fBserve\fR), configuration valid (\fBvalidate\fR), +build succeeded (\fBrun\fR), or status displayed (\fBstatus\fR). +Post\-deploy hook failure is non\-fatal and still exits 0. +.TP +\fB1\fR +Startup failure, validation error, build failure, site not found, or configuration error. +.TP +\fB2\fR +Command\-line usage error (unknown flag, missing subcommand, etc.). +"#; + +const INSTALLATION: &[u8] = br#".SH "INSTALLATION" +When installed via deb or rpm packages, the post\-install script automatically +detects the available container runtime and configures system\-level access: +.TP +\fBDocker\fR +The \fBwitryna\fR user is added to the \fBdocker\fR group and a systemd +override is installed at +\fI/etc/systemd/system/witryna.service.d/10\-runtime.conf\fR +granting access to the Docker socket. +.TP +\fBPodman\fR +Subordinate UID/GID ranges are allocated (100000\-165535), user lingering is +enabled, and a systemd override is installed that disables +\fBRestrictNamespaces\fR and sets \fBXDG_RUNTIME_DIR\fR. +.PP +If neither runtime is found at install time, a warning is printed. +Install a runtime and reinstall the package, or manually copy the appropriate +override template from \fI/usr/share/doc/witryna/examples/systemd/\fR to +\fI/etc/systemd/system/witryna.service.d/10\-runtime.conf\fR. +"#; + +const FILES: &[u8] = br#".SH "FILES" +.TP +\fI/etc/witryna/witryna.toml\fR +Conventional configuration path for system\-wide installs. +The shipped systemd unit passes \fB\-\-config /etc/witryna/witryna.toml\fR +explicitly; without \fB\-\-config\fR the CLI defaults to \fIwitryna.toml\fR +in the current working directory. +.TP +\fI/var/lib/witryna/clones/<site>/\fR +Git repository clones. +.TP +\fI/var/lib/witryna/builds/<site>/<timestamp>/\fR +Timestamped build outputs. +.TP +\fI/var/lib/witryna/builds/<site>/current\fR +Symlink to the latest successful build. +.TP +\fI/var/lib/witryna/cache/<site>/\fR +Persistent build cache volumes. +.TP +\fI/var/log/witryna/<site>/<timestamp>.log\fR +Per\-build log files (site, timestamp, git commit, image, duration, status, stdout, stderr). +.TP +\fI/var/log/witryna/<site>/<timestamp>\-hook.log\fR +Post\-deploy hook output (if configured). +"#; + +const SEE_ALSO: &[u8] = br#".SH "SEE ALSO" +\fBwitryna.toml\fR(5) +"#; + +fn build_date() -> String { + std::process::Command::new("date") + .arg("+%Y-%m-%d") + .output() + .ok() + .and_then(|o| String::from_utf8(o.stdout).ok()) + .map(|s| s.trim().to_owned()) + .unwrap_or_default() +} |
