summaryrefslogtreecommitdiff
path: root/build.rs
diff options
context:
space:
mode:
Diffstat (limited to 'build.rs')
-rw-r--r--build.rs150
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()
+}