Skip to content

Commit

Permalink
Resolve toolchain name
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed Dec 3, 2022
1 parent acbb404 commit 47998cd
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 21 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ members = ["tests/auxiliary/build-info"]
[dependencies]
anyhow = "1.0.47"
ctrlc = { version = "3.1.4", features = ["termination"] }
home = "0.5"
indexmap = { version = "1.5.2", features = ["std"] }
is-terminal = "0.4"
lexopt = "0.2"
Expand Down
2 changes: 2 additions & 0 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub(crate) struct Context {
pkg_features: HashMap<PackageId, Features>,
cargo: PathBuf,
pub(crate) cargo_version: u32,
pub(crate) rustup_toolchains: Option<PathBuf>,
pub(crate) restore: restore::Manager,
pub(crate) current_dir: PathBuf,
pub(crate) version_range: Option<Vec<(u32, String)>>,
Expand Down Expand Up @@ -70,6 +71,7 @@ impl Context {
pkg_features,
cargo: cargo.into(),
cargo_version,
rustup_toolchains: home::rustup_home().ok().map(|p| p.join("toolchains")),
restore,
current_dir: env::current_dir()?,
version_range: None,
Expand Down
8 changes: 5 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ fn exec_cargo_inner(
}

if cx.print_command_list {
print_command(line);
print_command(line.clone());
return Ok(());
}

Expand All @@ -518,14 +518,15 @@ fn exec_cargo_inner(

fn cargo_clean(cx: &Context, id: Option<&PackageId>) -> Result<()> {
let mut line = cx.cargo();
line.context(cx);
line.arg("clean");
if let Some(id) = id {
line.arg("--package");
line.arg(&cx.packages(id).name);
}

if cx.print_command_list {
print_command(&line);
print_command(line);
return Ok(());
}

Expand All @@ -537,8 +538,9 @@ fn cargo_clean(cx: &Context, id: Option<&PackageId>) -> Result<()> {
line.run()
}

fn print_command(line: &ProcessBuilder<'_>) {
fn print_command(mut line: ProcessBuilder<'_>) {
let _guard = term::verbose::scoped(true);
line.resolve_toolchain = true;
let l = line.to_string();
println!("{}", &l[1..l.len() - 1]);
}
36 changes: 33 additions & 3 deletions src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ pub(crate) struct ProcessBuilder<'a> {
/// This list always has a trailing comma if it is not empty.
// cargo less than Rust 1.38 cannot handle multiple '--features' flags, so it creates another String.
features: String,

cx: Option<&'a Context>,
pub(crate) resolve_toolchain: bool,
}

impl<'a> ProcessBuilder<'a> {
Expand All @@ -56,6 +59,8 @@ impl<'a> ProcessBuilder<'a> {
leading_args: Vec::new(),
args: Vec::new(),
features: String::new(),
cx: None,
resolve_toolchain: false,
}
}

Expand All @@ -80,10 +85,15 @@ impl<'a> ProcessBuilder<'a> {
self
}

pub(crate) fn context(&mut self, cx: &'a Context) -> &mut Self {
self.cx = Some(cx);
self
}

pub(crate) fn apply_context(&mut self, cx: &'a Context) -> &mut Self {
self.propagated_leading_args = &cx.leading_args;
self.trailing_args = &cx.trailing_args;
self
self.context(cx)
}

pub(crate) fn append_features(&mut self, features: impl IntoIterator<Item = impl AsRef<str>>) {
Expand Down Expand Up @@ -181,14 +191,34 @@ impl<'a> ProcessBuilder<'a> {
}
}

fn resolve_toolchain<'a>(cx: Option<&Context>, path: &'a Path) -> Option<(&'a str, &'a str)> {
let rustup_toolchains = &cx?.rustup_toolchains.as_ref()?;
let path = path.strip_prefix(rustup_toolchains).ok()?;
let file_stem = path.file_stem()?;
if file_stem == "cargo" || file_stem == "rustc" {
Some((path.parent()?.parent()?.to_str()?, file_stem.to_str().unwrap()))
} else {
None
}
}

impl fmt::Display for ProcessBuilder<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "`")?;

let program = Path::new(&*self.program);
if f.alternate() || term::verbose() {
write!(f, "{}", self.program.to_string_lossy())?;
if self.resolve_toolchain {
if let Some((toolchain, program)) = resolve_toolchain(self.cx, program) {
write!(f, "{program} +{toolchain}")?;
} else {
write!(f, "{}", self.program.to_string_lossy())?;
}
} else {
write!(f, "{}", self.program.to_string_lossy())?;
}
} else {
write!(f, "{}", Path::new(&*self.program).file_stem().unwrap().to_string_lossy())?;
write!(f, "{}", program.file_stem().unwrap().to_string_lossy())?;
}

for arg in &self.leading_args {
Expand Down
18 changes: 14 additions & 4 deletions tests/auxiliary/build-info/build.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
use std::{env, fs, path::PathBuf};
use std::{env, fs, path::PathBuf, process::Command, str};

fn main() {
let target = env::var("TARGET").expect("TARGET not set");
let rustc = &*env::var("RUSTC").expect("RUSTC not set");
let output = Command::new(rustc).args(["--print", "sysroot"]).output().unwrap();
assert!(output.status.success());
let sysroot = str::from_utf8(&output.stdout).unwrap().trim();
let out_dir: PathBuf = env::var_os("OUT_DIR").expect("OUT_DIR not set").into();
let out_file = &out_dir.join("target");
fs::write(out_file, format!("\"{target}\""))
.unwrap_or_else(|e| panic!("failed to write {}: {e}", out_file.display()));
let out_file = &out_dir.join("build-info");
fs::write(
out_file,
format!(
"pub const TARGET: &str = r\"{target}\";\n\
pub const SYSROOT: &str = r\"{sysroot}\";\n"
),
)
.unwrap_or_else(|e| panic!("failed to write {}: {e}", out_file.display()));
}
2 changes: 1 addition & 1 deletion tests/auxiliary/build-info/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
pub const TARGET: &str = include!(concat!(env!("OUT_DIR"), "/target"));
include!(concat!(env!("OUT_DIR"), "/build-info"));
2 changes: 1 addition & 1 deletion tests/auxiliary/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub fn cargo_bin_exe() -> Command {
cmd
}

fn test_toolchain() -> String {
pub(crate) fn test_toolchain() -> String {
if let Some(toolchain) = test_version() {
format!("+1.{toolchain} ")
} else {
Expand Down
65 changes: 56 additions & 9 deletions tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ mod auxiliary;

use std::{
env::{self, consts::EXE_SUFFIX},
path::MAIN_SEPARATOR,
path::{Path, MAIN_SEPARATOR},
};

use auxiliary::{cargo_bin_exe, cargo_hack, has_stable_toolchain, CommandExt, TARGET};

use crate::auxiliary::test_toolchain;

#[test]
fn failures() {
cargo_bin_exe().assert_failure("real");
Expand Down Expand Up @@ -1464,17 +1466,62 @@ fn empty_string() {

#[test]
fn print_command_list() {
fn resolve_toolchain() -> String {
let rustup_toolchains = home::rustup_home().unwrap().join("toolchains");
String::from("+")
+ Path::new(build_info::SYSROOT)
.strip_prefix(rustup_toolchains)
.unwrap()
.to_str()
.unwrap()
+ " "
}

let mut toolchain = test_toolchain();
if toolchain.is_empty() {
toolchain = resolve_toolchain();
};
cargo_hack(["check", "--each-feature", "--print-command-list"])
.assert_success("real")
.stdout_contains(
"
cargo check --manifest-path Cargo.toml --no-default-features
cargo check --manifest-path Cargo.toml --no-default-features --features a
cargo check --manifest-path Cargo.toml --no-default-features --features b
cargo check --manifest-path Cargo.toml --no-default-features --features c
cargo check --manifest-path Cargo.toml --no-default-features --features default
cargo check --manifest-path Cargo.toml --no-default-features --all-features
",
format!("
cargo{EXE_SUFFIX} {toolchain}check --manifest-path Cargo.toml --no-default-features
cargo{EXE_SUFFIX} {toolchain}check --manifest-path Cargo.toml --no-default-features --features a
cargo{EXE_SUFFIX} {toolchain}check --manifest-path Cargo.toml --no-default-features --features b
cargo{EXE_SUFFIX} {toolchain}check --manifest-path Cargo.toml --no-default-features --features c
cargo{EXE_SUFFIX} {toolchain}check --manifest-path Cargo.toml --no-default-features --features default
cargo{EXE_SUFFIX} {toolchain}check --manifest-path Cargo.toml --no-default-features --all-features
"),
)
.stdout_not_contains("`");
}

#[cfg_attr(windows, ignore)] // rustup bug: https://github.com/rust-lang/rustup/issues/3036
#[test]
fn print_command_list_version_range() {
cargo_hack([
"check",
"--each-feature",
"--print-command-list",
"--version-range",
"1.63..1.64",
])
.assert_success("real")
.stdout_contains(
format!("
cargo{EXE_SUFFIX} +1.63 check --manifest-path Cargo.toml --no-default-features
cargo{EXE_SUFFIX} +1.63 check --manifest-path Cargo.toml --no-default-features --features a
cargo{EXE_SUFFIX} +1.63 check --manifest-path Cargo.toml --no-default-features --features b
cargo{EXE_SUFFIX} +1.63 check --manifest-path Cargo.toml --no-default-features --features c
cargo{EXE_SUFFIX} +1.63 check --manifest-path Cargo.toml --no-default-features --features default
cargo{EXE_SUFFIX} +1.63 check --manifest-path Cargo.toml --no-default-features --all-features
cargo{EXE_SUFFIX} +1.64 check --manifest-path Cargo.toml --no-default-features
cargo{EXE_SUFFIX} +1.64 check --manifest-path Cargo.toml --no-default-features --features a
cargo{EXE_SUFFIX} +1.64 check --manifest-path Cargo.toml --no-default-features --features b
cargo{EXE_SUFFIX} +1.64 check --manifest-path Cargo.toml --no-default-features --features c
cargo{EXE_SUFFIX} +1.64 check --manifest-path Cargo.toml --no-default-features --features default
cargo{EXE_SUFFIX} +1.64 check --manifest-path Cargo.toml --no-default-features --all-features
"),
)
.stdout_not_contains("`");
}

0 comments on commit 47998cd

Please sign in to comment.