|
| 1 | +use semver::Version; |
| 2 | +use std::io::ErrorKind; |
| 3 | +use std::path::Path; |
| 4 | +use std::process::{Command, Stdio}; |
| 5 | + |
| 6 | +pub fn check(root: &Path, cargo: &Path, bad: &mut bool) { |
| 7 | + let result = Command::new("x").arg("--wrapper-version").stdout(Stdio::piped()).spawn(); |
| 8 | + // This runs the command inside a temporary directory. |
| 9 | + // This allows us to compare output of result to see if `--wrapper-version` is not a recognized argument to x. |
| 10 | + let temp_result = Command::new("x") |
| 11 | + .arg("--wrapper-version") |
| 12 | + .current_dir(std::env::temp_dir()) |
| 13 | + .stdout(Stdio::piped()) |
| 14 | + .spawn(); |
| 15 | + |
| 16 | + let (child, temp_child) = match (result, temp_result) { |
| 17 | + (Ok(child), Ok(temp_child)) => (child, temp_child), |
| 18 | + (Err(e), _) | (_, Err(e)) => match e.kind() { |
| 19 | + ErrorKind::NotFound => return, |
| 20 | + _ => return tidy_error!(bad, "failed to run `x`: {}", e), |
| 21 | + }, |
| 22 | + }; |
| 23 | + |
| 24 | + let output = child.wait_with_output().unwrap(); |
| 25 | + let temp_output = temp_child.wait_with_output().unwrap(); |
| 26 | + |
| 27 | + if output != temp_output { |
| 28 | + return tidy_error!( |
| 29 | + bad, |
| 30 | + "Current version of x does not support the `--wrapper-version` argument\nConsider updating to the newer version of x by running `cargo install --path src/tools/x`" |
| 31 | + ); |
| 32 | + } |
| 33 | + |
| 34 | + if output.status.success() { |
| 35 | + let version = String::from_utf8_lossy(&output.stdout); |
| 36 | + let version = Version::parse(version.trim_end()).unwrap(); |
| 37 | + |
| 38 | + if let Some(expected) = get_x_wrapper_version(root, cargo) { |
| 39 | + if version < expected { |
| 40 | + return tidy_error!( |
| 41 | + bad, |
| 42 | + "Current version of x is {version}, but the latest version is {expected}\nConsider updating to the newer version of x by running `cargo install --path src/tools/x`" |
| 43 | + ); |
| 44 | + } |
| 45 | + } else { |
| 46 | + return tidy_error!( |
| 47 | + bad, |
| 48 | + "Unable to parse the latest version of `x` at `src/tools/x/Cargo.toml`" |
| 49 | + ); |
| 50 | + } |
| 51 | + } else { |
| 52 | + return tidy_error!(bad, "failed to check version of `x`: {}", output.status); |
| 53 | + } |
| 54 | +} |
| 55 | + |
| 56 | +// Parse latest version out of `x` Cargo.toml |
| 57 | +fn get_x_wrapper_version(root: &Path, cargo: &Path) -> Option<Version> { |
| 58 | + let mut cmd = cargo_metadata::MetadataCommand::new(); |
| 59 | + cmd.cargo_path(cargo) |
| 60 | + .manifest_path(root.join("src/tools/x/Cargo.toml")) |
| 61 | + .no_deps() |
| 62 | + .features(cargo_metadata::CargoOpt::AllFeatures); |
| 63 | + let mut metadata = t!(cmd.exec()); |
| 64 | + metadata.packages.pop().map(|x| x.version) |
| 65 | +} |
0 commit comments