use anyhow::{Context as _, Result}; use cargo_metadata::Metadata; use indoc::{indoc, writedoc}; use std::{ffi::OsString, fs, io::Write as _, process::Command}; use xtask::exec; pub fn docs(metadata: Metadata) -> Result<()> { const PACKAGE_TO_DESCRIPTION: &[(&str, &str)] = &[ ("aya", "User-space BPF program loading and manipulation"), ("aya-bpf", "Kernel-space BPF program implementation toolkit"), ("aya-log-ebpf", "Kernel-space logging from BPF programs"), ( "aya-log", "User-space consumption of logs from BPF programs", ), ]; let Metadata { workspace_root, target_directory, .. } = metadata; exec( Command::new("cargo") .current_dir(&workspace_root) .args(["clean", "--doc"]), )?; let tmp = tempfile::tempdir().context("create tempdir")?; let header = tmp.path().join("header.html"); fs::write(&header, r#""#).context("write header.html")?; let mut rustdocflags = OsString::new(); rustdocflags.push("--cfg docsrs --html-in-header "); rustdocflags.push(header); rustdocflags.push(" -D warnings"); exec( Command::new("cargo") .current_dir(&workspace_root) .env("RUSTDOCFLAGS", rustdocflags) .args(["+nightly", "doc", "--no-deps", "--all-features"]) .args( PACKAGE_TO_DESCRIPTION .iter() .flat_map(|(package, _)| ["--package", package]), ), )?; let site = workspace_root.join("site"); match fs::remove_dir_all(&site) { Ok(()) => {} Err(err) => { if err.kind() != std::io::ErrorKind::NotFound { return Err(err).context(format!("remove {site:?}")); } } } let doc = target_directory.join("doc"); fs::rename(&doc, &site).with_context(|| format!("rename {doc:?} to {site:?}"))?; exec(Command::new("sh").current_dir(&site).args([ "-c", "grep -FRl crabby.svg | xargs sed -i s/crabby.svg/crabby_dev.svg/g", ]))?; fs::write( site.join("robots.txt"), indoc! {r#" User-Agent:* Disallow: / "#}, ) .context("can't write robots.txt")?; let mut index = fs::File::create(site.join("index.html")) .with_context(|| format!("create {site:?}/index.html"))?; writedoc! {&mut index, r#" "#} .context("write to index.html")?; Ok(()) }