mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-28 11:20:36 +00:00
Use the same filename hash for pre-release channels.
This commit is contained in:
parent
805462e971
commit
6e3f35b20a
@ -614,7 +614,7 @@ fn compute_metadata<'a, 'cfg>(
|
||||
unit.target.name().hash(&mut hasher);
|
||||
unit.target.kind().hash(&mut hasher);
|
||||
|
||||
bcx.rustc().verbose_version.hash(&mut hasher);
|
||||
hash_rustc_version(bcx, &mut hasher);
|
||||
|
||||
if cx.bcx.ws.is_member(unit.pkg) {
|
||||
// This is primarily here for clippy. This ensures that the clippy
|
||||
@ -641,3 +641,35 @@ fn compute_metadata<'a, 'cfg>(
|
||||
|
||||
Some(Metadata(hasher.finish()))
|
||||
}
|
||||
|
||||
fn hash_rustc_version(bcx: &BuildContext<'_, '_>, hasher: &mut SipHasher) {
|
||||
let vers = &bcx.rustc().version;
|
||||
if vers.pre.is_empty() {
|
||||
// For stable, keep the artifacts separate. This helps if someone is
|
||||
// testing multiple versions, to avoid recompiles.
|
||||
bcx.rustc().verbose_version.hash(hasher);
|
||||
return;
|
||||
}
|
||||
// On "nightly"/"beta"/"dev"/etc, keep each "channel" separate. Don't hash
|
||||
// the date/git information, so that whenever someone updates "nightly",
|
||||
// they won't have a bunch of stale artifacts in the target directory.
|
||||
//
|
||||
// This assumes that the first segment is the important bit ("nightly",
|
||||
// "beta", "dev", etc.). Skip other parts like the `.3` in `-beta.3`.
|
||||
vers.pre[0].hash(hasher);
|
||||
// Keep "host" since some people switch hosts to implicitly change
|
||||
// targets, (like gnu vs musl or gnu vs msvc). In the future, we may want
|
||||
// to consider hashing `unit.kind.short_name()` instead.
|
||||
bcx.rustc().host.hash(hasher);
|
||||
// None of the other lines are important. Currently they are:
|
||||
// binary: rustc <-- or "rustdoc"
|
||||
// commit-hash: 38114ff16e7856f98b2b4be7ab4cd29b38bed59a
|
||||
// commit-date: 2020-03-21
|
||||
// host: x86_64-apple-darwin
|
||||
// release: 1.44.0-nightly
|
||||
// LLVM version: 9.0
|
||||
//
|
||||
// The backend version ("LLVM version") might become more relevant in
|
||||
// the future when cranelift sees more use, and people want to switch
|
||||
// between different backends without recompiling.
|
||||
}
|
||||
|
@ -25,6 +25,8 @@ pub struct Rustc {
|
||||
pub workspace_wrapper: Option<PathBuf>,
|
||||
/// Verbose version information (the output of `rustc -vV`)
|
||||
pub verbose_version: String,
|
||||
/// The rustc version (`1.23.4-beta.2`), this comes from verbose_version.
|
||||
pub version: semver::Version,
|
||||
/// The host triple (arch-platform-OS), this comes from verbose_version.
|
||||
pub host: InternedString,
|
||||
cache: Mutex<Cache>,
|
||||
@ -51,25 +53,34 @@ impl Rustc {
|
||||
cmd.arg("-vV");
|
||||
let verbose_version = cache.cached_output(&cmd)?.0;
|
||||
|
||||
let host = {
|
||||
let triple = verbose_version
|
||||
let extract = |field: &str| -> CargoResult<&str> {
|
||||
verbose_version
|
||||
.lines()
|
||||
.find(|l| l.starts_with("host: "))
|
||||
.map(|l| &l[6..])
|
||||
.find(|l| l.starts_with(field))
|
||||
.map(|l| &l[field.len()..])
|
||||
.ok_or_else(|| {
|
||||
anyhow::format_err!(
|
||||
"`rustc -vV` didn't have a line for `host:`, got:\n{}",
|
||||
"`rustc -vV` didn't have a line for `{}`, got:\n{}",
|
||||
field.trim(),
|
||||
verbose_version
|
||||
)
|
||||
})?;
|
||||
InternedString::new(triple)
|
||||
})
|
||||
};
|
||||
|
||||
let host = InternedString::new(extract("host: ")?);
|
||||
let version = semver::Version::parse(extract("release: ")?).chain_err(|| {
|
||||
format!(
|
||||
"rustc version does not appear to be a valid semver version, from:\n{}",
|
||||
verbose_version
|
||||
)
|
||||
})?;
|
||||
|
||||
Ok(Rustc {
|
||||
path,
|
||||
wrapper,
|
||||
workspace_wrapper,
|
||||
verbose_version,
|
||||
version,
|
||||
host,
|
||||
cache: Mutex::new(cache),
|
||||
})
|
||||
|
@ -11,8 +11,7 @@ use std::time::SystemTime;
|
||||
|
||||
use cargo_test_support::paths::{self, CargoPathExt};
|
||||
use cargo_test_support::registry::Package;
|
||||
use cargo_test_support::sleep_ms;
|
||||
use cargo_test_support::{basic_manifest, is_coarse_mtime, project};
|
||||
use cargo_test_support::{basic_manifest, is_coarse_mtime, project, rustc_host, sleep_ms};
|
||||
|
||||
#[cargo_test]
|
||||
fn modifying_and_moving() {
|
||||
@ -2150,3 +2149,177 @@ fn rerun_if_changes() {
|
||||
.with_stderr("[FINISHED] [..]")
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn channel_shares_filenames() {
|
||||
// Test that different "nightly" releases use the same output filename.
|
||||
|
||||
// Create separate rustc binaries to emulate running different toolchains.
|
||||
let nightly1 = format!(
|
||||
"\
|
||||
rustc 1.44.0-nightly (38114ff16 2020-03-21)
|
||||
binary: rustc
|
||||
commit-hash: 38114ff16e7856f98b2b4be7ab4cd29b38bed59a
|
||||
commit-date: 2020-03-21
|
||||
host: {}
|
||||
release: 1.44.0-nightly
|
||||
LLVM version: 9.0
|
||||
",
|
||||
rustc_host()
|
||||
);
|
||||
|
||||
let nightly2 = format!(
|
||||
"\
|
||||
rustc 1.44.0-nightly (a5b09d354 2020-03-31)
|
||||
binary: rustc
|
||||
commit-hash: a5b09d35473615e7142f5570f5c5fad0caf68bd2
|
||||
commit-date: 2020-03-31
|
||||
host: {}
|
||||
release: 1.44.0-nightly
|
||||
LLVM version: 9.0
|
||||
",
|
||||
rustc_host()
|
||||
);
|
||||
|
||||
let beta1 = format!(
|
||||
"\
|
||||
rustc 1.43.0-beta.3 (4c587bbda 2020-03-25)
|
||||
binary: rustc
|
||||
commit-hash: 4c587bbda04ab55aaf56feab11dfdfe387a85d7a
|
||||
commit-date: 2020-03-25
|
||||
host: {}
|
||||
release: 1.43.0-beta.3
|
||||
LLVM version: 9.0
|
||||
",
|
||||
rustc_host()
|
||||
);
|
||||
|
||||
let beta2 = format!(
|
||||
"\
|
||||
rustc 1.42.0-beta.5 (4e1c5f0e9 2020-02-28)
|
||||
binary: rustc
|
||||
commit-hash: 4e1c5f0e9769a588b91c977e3d81e140209ef3a2
|
||||
commit-date: 2020-02-28
|
||||
host: {}
|
||||
release: 1.42.0-beta.5
|
||||
LLVM version: 9.0
|
||||
",
|
||||
rustc_host()
|
||||
);
|
||||
|
||||
let stable1 = format!(
|
||||
"\
|
||||
rustc 1.42.0 (b8cedc004 2020-03-09)
|
||||
binary: rustc
|
||||
commit-hash: b8cedc00407a4c56a3bda1ed605c6fc166655447
|
||||
commit-date: 2020-03-09
|
||||
host: {}
|
||||
release: 1.42.0
|
||||
LLVM version: 9.0
|
||||
",
|
||||
rustc_host()
|
||||
);
|
||||
|
||||
let stable2 = format!(
|
||||
"\
|
||||
rustc 1.41.1 (f3e1a954d 2020-02-24)
|
||||
binary: rustc
|
||||
commit-hash: f3e1a954d2ead4e2fc197c7da7d71e6c61bad196
|
||||
commit-date: 2020-02-24
|
||||
host: {}
|
||||
release: 1.41.1
|
||||
LLVM version: 9.0
|
||||
",
|
||||
rustc_host()
|
||||
);
|
||||
|
||||
let compiler = project()
|
||||
.at("compiler")
|
||||
.file("Cargo.toml", &basic_manifest("compiler", "0.1.0"))
|
||||
.file(
|
||||
"src/main.rs",
|
||||
r#"
|
||||
fn main() {
|
||||
if std::env::args_os().any(|a| a == "-vV") {
|
||||
print!("{}", env!("FUNKY_VERSION_TEST"));
|
||||
return;
|
||||
}
|
||||
let mut cmd = std::process::Command::new("rustc");
|
||||
cmd.args(std::env::args_os().skip(1));
|
||||
assert!(cmd.status().unwrap().success());
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.build();
|
||||
|
||||
let makeit = |version, vv| {
|
||||
// Force a rebuild.
|
||||
compiler.target_debug_dir().join("deps").rm_rf();
|
||||
compiler.cargo("build").env("FUNKY_VERSION_TEST", vv).run();
|
||||
fs::rename(compiler.bin("compiler"), compiler.bin(version)).unwrap();
|
||||
};
|
||||
makeit("nightly1", nightly1);
|
||||
makeit("nightly2", nightly2);
|
||||
makeit("beta1", beta1);
|
||||
makeit("beta2", beta2);
|
||||
makeit("stable1", stable1);
|
||||
makeit("stable2", stable2);
|
||||
|
||||
// Run `cargo check` with different rustc versions to observe its behavior.
|
||||
let p = project().file("src/lib.rs", "").build();
|
||||
|
||||
// Runs `cargo check` and returns the rmeta filename created.
|
||||
// Checks that the freshness matches the given value.
|
||||
let check = |version, fresh| -> String {
|
||||
let output = p
|
||||
.cargo("check --message-format=json")
|
||||
.env("RUSTC", compiler.bin(version))
|
||||
.exec_with_output()
|
||||
.unwrap();
|
||||
// Collect the filenames generated.
|
||||
let mut artifacts: Vec<_> = std::str::from_utf8(&output.stdout)
|
||||
.unwrap()
|
||||
.lines()
|
||||
.filter_map(|line| {
|
||||
let value: serde_json::Value = serde_json::from_str(line).unwrap();
|
||||
if value["reason"].as_str().unwrap() == "compiler-artifact" {
|
||||
assert_eq!(value["fresh"].as_bool().unwrap(), fresh);
|
||||
let filenames = value["filenames"].as_array().unwrap();
|
||||
assert_eq!(filenames.len(), 1);
|
||||
Some(filenames[0].to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
// Should only generate one rmeta file.
|
||||
assert_eq!(artifacts.len(), 1);
|
||||
artifacts.pop().unwrap()
|
||||
};
|
||||
|
||||
let nightly1_name = check("nightly1", false);
|
||||
assert_eq!(check("nightly1", true), nightly1_name);
|
||||
assert_eq!(check("nightly2", false), nightly1_name); // same as before
|
||||
assert_eq!(check("nightly2", true), nightly1_name);
|
||||
// Should rebuild going back to nightly1.
|
||||
assert_eq!(check("nightly1", false), nightly1_name);
|
||||
|
||||
let beta1_name = check("beta1", false);
|
||||
assert_ne!(beta1_name, nightly1_name);
|
||||
assert_eq!(check("beta1", true), beta1_name);
|
||||
assert_eq!(check("beta2", false), beta1_name); // same as before
|
||||
assert_eq!(check("beta2", true), beta1_name);
|
||||
// Should rebuild going back to beta1.
|
||||
assert_eq!(check("beta1", false), beta1_name);
|
||||
|
||||
let stable1_name = check("stable1", false);
|
||||
assert_ne!(stable1_name, nightly1_name);
|
||||
assert_ne!(stable1_name, beta1_name);
|
||||
let stable2_name = check("stable2", false);
|
||||
assert_ne!(stable1_name, stable2_name);
|
||||
// Check everything is fresh.
|
||||
assert_eq!(check("stable1", true), stable1_name);
|
||||
assert_eq!(check("stable2", true), stable2_name);
|
||||
assert_eq!(check("beta1", true), beta1_name);
|
||||
assert_eq!(check("nightly1", true), nightly1_name);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user