Skip to content

Commit 9d3c23e

Browse files
committed
Auto merge of rust-lang#125736 - Oneirical:run-make-file-management, r=<try>
run-make-support: add helpers for `tmp_dir().join()` and `fs` operations Suggested by rust-lang#125728. The point of this wrapper is to stop silent fails caused by forgetting to `unwrap` `fs` functions. However, functions like `fs::read` which return something and get stored in a variable should cause a failure on their own if they are not unwrapped (as the `Result` will be stored in the variable, and something will be done on that `Result` that should have been done to its contents). Is it still pertinent to wrap `fs::read_to_string`, `fs::metadata` and so on? try-job: x86_64-msvc try-job: i686-mingw
2 parents e1ac0fa + c76d3b4 commit 9d3c23e

File tree

65 files changed

+339
-227
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+339
-227
lines changed

src/tools/run-make-support/src/cc.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ use std::path::Path;
22
use std::process::Command;
33

44
use crate::{
5-
bin_name, cygpath_windows, env_var, handle_failed_output, is_msvc, is_windows, tmp_dir, uname,
5+
bin_name, cygpath_windows, env_var, handle_failed_output, is_msvc, is_windows, rmake_out_path,
6+
uname,
67
};
78

89
/// Construct a new platform-specific C compiler invocation.
@@ -69,13 +70,13 @@ impl Cc {
6970
// ```
7071

7172
if is_msvc() {
72-
let fe_path = cygpath_windows(tmp_dir().join(bin_name(name)));
73-
let fo_path = cygpath_windows(tmp_dir().join(format!("{name}.obj")));
73+
let fe_path = cygpath_windows(rmake_out_path(bin_name(name)));
74+
let fo_path = cygpath_windows(rmake_out_path(format!("{name}.obj")));
7475
self.cmd.arg(format!("-Fe:{fe_path}"));
7576
self.cmd.arg(format!("-Fo:{fo_path}"));
7677
} else {
7778
self.cmd.arg("-o");
78-
self.cmd.arg(tmp_dir().join(name));
79+
self.cmd.arg(rmake_out_path(name));
7980
}
8081

8182
self

src/tools/run-make-support/src/clang.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::path::Path;
22
use std::process::Command;
33

4-
use crate::{bin_name, env_var, handle_failed_output, tmp_dir};
4+
use crate::{bin_name, env_var, handle_failed_output, rmake_out_path};
55

66
/// Construct a new `clang` invocation. `clang` is not always available for all targets.
77
pub fn clang() -> Clang {
@@ -34,7 +34,7 @@ impl Clang {
3434
/// extension will be determined by [`bin_name`].
3535
pub fn out_exe(&mut self, name: &str) -> &mut Self {
3636
self.cmd.arg("-o");
37-
self.cmd.arg(tmp_dir().join(bin_name(name)));
37+
self.cmd.arg(rmake_out_path(bin_name(name)));
3838
self
3939
}
4040

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
use std::fs;
2+
use std::path::Path;
3+
4+
/// A safe wrapper around `std::fs::remove_file` that prints the file path if an operation fails.
5+
pub fn remove_file<P: AsRef<Path>>(path: P) {
6+
fs::remove_file(path.as_ref()).expect(&format!(
7+
"the file in path \"{:?}\" could not be removed.",
8+
path.as_ref().display()
9+
));
10+
}
11+
12+
/// A safe wrapper around `std::fs::copy` that prints the file paths if an operation fails.
13+
pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) {
14+
fs::copy(from.as_ref(), to.as_ref()).expect(&format!(
15+
"the file \"{:?}\" could not be copied over to \"{:?}\".",
16+
from.as_ref().display(),
17+
to.as_ref().display(),
18+
));
19+
}
20+
21+
/// A safe wrapper around `std::fs::File::create` that prints the file path if an operation fails.
22+
pub fn create_file<P: AsRef<Path>>(path: P) {
23+
fs::File::create(path.as_ref()).expect(&format!(
24+
"the file in path \"{:?}\" could not be created.",
25+
path.as_ref().display()
26+
));
27+
}
28+
29+
/// A safe wrapper around `std::fs::read` that prints the file path if an operation fails.
30+
pub fn read<P: AsRef<Path>>(path: P) -> Vec<u8> {
31+
fs::read(path.as_ref())
32+
.expect(&format!("the file in path \"{:?}\" could not be read.", path.as_ref().display()))
33+
}
34+
35+
/// A safe wrapper around `std::fs::read_to_string` that prints the file path if an operation fails.
36+
pub fn read_to_string<P: AsRef<Path>>(path: P) -> String {
37+
fs::read_to_string(path.as_ref()).expect(&format!(
38+
"the file in path \"{:?}\" could not be read into a String.",
39+
path.as_ref().display()
40+
))
41+
}
42+
43+
/// A safe wrapper around `std::fs::read_dir` that prints the file path if an operation fails.
44+
pub fn read_dir<P: AsRef<Path>>(path: P) -> fs::ReadDir {
45+
fs::read_dir(path.as_ref()).expect(&format!(
46+
"the directory in path \"{:?}\" could not be read.",
47+
path.as_ref().display()
48+
))
49+
}
50+
51+
/// A safe wrapper around `std::fs::write` that prints the file path if an operation fails.
52+
pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) {
53+
fs::write(path.as_ref(), contents.as_ref()).expect(&format!(
54+
"the file in path \"{:?}\" could not be written to.",
55+
path.as_ref().display()
56+
));
57+
}
58+
59+
/// A safe wrapper around `std::fs::remove_dir_all` that prints the file path if an operation fails.
60+
pub fn remove_dir_all<P: AsRef<Path>>(path: P) {
61+
fs::remove_dir_all(path.as_ref()).expect(&format!(
62+
"the directory in path \"{:?}\" could not be removed alongside all its contents.",
63+
path.as_ref().display(),
64+
));
65+
}
66+
67+
/// A safe wrapper around `std::fs::create_dir` that prints the file path if an operation fails.
68+
pub fn create_dir<P: AsRef<Path>>(path: P) {
69+
fs::create_dir(path.as_ref()).expect(&format!(
70+
"the directory in path \"{:?}\" could not be created.",
71+
path.as_ref().display()
72+
));
73+
}
74+
75+
/// A safe wrapper around `std::fs::create_dir_all` that prints the file path if an operation fails.
76+
pub fn create_dir_all<P: AsRef<Path>>(path: P) {
77+
fs::create_dir_all(path.as_ref()).expect(&format!(
78+
"the directory (and all its parents) in path \"{:?}\" could not be created.",
79+
path.as_ref().display()
80+
));
81+
}
82+
83+
/// A safe wrapper around `std::fs::metadata` that prints the file path if an operation fails.
84+
pub fn metadata<P: AsRef<Path>>(path: P) -> fs::Metadata {
85+
fs::metadata(path.as_ref()).expect(&format!(
86+
"the file's metadata in path \"{:?}\" could not be read.",
87+
path.as_ref().display()
88+
))
89+
}
90+
91+
/// A safe wrapper around `std::fs::rename` that prints the file paths if an operation fails.
92+
pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) {
93+
fs::rename(from.as_ref(), to.as_ref()).expect(&format!(
94+
"the file \"{:?}\" could not be moved over to \"{:?}\".",
95+
from.as_ref().display(),
96+
to.as_ref().display(),
97+
));
98+
}

src/tools/run-make-support/src/lib.rs

+16-18
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
pub mod cc;
77
pub mod clang;
88
pub mod diff;
9+
pub mod fs_wrapper;
910
pub mod llvm_readobj;
1011
pub mod run;
1112
pub mod rustc;
1213
pub mod rustdoc;
1314

1415
use std::env;
1516
use std::ffi::OsString;
16-
use std::fs;
1717
use std::io;
1818
use std::path::{Path, PathBuf};
1919
use std::process::{Command, Output};
@@ -46,10 +46,15 @@ pub fn env_var_os(name: &str) -> OsString {
4646
}
4747

4848
/// Path of `TMPDIR` (a temporary build directory, not under `/tmp`).
49-
pub fn tmp_dir() -> PathBuf {
49+
pub fn rmake_out_dir() -> PathBuf {
5050
env_var_os("TMPDIR").into()
5151
}
5252

53+
/// Returns the directory TMPDIR/name.
54+
pub fn rmake_out_path<P: AsRef<Path>>(name: P) -> PathBuf {
55+
rmake_out_dir().join(name.as_ref())
56+
}
57+
5358
/// `TARGET`
5459
pub fn target() -> String {
5560
env_var("TARGET")
@@ -73,7 +78,7 @@ pub fn is_darwin() -> bool {
7378
/// Construct a path to a static library under `$TMPDIR` given the library name. This will return a
7479
/// path with `$TMPDIR` joined with platform-and-compiler-specific library name.
7580
pub fn static_lib(name: &str) -> PathBuf {
76-
tmp_dir().join(static_lib_name(name))
81+
rmake_out_path(static_lib_name(name))
7782
}
7883

7984
pub fn python_command() -> Command {
@@ -118,7 +123,7 @@ pub fn static_lib_name(name: &str) -> String {
118123
/// Construct a path to a dynamic library under `$TMPDIR` given the library name. This will return a
119124
/// path with `$TMPDIR` joined with platform-and-compiler-specific library name.
120125
pub fn dynamic_lib(name: &str) -> PathBuf {
121-
tmp_dir().join(dynamic_lib_name(name))
126+
rmake_out_path(dynamic_lib_name(name))
122127
}
123128

124129
/// Construct the dynamic library name based on the platform.
@@ -161,7 +166,7 @@ pub fn dynamic_lib_extension() -> &'static str {
161166
/// Construct a path to a rust library (rlib) under `$TMPDIR` given the library name. This will return a
162167
/// path with `$TMPDIR` joined with the library name.
163168
pub fn rust_lib(name: &str) -> PathBuf {
164-
tmp_dir().join(rust_lib_name(name))
169+
rmake_out_path(rust_lib_name(name))
165170
}
166171

167172
/// Generate the name a rust library (rlib) would have. If you want the complete path, use
@@ -240,15 +245,15 @@ pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
240245
fn copy_dir_all_inner(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
241246
let dst = dst.as_ref();
242247
if !dst.is_dir() {
243-
fs::create_dir_all(&dst)?;
248+
std::fs::create_dir_all(&dst)?;
244249
}
245-
for entry in fs::read_dir(src)? {
250+
for entry in std::fs::read_dir(src)? {
246251
let entry = entry?;
247252
let ty = entry.file_type()?;
248253
if ty.is_dir() {
249254
copy_dir_all_inner(entry.path(), dst.join(entry.file_name()))?;
250255
} else {
251-
fs::copy(entry.path(), dst.join(entry.file_name()))?;
256+
std::fs::copy(entry.path(), dst.join(entry.file_name()))?;
252257
}
253258
}
254259
Ok(())
@@ -267,22 +272,15 @@ pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
267272

268273
/// Check that all files in `dir1` exist and have the same content in `dir2`. Panic otherwise.
269274
pub fn recursive_diff(dir1: impl AsRef<Path>, dir2: impl AsRef<Path>) {
270-
fn read_file(path: &Path) -> Vec<u8> {
271-
match fs::read(path) {
272-
Ok(c) => c,
273-
Err(e) => panic!("Failed to read `{}`: {:?}", path.display(), e),
274-
}
275-
}
276-
277275
let dir2 = dir2.as_ref();
278276
read_dir(dir1, |entry_path| {
279277
let entry_name = entry_path.file_name().unwrap();
280278
if entry_path.is_dir() {
281279
recursive_diff(&entry_path, &dir2.join(entry_name));
282280
} else {
283281
let path2 = dir2.join(entry_name);
284-
let file1 = read_file(&entry_path);
285-
let file2 = read_file(&path2);
282+
let file1 = fs_wrapper::read(&entry_path);
283+
let file2 = fs_wrapper::read(&path2);
286284

287285
// We don't use `assert_eq!` because they are `Vec<u8>`, so not great for display.
288286
// Why not using String? Because there might be minified files or even potentially
@@ -298,7 +296,7 @@ pub fn recursive_diff(dir1: impl AsRef<Path>, dir2: impl AsRef<Path>) {
298296
}
299297

300298
pub fn read_dir<F: Fn(&Path)>(dir: impl AsRef<Path>, callback: F) {
301-
for entry in fs::read_dir(dir).unwrap() {
299+
for entry in fs_wrapper::read_dir(dir) {
302300
callback(&entry.unwrap().path());
303301
}
304302
}

src/tools/run-make-support/src/rustc.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::io::Write;
33
use std::path::Path;
44
use std::process::{Command, Output, Stdio};
55

6-
use crate::{env_var, handle_failed_output, set_host_rpath, tmp_dir};
6+
use crate::{env_var, handle_failed_output, rmake_out_dir, set_host_rpath};
77

88
/// Construct a new `rustc` invocation.
99
pub fn rustc() -> Rustc {
@@ -28,7 +28,7 @@ fn setup_common() -> Command {
2828
let rustc = env_var("RUSTC");
2929
let mut cmd = Command::new(rustc);
3030
set_host_rpath(&mut cmd);
31-
cmd.arg("--out-dir").arg(tmp_dir()).arg("-L").arg(tmp_dir());
31+
cmd.arg("--out-dir").arg(rmake_out_dir()).arg("-L").arg(rmake_out_dir());
3232
cmd
3333
}
3434

tests/run-make/artifact-incr-cache-no-obj/rmake.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
//
66
// Fixes: rust-lang/rust#123234
77

8-
use run_make_support::{rustc, tmp_dir};
8+
use run_make_support::{rmake_out_dir, rustc};
99

1010
fn main() {
11-
let inc_dir = tmp_dir();
11+
let inc_dir = rmake_out_dir();
1212

1313
for _ in 0..=1 {
1414
rustc()

tests/run-make/artifact-incr-cache/rmake.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
// Also see discussion at
88
// <https://internals.rust-lang.org/t/interaction-between-incremental-compilation-and-emit/20551>
99

10-
use run_make_support::{rustc, tmp_dir};
10+
use run_make_support::{rmake_out_dir, rustc};
1111

1212
fn main() {
13-
let inc_dir = tmp_dir();
13+
let inc_dir = rmake_out_dir();
1414

1515
for _ in 0..=1 {
1616
rustc()

tests/run-make/bare-outfile/rmake.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33

44
//@ ignore-cross-compile
55

6-
use run_make_support::{run, rustc, tmp_dir};
6+
use run_make_support::fs_wrapper;
7+
use run_make_support::{rmake_out_dir, rmake_out_path, run, rustc};
78
use std::env;
8-
use std::fs;
99

1010
fn main() {
11-
fs::copy("foo.rs", tmp_dir().join("foo.rs")).unwrap();
12-
env::set_current_dir(tmp_dir());
11+
fs_wrapper::copy("foo.rs", rmake_out_path("foo.rs"));
12+
env::set_current_dir(rmake_out_dir()).unwrap();
1313
rustc().output("foo").input("foo.rs").run();
1414
run("foo");
1515
}

tests/run-make/box-struct-no-segfault/rmake.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
// This test checks that this bug does not resurface.
66
// See https://github.com/rust-lang/rust/issues/28766
77

8-
use run_make_support::{rustc, tmp_dir};
8+
use run_make_support::{rmake_out_dir, rustc};
99

1010
fn main() {
1111
rustc().opt().input("foo.rs").run();
12-
rustc().opt().library_search_path(tmp_dir()).input("main.rs").run();
12+
rustc().opt().library_search_path(rmake_out_dir()).input("main.rs").run();
1313
}

tests/run-make/c-link-to-rust-dylib/rmake.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,28 @@
66
use std::fs::remove_file;
77

88
use run_make_support::{
9-
cc, dynamic_lib_extension, is_msvc, read_dir, run, run_fail, rustc, tmp_dir,
9+
cc, dynamic_lib_extension, is_msvc, read_dir, rmake_out_dir, run, run_fail, rustc,
1010
};
1111

1212
fn main() {
1313
rustc().input("foo.rs").run();
1414

1515
if is_msvc() {
16-
let lib = tmp_dir().join("foo.dll.lib");
16+
let lib = rmake_out_dir().join("foo.dll.lib");
1717

1818
cc().input("bar.c").arg(lib).out_exe("bar").run();
1919
} else {
2020
cc().input("bar.c")
2121
.arg("-lfoo")
22-
.output(tmp_dir().join("bar"))
23-
.library_search_path(tmp_dir())
22+
.output(rmake_out_dir().join("bar"))
23+
.library_search_path(rmake_out_dir())
2424
.run();
2525
}
2626

2727
run("bar");
2828

2929
let expected_extension = dynamic_lib_extension();
30-
read_dir(tmp_dir(), |path| {
30+
read_dir(rmake_out_dir(), |path| {
3131
if path.is_file()
3232
&& path.extension().is_some_and(|ext| ext == expected_extension)
3333
&& path.file_name().and_then(|name| name.to_str()).is_some_and(|name| {

tests/run-make/c-link-to-rust-staticlib/rmake.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33

44
//@ ignore-cross-compile
55

6+
use run_make_support::fs_wrapper::remove_file;
67
use run_make_support::{cc, extra_c_flags, run, rustc, static_lib};
78
use std::fs;
89

910
fn main() {
1011
rustc().input("foo.rs").run();
1112
cc().input("bar.c").input(static_lib("foo")).out_exe("bar").args(&extra_c_flags()).run();
1213
run("bar");
13-
fs::remove_file(static_lib("foo"));
14+
remove_file(static_lib("foo"));
1415
run("bar");
1516
}

0 commit comments

Comments
 (0)