techtree/techtree-manager/src/render.rs
2025-05-22 15:49:06 +02:00

98 lines
2.7 KiB
Rust

use std::process::Command;
use anyhow::Context as _;
trait SuccessExt {
fn success(&mut self) -> anyhow::Result<()>;
}
impl SuccessExt for Command {
fn success(&mut self) -> anyhow::Result<()> {
if !self.status()?.success() {
anyhow::bail!("Command returned unsuccessfully");
}
Ok(())
}
}
pub async fn render_and_publish(
tree: &crate::tree::Tree,
timestamp: &str,
repo_auth_url: &url::Url,
) -> anyhow::Result<()> {
let render_repo = std::path::PathBuf::from("render-git");
if render_repo.is_dir() {
log::info!("Found old {render_repo:?} repository, removing...");
std::fs::remove_dir_all(&render_repo)
.context("Failed to remove stale render repository")?;
}
std::fs::create_dir(&render_repo).context("Failed creating directory for rendered graph")?;
Command::new("git")
.arg("-C")
.arg(&render_repo)
.arg("init")
.success()
.context("Failed to initialize render repository")?;
Command::new("git")
.arg("-C")
.arg(&render_repo)
.args(["config", "user.email", "git@fa-fo.de"])
.success()
.context("Failed to configure identity for render repo")?;
Command::new("git")
.arg("-C")
.arg(&render_repo)
.args(["config", "user.name", "Forgejo Actions"])
.success()
.context("Failed to configure identity for render repo")?;
let dot_file = render_repo.join("techtree.dot");
let svg_file = render_repo.join("techtree.svg");
let dot_source = tree.to_dot();
std::fs::write(&dot_file, dot_source.as_bytes())
.context("Failed to write `dot` source file")?;
Command::new("dot")
.args(["-T", "svg"])
.arg("-o")
.arg(&svg_file)
.arg(&dot_file)
.success()
.context("Failed to generate svg graph from dot source")?;
Command::new("git")
.arg("-C")
.arg(&render_repo)
.arg("add")
.arg(dot_file.file_name().unwrap())
.arg(svg_file.file_name().unwrap())
.success()
.context("Failed to add generated graph files to git index")?;
Command::new("git")
.arg("-C")
.arg(&render_repo)
.arg("commit")
.args(["-m", &format!("Updated techtree at {timestamp}")])
.success()
.context("Failed to add generated graph files to git index")?;
Command::new("git")
.arg("-C")
.arg(&render_repo)
.arg("push")
.arg("--force")
.arg(repo_auth_url.to_string())
.arg("HEAD:refs/heads/render")
.status()
.context("Failed to push rendered graph to forgejo repository")?;
Ok(())
}