From 05dd9ae24f6824827c817414ce7fdc9e19fdff99 Mon Sep 17 00:00:00 2001 From: Mark Dittmer Date: Thu, 14 May 2026 13:59:43 +0000 Subject: [PATCH] Introduce standalone static-toml integration example and robust parent directory creation interfaces gherrit-pr-id: Gnatzth2id6x4gqfajqfth3pygza336dw --- anneal/Cargo.toml | 2 +- .../examples/static-toml/.cargo/config.toml | 2 + .../examples/static-toml/Cargo.toml | 26 ++++++ .../examples/static-toml/build-toolchain.sh | 18 ++++ .../examples/static-toml/build.rs | 32 +++++++ .../examples/static-toml/src/main.rs | 80 ++++++++++++++++++ .../examples/static-toml/toolchain.tar.zst | Bin 0 -> 179 bytes anneal/v2/toolchain-config/src/lib.rs | 2 + 8 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 anneal/v2/toolchain-config/examples/static-toml/.cargo/config.toml create mode 100644 anneal/v2/toolchain-config/examples/static-toml/Cargo.toml create mode 100755 anneal/v2/toolchain-config/examples/static-toml/build-toolchain.sh create mode 100644 anneal/v2/toolchain-config/examples/static-toml/build.rs create mode 100644 anneal/v2/toolchain-config/examples/static-toml/src/main.rs create mode 100644 anneal/v2/toolchain-config/examples/static-toml/toolchain.tar.zst diff --git a/anneal/Cargo.toml b/anneal/Cargo.toml index 140b637732..c625032af9 100644 --- a/anneal/Cargo.toml +++ b/anneal/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = [".", "tools/doc_gen", "v2/toolchain-config"] +members = [".", "tools/doc_gen", "v2/toolchain-config", "v2/toolchain-config/examples/static-toml"] [package] name = "cargo-anneal" diff --git a/anneal/v2/toolchain-config/examples/static-toml/.cargo/config.toml b/anneal/v2/toolchain-config/examples/static-toml/.cargo/config.toml new file mode 100644 index 0000000000..15775c774d --- /dev/null +++ b/anneal/v2/toolchain-config/examples/static-toml/.cargo/config.toml @@ -0,0 +1,2 @@ +[env] +__TOOLCHAIN_EXAMPLE_STATIC_TOML = "1" diff --git a/anneal/v2/toolchain-config/examples/static-toml/Cargo.toml b/anneal/v2/toolchain-config/examples/static-toml/Cargo.toml new file mode 100644 index 0000000000..f39a6ddb5b --- /dev/null +++ b/anneal/v2/toolchain-config/examples/static-toml/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "toolchain-config-example-static-toml" +version = "0.1.0" +edition = "2024" +publish = false + +[dependencies] +toolchain-config = { path = "../.." } +clap = { version = "4.6", features = ["derive"] } +sha2 = "0.10" +dirs = "6.0" + +[build-dependencies] +toml = "0.8" + +[package.metadata.toolchain.linux.x86_64] +checksum = "1111111111111111111111111111111111111111111111111111111111111111" +url = "http://example.com/archive.tar.zst" + +[package.metadata.toolchain.macos.aarch64] +checksum = "2222222222222222222222222222222222222222222222222222222222222222" +url = "http://example.com/macos.tar.zst" + +[package.metadata.toolchain.windows.x86_64] +checksum = "3333333333333333333333333333333333333333333333333333333333333333" +url = "http://example.com/windows.tar.zst" diff --git a/anneal/v2/toolchain-config/examples/static-toml/build-toolchain.sh b/anneal/v2/toolchain-config/examples/static-toml/build-toolchain.sh new file mode 100755 index 0000000000..631b298517 --- /dev/null +++ b/anneal/v2/toolchain-config/examples/static-toml/build-toolchain.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +TMP_DIR="$(mktemp -d)" +mkdir -p "$TMP_DIR/bin" + +cat << 'EOF' > "$TMP_DIR/bin/hello" +#!/usr/bin/env bash +echo "Hello, world!" +EOF + +chmod +x "$TMP_DIR/bin/hello" + +tar --zstd -cf "$SCRIPT_DIR/toolchain.tar.zst" -C "$TMP_DIR" . + +rm -rf "$TMP_DIR" diff --git a/anneal/v2/toolchain-config/examples/static-toml/build.rs b/anneal/v2/toolchain-config/examples/static-toml/build.rs new file mode 100644 index 0000000000..3a4e905d81 --- /dev/null +++ b/anneal/v2/toolchain-config/examples/static-toml/build.rs @@ -0,0 +1,32 @@ +fn main() { + println!("cargo:rerun-if-changed=Cargo.toml"); + + let os = std::env::consts::OS; + let arch = std::env::consts::ARCH; + + let content = std::fs::read_to_string("Cargo.toml").expect("Failed to read Cargo.toml"); + let toml: toml::Value = toml::from_str(&content).expect("Failed to parse Cargo.toml"); + + let metadata = toml + .get("package") + .and_then(|p| p.get("metadata")) + .and_then(|m| m.get("toolchain")) + .expect("Missing [package.metadata.toolchain] in Cargo.toml"); + + let target_table = metadata + .get(os) + .and_then(|o| o.get(arch)) + .unwrap_or_else(|| panic!("Missing toolchain configuration for {}.{}", os, arch)); + + let checksum = target_table + .get("checksum") + .and_then(|c| c.as_str()) + .expect("Missing checksum key"); + let url = target_table + .get("url") + .and_then(|u| u.as_str()) + .expect("Missing url key"); + + println!("cargo:rustc-env=TOOLCHAIN_CHECKSUM={}", checksum); + println!("cargo:rustc-env=TOOLCHAIN_URL={}", url); +} diff --git a/anneal/v2/toolchain-config/examples/static-toml/src/main.rs b/anneal/v2/toolchain-config/examples/static-toml/src/main.rs new file mode 100644 index 0000000000..5cf9ee755b --- /dev/null +++ b/anneal/v2/toolchain-config/examples/static-toml/src/main.rs @@ -0,0 +1,80 @@ +use clap::{Parser, Subcommand}; +use std::process::Command; +use toolchain_config::{Config, LocalOverride, TarZstLibraryExtractor}; + +#[derive(Parser)] +#[command(name = "toolchain-config-example-static-toml")] +#[command(about = "Example illustrating static TOML integration using toolchain-config library")] +struct Cli { + #[command(subcommand)] + command: Commands, +} + +#[derive(Subcommand)] +enum Commands { + Setup, + Hello, +} + +fn decode_hex(s: &str) -> Vec { + (0..s.len()) + .step_by(2) + .map(|i| u8::from_str_radix(&s[i..i + 2], 16).unwrap()) + .collect() +} + +fn get_root_dir() -> std::path::PathBuf { + let home = dirs::home_dir().expect("Could not find home directory"); + home.join(".toolchain-config-example-static-toml").join("toolchain") +} + +fn main() { + let cli = Cli::parse(); + let root_dir = get_root_dir(); + + let checksum_bytes = decode_hex(env!("TOOLCHAIN_CHECKSUM")); + let config = Config::::new( + env!("TOOLCHAIN_URL"), + &checksum_bytes, + ); + + match cli.command { + Commands::Setup => { + let local_override = if std::env::var("__TOOLCHAIN_EXAMPLE_STATIC_TOML").is_ok() { + println!("Local testing override active. Assembling mock toolchain archive..."); + let manifest_dir = std::env::var("CARGO_MANIFEST_DIR") + .expect("CARGO_MANIFEST_DIR environment variable missing"); + let script_path = std::path::Path::new(&manifest_dir).join("build-toolchain.sh"); + + let status = Command::new(&script_path) + .status() + .expect("Failed to execute build-toolchain.sh"); + assert!(status.success(), "build-toolchain.sh script failed"); + + let archive_path = std::path::Path::new(&manifest_dir).join("toolchain.tar.zst"); + Some(LocalOverride::Archive(archive_path)) + } else { + None + }; + + println!("Provisioning toolchain environment..."); + toolchain_config::setup(&config, local_override, root_dir) + .expect("Setup subcommand failed"); + println!("Toolchain successfully set up."); + } + Commands::Hello => { + let toolchain_dir = config.toolchain_dir(&root_dir); + let hello_bin = toolchain_dir.join("bin").join("hello"); + + if !hello_bin.exists() { + eprintln!("Error: Toolchain executable missing at {:?}. Please run setup first.", hello_bin); + std::process::exit(1); + } + + let status = Command::new(&hello_bin) + .status() + .expect("Failed to delegate execution to bin/hello"); + std::process::exit(status.code().unwrap_or(1)); + } + } +} diff --git a/anneal/v2/toolchain-config/examples/static-toml/toolchain.tar.zst b/anneal/v2/toolchain-config/examples/static-toml/toolchain.tar.zst new file mode 100644 index 0000000000000000000000000000000000000000..9ee1244aaa84105db36c5d2e47d55a78b9485d1e GIT binary patch literal 179 zcmV;k08IZVwJ-eySTzLz(nuX0P-Scmz+njrz7o~FKB_{-=zj)n665hmGy9xM282;G za3g>UB7|>XXmkjVa3;s-A$mJiND;8+awS=h5I%=B<( extractor: &E, ) -> Result, std::io::Error> { let parent = dst.parent().expect("toolchains directory has parent"); + std::fs::create_dir_all(parent)?; let temp_dir = tempfile::Builder::new().prefix("setup-").tempdir_in(parent)?; let mut hash_reader = HashReader::<_, D>::new(src); @@ -186,6 +187,7 @@ fn link_or_copy_dir(src: &std::path::Path, dst: &std::path::Path) -> std::io::Re fn setup_from_directory(src: &std::path::Path, dst: &std::path::Path) -> Result<(), String> { let parent = dst.parent().expect("toolchains directory has parent"); + std::fs::create_dir_all(parent).map_err(|e| format!("Failed to create toolchain parent directory: {e}"))?; let old_dir = if dst.symlink_metadata().is_ok() { let old = tempfile::Builder::new() .prefix("setup-old-")