118 lines
3.2 KiB
Rust
118 lines
3.2 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 struct RenderedTree {
|
|
repo_dir: std::path::PathBuf,
|
|
dot_file: std::path::PathBuf,
|
|
svg_file: std::path::PathBuf,
|
|
}
|
|
|
|
pub async fn render(
|
|
_ctx: &crate::Context,
|
|
tree: &crate::tree::Tree,
|
|
) -> anyhow::Result<RenderedTree> {
|
|
let repo_dir = std::path::PathBuf::from("render-git");
|
|
|
|
if repo_dir.is_dir() {
|
|
log::info!("Found old {repo_dir:?} repository, removing...");
|
|
std::fs::remove_dir_all(&repo_dir).context("Failed to remove stale render repository")?;
|
|
}
|
|
|
|
std::fs::create_dir(&repo_dir).context("Failed creating directory for rendered graph")?;
|
|
|
|
let dot_file = repo_dir.join("techtree.dot");
|
|
let svg_file = repo_dir.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")?;
|
|
|
|
Ok(RenderedTree {
|
|
repo_dir,
|
|
dot_file,
|
|
svg_file,
|
|
})
|
|
}
|
|
|
|
pub async fn publish(ctx: &crate::Context, rendered: &RenderedTree) -> anyhow::Result<()> {
|
|
Command::new("git")
|
|
.arg("-C")
|
|
.arg(&rendered.repo_dir)
|
|
.arg("init")
|
|
.arg("--initial-branch=render")
|
|
.arg("--quiet")
|
|
.success()
|
|
.context("Failed to initialize render repository")?;
|
|
|
|
Command::new("git")
|
|
.arg("-C")
|
|
.arg(&rendered.repo_dir)
|
|
.args(["config", "user.email", "git@fa-fo.de"])
|
|
.success()
|
|
.context("Failed to configure identity for render repo")?;
|
|
|
|
Command::new("git")
|
|
.arg("-C")
|
|
.arg(&rendered.repo_dir)
|
|
.args(["config", "user.name", "Forgejo Actions"])
|
|
.success()
|
|
.context("Failed to configure identity for render repo")?;
|
|
|
|
Command::new("git")
|
|
.arg("-C")
|
|
.arg(&rendered.repo_dir)
|
|
.arg("add")
|
|
.arg(rendered.dot_file.strip_prefix(&rendered.repo_dir).unwrap())
|
|
.arg(rendered.svg_file.strip_prefix(&rendered.repo_dir).unwrap())
|
|
.success()
|
|
.context("Failed to add generated graph files to git index")?;
|
|
|
|
Command::new("git")
|
|
.arg("-C")
|
|
.arg(&rendered.repo_dir)
|
|
.arg("commit")
|
|
.args(["-m", &format!("Updated techtree at {}", ctx.timestamp)])
|
|
.success()
|
|
.context("Failed to add generated graph files to git index")?;
|
|
|
|
Command::new("git")
|
|
.arg("-C")
|
|
.arg(&rendered.repo_dir)
|
|
.arg("push")
|
|
.arg("--force")
|
|
.arg("--quiet")
|
|
.arg(
|
|
ctx.repo_auth_url
|
|
.as_ref()
|
|
.expect("cannot publish without authentication token")
|
|
.to_string(),
|
|
)
|
|
.arg("HEAD:refs/heads/render")
|
|
.status()
|
|
.context("Failed to push rendered graph to forgejo repository")?;
|
|
|
|
Ok(())
|
|
}
|