1pub mod bolt;
7pub mod build;
8pub mod check;
9pub mod clean;
10pub(crate) mod cli;
11pub mod pgo;
12pub(crate) mod utils;
13pub(crate) mod workspace;
14
15use anyhow::anyhow;
16use std::ffi::OsStr;
17use std::path::{Path, PathBuf};
18use std::process::{Command, ExitStatus};
19
20pub use workspace::get_cargo_ctx;
21
22pub(crate) fn resolve_binary(path: &Path) -> anyhow::Result<PathBuf> {
23 Ok(which::which(path)?)
24}
25
26#[derive(Debug)]
27struct Utf8Output {
28 stdout: String,
29 stderr: String,
30 status: ExitStatus,
31}
32
33impl Utf8Output {
34 pub fn ok(self) -> anyhow::Result<Self> {
35 if self.status.success() {
36 Ok(self)
37 } else {
38 Err(anyhow::anyhow!(
39 "Command ended with {}\nStderr\n{}\nStdout\n{}",
40 self.status,
41 self.stderr,
42 self.stdout
43 ))
44 }
45 }
46}
47
48fn run_command<S: AsRef<OsStr>, Str: AsRef<OsStr>>(
50 program: S,
51 args: &[Str],
52) -> anyhow::Result<Utf8Output> {
53 let mut cmd = Command::new(program);
54 for arg in args {
55 cmd.arg(arg);
56 }
57 log::debug!("Running command {:?}", cmd);
58 cmd.stdout(std::process::Stdio::piped());
59 cmd.stderr(std::process::Stdio::piped());
60
61 let output = cmd.output()?;
62 Ok(Utf8Output {
63 stdout: String::from_utf8(output.stdout)?,
64 stderr: String::from_utf8(output.stderr)?,
65 status: output.status,
66 })
67}
68
69pub fn get_default_target() -> anyhow::Result<String> {
71 get_rustc_info("host: ")
72}
73
74pub fn get_rustc_version() -> anyhow::Result<semver::Version> {
75 let version = get_rustc_info("release: ")?;
76 let version = semver::Version::parse(&version)?;
77 Ok(version)
78}
79
80fn get_rustc_info(field: &str) -> anyhow::Result<String> {
81 let output = run_command("rustc", &["-vV"])?;
83
84 let host = output
86 .stdout
87 .lines()
88 .find(|l| l.starts_with(field))
89 .map(|l| l[field.len()..].trim())
90 .ok_or_else(|| anyhow!("Failed to parse field {} from rustc output.", field))?
91 .to_owned();
92 Ok(host)
93}
94
95fn clear_directory(path: &Path) -> std::io::Result<()> {
97 std::fs::remove_dir_all(path)?;
98 ensure_directory(path)
99}
100
101fn ensure_directory(path: &Path) -> std::io::Result<()> {
103 std::fs::create_dir_all(path)
104}