Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 39 additions & 23 deletions crates/socket-patch-cli/tests/common/yarn_classic_vex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

use std::ffi::OsString;
use std::path::Path;
use std::process::{Command, Stdio};
use std::process::Command;

use crate::vex_e2e_common::{
assert_absent, assert_attested, assert_not_attested, binary, run_vex, statements_for,
Expand Down Expand Up @@ -112,36 +112,52 @@ pub fn skip(suite: &str, why: &str) {
/// probed from a neutral temp dir (an ancestor `packageManager` field would
/// make corepack refuse) with the suites' cache isolation applied by
/// `isolate`. On `false` the caller returns after [`skip`].
///
/// A failed fetch is retried (after 2 s, then 5 s) before it counts as
/// unavailable: one DNS blip on a CI host otherwise fails the leg under
/// [`REQUIRED_ENV`]`=1` and evicts its merge-queue entry (#1671).
pub fn require_yarn_classic(suite: &str, isolate: impl Fn(&mut Command)) -> bool {
let spec = yarn_classic();
let want = yarn_classic_version();
let probe = tempfile::tempdir().expect("tempdir");
let mut cmd = Command::new("corepack");
cmd.args([spec.as_str(), "--version"])
.current_dir(probe.path())
.env("COREPACK_ENABLE_DOWNLOAD_PROMPT", "0");
isolate(&mut cmd);
let got = cmd
.stderr(Stdio::null())
.output()
.ok()
.filter(|o| o.status.success())
.map(|o| String::from_utf8_lossy(&o.stdout).trim().to_string());
match got {
Some(v) if v == want => true,
Some(v) => {
let mut last_err = String::new();
for (attempt, backoff) in [0, 2, 5].into_iter().enumerate() {
std::thread::sleep(std::time::Duration::from_secs(backoff));
let mut cmd = Command::new("corepack");
cmd.args([spec.as_str(), "--version"])
.current_dir(probe.path())
.env("COREPACK_ENABLE_DOWNLOAD_PROMPT", "0");
isolate(&mut cmd);
let out = match cmd.output() {
Ok(out) => out,
Err(e) => {
// corepack itself is missing: retrying cannot help.
last_err = format!("cannot run corepack: {e}");
break;
}
};
if out.status.success() {
let got = String::from_utf8_lossy(&out.stdout).trim().to_string();
if got == want {
return true;
}
// A wrong release is never a skip: the leg would silently test
// another yarn.
panic!("{suite}: `corepack {spec} --version` reported {v:?}, expected {want}");
}
None => {
skip(
suite,
&format!("`corepack {spec}` unavailable (corepack absent or not fetchable)"),
);
false
panic!("{suite}: `corepack {spec} --version` reported {got:?}, expected {want}");
}
last_err = format!(
"attempt {} exited {}: {}",
attempt + 1,
out.status,
String::from_utf8_lossy(&out.stderr).trim()
);
eprintln!("{suite}: `corepack {spec} --version` failed, {last_err}");
}
skip(
suite,
&format!("`corepack {spec}` unavailable (corepack absent or not fetchable; {last_err})"),
);
false
}

// ── manifest-less VEX ─────────────────────────────────────────────────
Expand Down
Loading