Skip to content

Commit 138256f

Browse files
committed
Replace unstable fs::set_modified() with ad-hoc "touch" function.
1 parent 7b3a1e2 commit 138256f

File tree

3 files changed

+66
-7
lines changed

3 files changed

+66
-7
lines changed

src/book/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ impl MDBook {
312312
if let Some(package_dir) = &self.config.rust.package_dir {
313313
extern_args.load(&package_dir)?;
314314
}
315-
315+
316316
let mut failed = false;
317317
for item in book.iter() {
318318
if let BookItem::Chapter(ref ch) = *item {

src/config.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1368,7 +1368,6 @@ mod tests {
13681368
);
13691369
}
13701370

1371-
13721371
/* todo -- make this test fail, as it should
13731372
#[test]
13741373
#[should_panic(expected = "Invalid configuration file")]

src/utils/extern_args.rs

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
33
use crate::errors::*;
44
use log::{info, warn};
5+
use std::fs;
56
use std::fs::File;
7+
use std::io::prelude::*;
68
use std::path::{Path, PathBuf};
79
use std::process::Command;
810

@@ -62,8 +64,7 @@ impl ExternArgs {
6264
let try_path: PathBuf = [&proj_root.to_string_lossy(), "src", fname]
6365
.iter()
6466
.collect();
65-
let f = File::options().append(true).open(&try_path)?;
66-
f.set_modified(std::time::SystemTime::now())?;
67+
touch(&try_path)?;
6768
break;
6869
// file should be closed when f goes out of scope at bottom of this loop
6970
}
@@ -103,10 +104,16 @@ impl ExternArgs {
103104
self.suffix_args
104105
.push(arg_iter.next().unwrap_or("").to_owned());
105106
}
106-
"--extern" => { // needs a hack to force reference to rlib over rmeta
107+
"--extern" => {
108+
// needs a hack to force reference to rlib over rmeta
107109
self.suffix_args.push(arg.to_owned());
108-
self.suffix_args
109-
.push(arg_iter.next().unwrap_or("").replace(".rmeta", ".rlib").to_owned());
110+
self.suffix_args.push(
111+
arg_iter
112+
.next()
113+
.unwrap_or("")
114+
.replace(".rmeta", ".rlib")
115+
.to_owned(),
116+
);
110117
}
111118
_ => {}
112119
}
@@ -129,9 +136,31 @@ impl ExternArgs {
129136
}
130137
}
131138

139+
// Private "touch" function to update file modification time without changing content.
140+
// needed because [std::fs::set_modified] is unstable in rust 1.74,
141+
// which is currently the MSRV for mdBook. It is available in rust 1.76 onward.
142+
143+
fn touch(victim: &Path) -> Result<()> {
144+
let curr_content = fs::read(victim).with_context(|| "reading existing file")?;
145+
let mut touchfs = File::options()
146+
.append(true)
147+
.open(victim)
148+
.with_context(|| "opening for touch")?;
149+
150+
let _len_written = touchfs.write(b"z")?; // write a byte
151+
touchfs.flush().expect("closing"); // close the file
152+
drop(touchfs); // close modified file, hopefully updating modification time
153+
154+
fs::write(victim, curr_content).with_context(|| "trying to restore old content")
155+
}
156+
132157
#[cfg(test)]
133158
mod test {
134159
use super::*;
160+
use std::fs;
161+
use std::thread;
162+
use std::time::Duration;
163+
use tempfile;
135164

136165
#[test]
137166
fn parse_response_parses_string() -> Result<()> {
@@ -166,4 +195,35 @@ mod test {
166195

167196
Ok(())
168197
}
198+
199+
#[test]
200+
fn verify_touch() -> Result<()> {
201+
const FILE_CONTENT: &[u8] =
202+
b"I am some random text with crlfs \r\n but also nls \n and terminated with a nl \n";
203+
const DELAY: Duration = Duration::from_millis(10); // don't hang up tests for too long.
204+
205+
let temp_dir = tempfile::TempDir::new()?;
206+
let mut victim_path = temp_dir.path().to_owned();
207+
victim_path.push("workfile.dir");
208+
fs::write(&victim_path, FILE_CONTENT)?;
209+
let old_md = fs::metadata(&victim_path)?;
210+
thread::sleep(DELAY);
211+
212+
touch(&victim_path)?;
213+
let new_md = fs::metadata(&victim_path)?;
214+
215+
let act_content = fs::read(&victim_path)?;
216+
217+
assert_eq!(FILE_CONTENT, act_content);
218+
assert!(
219+
new_md
220+
.modified()
221+
.expect("getting modified time")
222+
.duration_since(old_md.modified().expect("getting modified time old"))
223+
.expect("system botch")
224+
>= DELAY
225+
);
226+
227+
Ok(())
228+
}
169229
}

0 commit comments

Comments
 (0)