Skip to content

Commit 0157da4

Browse files
committed
Auto merge of rust-lang#122460 - jieyouxu:rmake-example-refactor, r=Nilstrieb
Rework rmake support library API ### Take 1: Strongly-typed API Context: rust-lang#122448 (comment) > My 2 cents: from my experience with writing similar "test DSLs", I would suggest to create these helpers as soon as possible in the process (basically the first time someone needs them, not only after N similar usages), and basically treat any imperative code in these high-level tests as a maintenance burden, basically making them as declarative as possible. Otherwise it might be a bit annoying to keep refactoring the tests later once such helpers are available. > > I would even discourage the arg method and create explicit methods for setting things like unpretty, the output file etc., but this might be more controversial, as it will make the invoked command-line arguments more opaque. cc `@Kobzol` for the testing DSL suggestion. Example: ```rs let output = Rustc::new() .input_file("main.rs") .emit(&[EmitKind::Metadata]) .extern_("stable", &stable_path) .output(); ``` ### Take 2: xshell-based macro API Example: ```rs let sh = Shell::new()?; let stable_path = stable_path.to_string_lossy(); let output = cmd!(sh, "rustc main.rs --emit=metadata --extern stable={stable_path}").output()?; ``` ### Take 3: Weakly-typed API with a few helper methods ```rs let output = Rustc::new() .input("main.rs") .emit("metadata") .extern_("stable", &stable_path) .output(); ```
2 parents d5db7fb + 1f2178b commit 0157da4

File tree

19 files changed

+404
-282
lines changed

19 files changed

+404
-282
lines changed

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

+12-177
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
1+
pub mod run;
2+
pub mod rustc;
3+
pub mod rustdoc;
4+
15
use std::env;
2-
use std::path::{Path, PathBuf};
3-
use std::process::{Command, Output};
6+
use std::path::PathBuf;
7+
use std::process::Output;
48

59
pub use object;
610
pub use wasmparser;
711

8-
pub fn out_dir() -> PathBuf {
9-
env::var_os("TMPDIR").unwrap().into()
10-
}
12+
pub use run::{run, run_fail};
13+
pub use rustc::{aux_build, rustc, Rustc};
14+
pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc};
1115

12-
fn setup_common_build_cmd(command: &str) -> Command {
13-
let rustc = env::var(command).unwrap();
14-
let mut cmd = Command::new(rustc);
15-
cmd.arg("--out-dir").arg(out_dir()).arg("-L").arg(out_dir());
16-
cmd
16+
/// Path of `TMPDIR` (a temporary build directory, not under `/tmp`).
17+
pub fn tmp_dir() -> PathBuf {
18+
env::var_os("TMPDIR").unwrap().into()
1719
}
1820

1921
fn handle_failed_output(cmd: &str, output: Output, caller_line_number: u32) -> ! {
@@ -24,170 +26,3 @@ fn handle_failed_output(cmd: &str, output: Output, caller_line_number: u32) -> !
2426
eprintln!("=== STDERR ===\n{}\n\n", String::from_utf8(output.stderr).unwrap());
2527
std::process::exit(1)
2628
}
27-
28-
pub fn rustc() -> RustcInvocationBuilder {
29-
RustcInvocationBuilder::new()
30-
}
31-
32-
pub fn aux_build() -> AuxBuildInvocationBuilder {
33-
AuxBuildInvocationBuilder::new()
34-
}
35-
36-
pub fn rustdoc() -> Rustdoc {
37-
Rustdoc::new()
38-
}
39-
40-
#[derive(Debug)]
41-
pub struct RustcInvocationBuilder {
42-
cmd: Command,
43-
}
44-
45-
impl RustcInvocationBuilder {
46-
fn new() -> Self {
47-
let cmd = setup_common_build_cmd("RUSTC");
48-
Self { cmd }
49-
}
50-
51-
pub fn arg(&mut self, arg: &str) -> &mut RustcInvocationBuilder {
52-
self.cmd.arg(arg);
53-
self
54-
}
55-
56-
pub fn args(&mut self, args: &[&str]) -> &mut RustcInvocationBuilder {
57-
self.cmd.args(args);
58-
self
59-
}
60-
61-
#[track_caller]
62-
pub fn run(&mut self) -> Output {
63-
let caller_location = std::panic::Location::caller();
64-
let caller_line_number = caller_location.line();
65-
66-
let output = self.cmd.output().unwrap();
67-
if !output.status.success() {
68-
handle_failed_output(&format!("{:#?}", self.cmd), output, caller_line_number);
69-
}
70-
output
71-
}
72-
}
73-
74-
#[derive(Debug)]
75-
pub struct AuxBuildInvocationBuilder {
76-
cmd: Command,
77-
}
78-
79-
impl AuxBuildInvocationBuilder {
80-
fn new() -> Self {
81-
let mut cmd = setup_common_build_cmd("RUSTC");
82-
cmd.arg("--crate-type=lib");
83-
Self { cmd }
84-
}
85-
86-
pub fn arg(&mut self, arg: &str) -> &mut AuxBuildInvocationBuilder {
87-
self.cmd.arg(arg);
88-
self
89-
}
90-
91-
#[track_caller]
92-
pub fn run(&mut self) -> Output {
93-
let caller_location = std::panic::Location::caller();
94-
let caller_line_number = caller_location.line();
95-
96-
let output = self.cmd.output().unwrap();
97-
if !output.status.success() {
98-
handle_failed_output(&format!("{:#?}", self.cmd), output, caller_line_number);
99-
}
100-
output
101-
}
102-
}
103-
104-
#[derive(Debug)]
105-
pub struct Rustdoc {
106-
cmd: Command,
107-
}
108-
109-
impl Rustdoc {
110-
fn new() -> Self {
111-
let cmd = setup_common_build_cmd("RUSTDOC");
112-
Self { cmd }
113-
}
114-
115-
pub fn arg(&mut self, arg: &str) -> &mut Self {
116-
self.cmd.arg(arg);
117-
self
118-
}
119-
120-
#[track_caller]
121-
pub fn run(&mut self) -> Output {
122-
let caller_location = std::panic::Location::caller();
123-
let caller_line_number = caller_location.line();
124-
125-
let output = self.cmd.output().unwrap();
126-
if !output.status.success() {
127-
handle_failed_output(&format!("{:#?}", self.cmd), output, caller_line_number);
128-
}
129-
output
130-
}
131-
}
132-
133-
fn run_common(bin_name: &str) -> (Command, Output) {
134-
let target = env::var("TARGET").unwrap();
135-
136-
let bin_name =
137-
if target.contains("windows") { format!("{}.exe", bin_name) } else { bin_name.to_owned() };
138-
139-
let mut bin_path = PathBuf::new();
140-
bin_path.push(env::var("TMPDIR").unwrap());
141-
bin_path.push(&bin_name);
142-
let ld_lib_path_envvar = env::var("LD_LIB_PATH_ENVVAR").unwrap();
143-
let mut cmd = Command::new(bin_path);
144-
cmd.env(&ld_lib_path_envvar, {
145-
let mut paths = vec![];
146-
paths.push(PathBuf::from(env::var("TMPDIR").unwrap()));
147-
for p in env::split_paths(&env::var("TARGET_RPATH_ENV").unwrap()) {
148-
paths.push(p.to_path_buf());
149-
}
150-
for p in env::split_paths(&env::var(&ld_lib_path_envvar).unwrap()) {
151-
paths.push(p.to_path_buf());
152-
}
153-
env::join_paths(paths.iter()).unwrap()
154-
});
155-
156-
if target.contains("windows") {
157-
let mut paths = vec![];
158-
for p in env::split_paths(&std::env::var("PATH").unwrap_or(String::new())) {
159-
paths.push(p.to_path_buf());
160-
}
161-
paths.push(Path::new(&std::env::var("TARGET_RPATH_DIR").unwrap()).to_path_buf());
162-
cmd.env("PATH", env::join_paths(paths.iter()).unwrap());
163-
}
164-
165-
let output = cmd.output().unwrap();
166-
(cmd, output)
167-
}
168-
169-
/// Run a built binary and make sure it succeeds.
170-
#[track_caller]
171-
pub fn run(bin_name: &str) -> Output {
172-
let caller_location = std::panic::Location::caller();
173-
let caller_line_number = caller_location.line();
174-
175-
let (cmd, output) = run_common(bin_name);
176-
if !output.status.success() {
177-
handle_failed_output(&format!("{:#?}", cmd), output, caller_line_number);
178-
}
179-
output
180-
}
181-
182-
/// Run a built binary and make sure it fails.
183-
#[track_caller]
184-
pub fn run_fail(bin_name: &str) -> Output {
185-
let caller_location = std::panic::Location::caller();
186-
let caller_line_number = caller_location.line();
187-
188-
let (cmd, output) = run_common(bin_name);
189-
if output.status.success() {
190-
handle_failed_output(&format!("{:#?}", cmd), output, caller_line_number);
191-
}
192-
output
193-
}

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

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
use std::env;
2+
use std::path::{Path, PathBuf};
3+
use std::process::{Command, Output};
4+
5+
use super::handle_failed_output;
6+
7+
fn run_common(bin_name: &str) -> (Command, Output) {
8+
let target = env::var("TARGET").unwrap();
9+
10+
let bin_name =
11+
if target.contains("windows") { format!("{}.exe", bin_name) } else { bin_name.to_owned() };
12+
13+
let mut bin_path = PathBuf::new();
14+
bin_path.push(env::var("TMPDIR").unwrap());
15+
bin_path.push(&bin_name);
16+
let ld_lib_path_envvar = env::var("LD_LIB_PATH_ENVVAR").unwrap();
17+
let mut cmd = Command::new(bin_path);
18+
cmd.env(&ld_lib_path_envvar, {
19+
let mut paths = vec![];
20+
paths.push(PathBuf::from(env::var("TMPDIR").unwrap()));
21+
for p in env::split_paths(&env::var("TARGET_RPATH_ENV").unwrap()) {
22+
paths.push(p.to_path_buf());
23+
}
24+
for p in env::split_paths(&env::var(&ld_lib_path_envvar).unwrap()) {
25+
paths.push(p.to_path_buf());
26+
}
27+
env::join_paths(paths.iter()).unwrap()
28+
});
29+
30+
if target.contains("windows") {
31+
let mut paths = vec![];
32+
for p in env::split_paths(&std::env::var("PATH").unwrap_or(String::new())) {
33+
paths.push(p.to_path_buf());
34+
}
35+
paths.push(Path::new(&std::env::var("TARGET_RPATH_DIR").unwrap()).to_path_buf());
36+
cmd.env("PATH", env::join_paths(paths.iter()).unwrap());
37+
}
38+
39+
let output = cmd.output().unwrap();
40+
(cmd, output)
41+
}
42+
43+
/// Run a built binary and make sure it succeeds.
44+
#[track_caller]
45+
pub fn run(bin_name: &str) -> Output {
46+
let caller_location = std::panic::Location::caller();
47+
let caller_line_number = caller_location.line();
48+
49+
let (cmd, output) = run_common(bin_name);
50+
if !output.status.success() {
51+
handle_failed_output(&format!("{:#?}", cmd), output, caller_line_number);
52+
}
53+
output
54+
}
55+
56+
/// Run a built binary and make sure it fails.
57+
#[track_caller]
58+
pub fn run_fail(bin_name: &str) -> Output {
59+
let caller_location = std::panic::Location::caller();
60+
let caller_line_number = caller_location.line();
61+
62+
let (cmd, output) = run_common(bin_name);
63+
if output.status.success() {
64+
handle_failed_output(&format!("{:#?}", cmd), output, caller_line_number);
65+
}
66+
output
67+
}

0 commit comments

Comments
 (0)