Skip to content

Commit 717adc8

Browse files
authored
Auto merge of #3246 - alexcrichton:mtimes-in-the-past, r=alexcrichton
Continuation of #2880 Just applied a patch to help fix the tests.
2 parents da5233f + db6db92 commit 717adc8

File tree

3 files changed

+108
-18
lines changed

3 files changed

+108
-18
lines changed

src/cargo/ops/cargo_rustc/fingerprint.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -191,13 +191,21 @@ impl Fingerprint {
191191
a, b)
192192
}
193193
}
194-
(&LocalFingerprint::MtimeBased(ref a, ref ap),
195-
&LocalFingerprint::MtimeBased(ref b, ref bp)) => {
196-
let a = a.0.lock().unwrap();
197-
let b = b.0.lock().unwrap();
198-
if *a != *b {
199-
bail!("mtime based components have changed: {:?} != {:?}, \
200-
paths are {:?} and {:?}", *a, *b, ap, bp)
194+
(&LocalFingerprint::MtimeBased(ref on_disk_mtime, ref ap),
195+
&LocalFingerprint::MtimeBased(ref previously_built_mtime, ref bp)) => {
196+
let on_disk_mtime = on_disk_mtime.0.lock().unwrap();
197+
let previously_built_mtime = previously_built_mtime.0.lock().unwrap();
198+
199+
let should_rebuild = match (*on_disk_mtime, *previously_built_mtime) {
200+
(None, None) => false,
201+
(Some(_), None) | (None, Some(_)) => true,
202+
(Some(on_disk), Some(previously_built)) => on_disk > previously_built,
203+
};
204+
205+
if should_rebuild {
206+
bail!("mtime based components have changed: previously {:?} now {:?}, \
207+
paths are {:?} and {:?}",
208+
*previously_built_mtime, *on_disk_mtime, ap, bp)
201209
}
202210
}
203211
_ => bail!("local fingerprint type has changed"),

tests/cargotest/support/paths.rs

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,17 @@ pub fn home() -> PathBuf {
5858
pub trait CargoPathExt {
5959
fn rm_rf(&self);
6060
fn mkdir_p(&self);
61-
fn move_into_the_past(&self);
61+
62+
fn move_into_the_past(&self) {
63+
self.move_in_time(|sec, nsec| (sec - 3600, nsec))
64+
}
65+
66+
fn move_into_the_future(&self) {
67+
self.move_in_time(|sec, nsec| (sec + 3600, nsec))
68+
}
69+
70+
fn move_in_time<F>(&self, F)
71+
where F: Fn(u64, u32) -> (u64, u32);
6272
}
6373

6474
impl CargoPathExt for Path {
@@ -91,31 +101,37 @@ impl CargoPathExt for Path {
91101
})
92102
}
93103

94-
fn move_into_the_past(&self) {
104+
fn move_in_time<F>(&self, travel_amount: F)
105+
where F: Fn(u64, u32) -> ((u64, u32)),
106+
{
95107
if self.is_file() {
96-
time_travel(self);
108+
time_travel(self, &travel_amount);
97109
} else {
98-
recurse(self, &self.join("target"));
110+
recurse(self, &self.join("target"), &travel_amount);
99111
}
100112

101-
fn recurse(p: &Path, bad: &Path) {
113+
fn recurse<F>(p: &Path, bad: &Path, travel_amount: &F)
114+
where F: Fn(u64, u32) -> ((u64, u32)),
115+
{
102116
if p.is_file() {
103-
time_travel(p)
117+
time_travel(p, travel_amount)
104118
} else if !p.starts_with(bad) {
105119
for f in t!(fs::read_dir(p)) {
106120
let f = t!(f).path();
107-
recurse(&f, bad);
121+
recurse(&f, bad, travel_amount);
108122
}
109123
}
110124
}
111125

112-
fn time_travel(path: &Path) {
126+
fn time_travel<F>(path: &Path, travel_amount: &F)
127+
where F: Fn(u64, u32) -> ((u64, u32)),
128+
{
113129
let stat = t!(path.metadata());
114130

115131
let mtime = FileTime::from_last_modification_time(&stat);
116-
let newtime = mtime.seconds_relative_to_1970() - 3600;
117-
let nanos = mtime.nanoseconds();
118-
let newtime = FileTime::from_seconds_since_1970(newtime, nanos);
132+
133+
let (sec, nsec) = travel_amount(mtime.seconds_relative_to_1970(), mtime.nanoseconds());
134+
let newtime = FileTime::from_seconds_since_1970(sec, nsec);
119135

120136
// Sadly change_file_times has a failure mode where a readonly file
121137
// cannot have its times changed on windows.

tests/freshness.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,3 +370,69 @@ fn same_build_dir_cached_packages() {
370370
[FINISHED] debug [unoptimized + debuginfo] target(s) in [..]
371371
", dir = p.url())));
372372
}
373+
374+
#[test]
375+
fn no_rebuild_if_build_artifacts_move_backwards_in_time() {
376+
let p = project("backwards_in_time")
377+
.file("Cargo.toml", r#"
378+
[package]
379+
name = "backwards_in_time"
380+
version = "0.0.1"
381+
authors = []
382+
383+
[dependencies]
384+
a = { path = "a" }
385+
"#)
386+
.file("src/lib.rs", "")
387+
.file("a/Cargo.toml", r#"
388+
[package]
389+
name = "a"
390+
version = "0.0.1"
391+
authors = []
392+
"#)
393+
.file("a/src/lib.rs", "");
394+
395+
assert_that(p.cargo_process("build"),
396+
execs().with_status(0));
397+
398+
p.root().move_into_the_past();
399+
400+
assert_that(p.cargo("build"),
401+
execs().with_status(0).with_stdout("").with_stderr("\
402+
[FINISHED] [..]
403+
"));
404+
}
405+
406+
#[test]
407+
fn rebuild_if_build_artifacts_move_forward_in_time() {
408+
let p = project("forwards_in_time")
409+
.file("Cargo.toml", r#"
410+
[package]
411+
name = "forwards_in_time"
412+
version = "0.0.1"
413+
authors = []
414+
415+
[dependencies]
416+
a = { path = "a" }
417+
"#)
418+
.file("src/lib.rs", "")
419+
.file("a/Cargo.toml", r#"
420+
[package]
421+
name = "a"
422+
version = "0.0.1"
423+
authors = []
424+
"#)
425+
.file("a/src/lib.rs", "");
426+
427+
assert_that(p.cargo_process("build"),
428+
execs().with_status(0));
429+
430+
p.root().move_into_the_future();
431+
432+
assert_that(p.cargo("build").env("RUST_LOG", ""),
433+
execs().with_status(0).with_stdout("").with_stderr("\
434+
[COMPILING] a v0.0.1 ([..])
435+
[COMPILING] forwards_in_time v0.0.1 ([..])
436+
[FINISHED] [..]
437+
"));
438+
}

0 commit comments

Comments
 (0)