//! Stages the web client bundle for embedding (feature `web-ui`, //! architecture/web-client.md): copies `cbd-web/dist` (the trunk //! output) into `OUT_DIR/webdist`, or generates a placeholder page //! when the bundle has not been built — a plain `cargo build` must //! neither fail nor require the wasm toolchain. Deliberately no //! cargo-in-cargo: this never invokes trunk itself. use std::path::Path; fn main() { generate_cli_assets(); stage_web_bundle(); } /// Writes shell completions and a man page for `crabidy-server` into `OUT_DIR` /// every build, and additionally into `$CBD_ASSET_DIR` when set /// (architecture/cli.md D7). `cbd-cli` is a default-features (clap-only) /// build-dependency, so this never pulls tonic into ordinary builds. fn generate_cli_assets() { use clap::CommandFactory; println!("cargo:rerun-if-env-changed=CBD_ASSET_DIR"); let bin = "crabidy-server"; let command = cbd_cli::ServerCli::command(); let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR is set for build scripts"); if let Err(err) = cbd_cli::generate_assets(command.clone(), bin, Path::new(&out_dir)) { println!("cargo:warning=cannot generate CLI assets into OUT_DIR: {err}"); } if let Some(asset_dir) = std::env::var_os("CBD_ASSET_DIR") { if let Err(err) = cbd_cli::generate_assets(command, bin, Path::new(&asset_dir)) { println!("cargo:warning=cannot generate CLI assets into CBD_ASSET_DIR: {err}"); } } } /// Stages the web client bundle for embedding (feature `web-ui`). fn stage_web_bundle() { // Rerun when the bundle changes (or appears). println!("cargo:rerun-if-changed=../cbd-web/dist"); if std::env::var_os("CARGO_FEATURE_WEB_UI").is_none() { return; } let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR is set for build scripts"); let staged = Path::new(&out_dir).join("webdist"); // Start fresh so removed assets do not linger across builds. if staged.exists() { std::fs::remove_dir_all(&staged).expect("clean staged webdist"); } std::fs::create_dir_all(&staged).expect("create staged webdist"); let dist = Path::new(env!("CARGO_MANIFEST_DIR")).join("../cbd-web/dist"); if dist.join("index.html").is_file() { copy_dir(&dist, &staged); } else { println!( "cargo:warning=cbd-web/dist not found - embedding a placeholder web UI \ (build the bundle with: devenv shell -- build-web)" ); std::fs::write( staged.join("index.html"), "crabidy\ \

crabidy web UI not built

\

This server binary was compiled without the web bundle. \ Build it with devenv shell -- build-web and \ rebuild the server.

", ) .expect("write placeholder index.html"); } } /// Copies `from` into `to` recursively (regular files only — the trunk /// output contains nothing else). fn copy_dir(from: &Path, to: &Path) { for entry in std::fs::read_dir(from).expect("read dist dir") { let entry = entry.expect("dist dir entry"); let target = to.join(entry.file_name()); let path = entry.path(); if path.is_dir() { std::fs::create_dir_all(&target).expect("create staged subdir"); copy_dir(&path, &target); } else { std::fs::copy(&path, &target).expect("copy dist file"); } } }