xref: /aosp_15_r20/external/bazelbuild-rules_rust/tools/upstream_wrapper/src/main.rs (revision d4726bddaa87cc4778e7472feed243fa4b6c267f)
1 use std::ffi::OsString;
2 use std::path::PathBuf;
3 use std::process::{exit, Command};
4 
5 const WRAPPED_TOOL_NAME: &str = env!("WRAPPED_TOOL_NAME");
6 const WRAPPED_TOOL_TARGET: &str = env!("WRAPPED_TOOL_TARGET");
7 
8 #[cfg(not(target_os = "windows"))]
9 const PATH_SEPARATOR: &str = ":";
10 #[cfg(target_os = "windows")]
11 const PATH_SEPARATOR: &str = ";";
12 
main()13 fn main() {
14     let runfiles = runfiles::Runfiles::create().unwrap();
15 
16     let wrapped_tool_path = runfiles::rlocation!(runfiles, WRAPPED_TOOL_TARGET);
17     if !wrapped_tool_path.exists() {
18         panic!(
19             "{WRAPPED_TOOL_NAME} does not exist at: {}",
20             wrapped_tool_path.display()
21         );
22     }
23 
24     let tool_directory = wrapped_tool_path
25         .parent()
26         .expect("parent directory of tool binary");
27     let old_path = std::env::var_os("PATH").unwrap_or_default();
28     let mut new_path = OsString::from(tool_directory);
29     new_path.push(PATH_SEPARATOR);
30     new_path.push(&old_path);
31 
32     let working_directory = std::env::var_os("BUILD_WORKING_DIRECTORY")
33         .map(PathBuf::from)
34         .unwrap_or_else(|| std::env::current_dir().expect("Failed to get working directory"));
35 
36     let status = Command::new(wrapped_tool_path)
37         .current_dir(&working_directory)
38         .args(std::env::args_os().skip(1))
39         .env("PATH", new_path)
40         .status()
41         .unwrap_or_else(|e| panic!("Failed to run {WRAPPED_TOOL_NAME} {:#}", e));
42     if let Some(exit_code) = status.code() {
43         exit(exit_code);
44     }
45     exit_for_signal(&status);
46     panic!("Child rustfmt process didn't exit or get a signal - don't know how to handle it");
47 }
48 
49 #[cfg(target_family = "unix")]
exit_for_signal(status: &std::process::ExitStatus)50 fn exit_for_signal(status: &std::process::ExitStatus) {
51     use std::os::unix::process::ExitStatusExt;
52     if let Some(signal) = status.signal() {
53         exit(signal);
54     }
55 }
56 
57 #[cfg(not(target_family = "unix"))]
58 #[allow(unused)]
exit_for_signal(status: &std::process::ExitStatus)59 fn exit_for_signal(status: &std::process::ExitStatus) {}
60