diff --git a/Cargo.toml b/Cargo.toml index 7ef49829..da46f9a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -86,7 +86,6 @@ network-types = { version = "0.0.7", default-features = false } nix = { version = "0.29.0", default-features = false } num_enum = { version = "0.7", default-features = false } object = { version = "0.36", default-features = false } -octorust = { version = "0.10", default-features = false } once_cell = { version = "1.20.1", default-features = false } proc-macro2 = { version = "1", default-features = false } proc-macro2-diagnostics = { version = "0.10.1", default-features = false } diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 922ad62b..1623ba5e 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -16,13 +16,11 @@ workspace = true [dependencies] anyhow = { workspace = true, features = ["std"] } aya-tool = { path = "../aya-tool", version = "0.1.0", default-features = false } -base64 = { workspace = true, features = ["std"] } cargo_metadata = { workspace = true } clap = { workspace = true, features = ["derive"] } dialoguer = { workspace = true } diff = { workspace = true } indoc = { workspace = true } -octorust = { workspace = true, features = ["rustls-tls"] } proc-macro2 = { workspace = true } public-api = { workspace = true } quote = { workspace = true } @@ -30,6 +28,5 @@ rustdoc-json = { workspace = true } rustup-toolchain = { workspace = true } syn = { workspace = true } tempfile = { workspace = true } -tokio = { workspace = true, features = ["rt"] } walkdir = { workspace = true } which = { workspace = true } diff --git a/xtask/src/run.rs b/xtask/src/run.rs index d5a48ebe..0cf1738d 100644 --- a/xtask/src/run.rs +++ b/xtask/src/run.rs @@ -11,7 +11,6 @@ use std::{ }; use anyhow::{Context as _, Result, anyhow, bail}; -use base64::engine::Engine as _; use cargo_metadata::{Artifact, CompilerMessage, Message, Target}; use clap::Parser; use walkdir::WalkDir; @@ -229,55 +228,69 @@ pub fn run(opts: Options) -> Result<()> { create_dir_all(&cache_dir).context("failed to create cache dir")?; let gen_init_cpio = cache_dir.join("gen_init_cpio"); - if !gen_init_cpio - .try_exists() - .context("failed to check existence of gen_init_cpio")? + let etag_path = cache_dir.join("gen_init_cpio.etag"); { - // TODO(https://github.com/oxidecomputer/third-party-api-clients/issues/96): Use ETag-based caching. - let client = octorust::Client::new( - String::from("aya-xtask-integration-test-run"), - github_api_token.map(octorust::auth::Credentials::Token), - )?; - let octorust::Response { - status: _, - headers: _, - body: octorust::types::ContentFile { mut content, .. }, - } = tokio::runtime::Builder::new_current_thread() - .enable_all() - .build() - .unwrap() - .block_on(client.repos().get_content_file( - "torvalds", - "linux", - "usr/gen_init_cpio.c", - "master", - )) - .context("failed to download gen_init_cpio.c")?; - // Github very helpfully wraps their base64 at 10 columns /s. - content.retain(|c| !c.is_whitespace()); - let content = base64::engine::general_purpose::STANDARD - .decode(content) - .context("failed to decode gen_init_cpio.c")?; + let gen_init_cpio_exists = gen_init_cpio.try_exists().with_context(|| { + format!("failed to check existence of {}", gen_init_cpio.display()) + })?; + let etag_path_exists = etag_path.try_exists().with_context(|| { + format!("failed to check existence of {}", etag_path.display()) + })?; + if !gen_init_cpio_exists && etag_path_exists { + println!( + "cargo:warning=({}).exists()={} != ({})={} (mismatch)", + gen_init_cpio.display(), + gen_init_cpio_exists, + etag_path.display(), + etag_path_exists, + ) + } + } + + let gen_init_cpio_source = { + drop(github_api_token); // Currently unused, but kept around in case we need it in the future. + let mut curl = Command::new("curl"); + curl.args([ + "-sfSL", + "https://raw.githubusercontent.com/torvalds/linux/master/usr/gen_init_cpio.c", + ]); + for arg in ["--etag-compare", "--etag-save"] { + curl.arg(arg).arg(&etag_path); + } + + let Output { + status, + stdout, + stderr, + } = curl + .output() + .with_context(|| format!("failed to run {curl:?}"))?; + if status.code() != Some(0) { + bail!("{curl:?} failed: stdout={stdout:?} stderr={stderr:?}") + } + stdout + }; + + if !gen_init_cpio_source.is_empty() { let mut clang = Command::new("clang"); clang .args(["-g", "-O2", "-x", "c", "-", "-o"]) - .arg(&gen_init_cpio); - let mut child = clang - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) + .arg(&gen_init_cpio) + .stdin(Stdio::piped()); + let mut clang_child = clang .spawn() .with_context(|| format!("failed to spawn {clang:?}"))?; - let Child { stdin, .. } = &mut child; + let Child { stdin, .. } = &mut clang_child; + let mut stdin = stdin.take().unwrap(); stdin - .write_all(&content) + .write_all(&gen_init_cpio_source) .with_context(|| format!("failed to write to {clang:?} stdin"))?; - std::mem::drop(stdin); // Send EOF. + drop(stdin); // Must explicitly close to signal EOF. - let output = child + let output = clang_child .wait_with_output() .with_context(|| format!("failed to wait for {clang:?}"))?; let Output { status, .. } = &output;