#[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 = 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//\fR Git repository clones. .TP \fI/var/lib/witryna/builds///\fR Timestamped build outputs. .TP \fI/var/lib/witryna/builds//current\fR Symlink to the latest successful build. .TP \fI/var/lib/witryna/cache//\fR Persistent build cache volumes. .TP \fI/var/log/witryna//.log\fR Per\-build log files (site, timestamp, git commit, image, duration, status, stdout, stderr). .TP \fI/var/log/witryna//\-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() }