Skip to content

Commit b336179

Browse files
smoeliusdjc
authored andcommitted
Implement RUSTUP_TOOLCHAIN_SOURCE with new Display impl
1 parent 64f2624 commit b336179

File tree

5 files changed

+117
-5
lines changed

5 files changed

+117
-5
lines changed

doc/user-guide/src/environment-variables.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@
7272
- `RUSTUP_CONCURRENT_DOWNLOADS` *unstable* (default: the number of components to download). Controls the number of
7373
downloads made concurrently.
7474

75+
- `RUSTUP_TOOLCHAIN_SOURCE` *unstable*. Set by rustup to tell proxied tools how `RUSTUP_TOOLCHAIN` was determined.
76+
7577
[directive syntax]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives
7678
[dc]: https://docs.docker.com/storage/storagedriver/overlayfs-driver/#modifying-files-or-directories
7779
[override]: overrides.md

src/cli/proxy_mode.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use anyhow::Result;
55
use crate::{
66
cli::{common::set_globals, job, self_update},
77
command::run_command_for_dir,
8+
config::ActiveSource,
89
process::Process,
910
toolchain::ResolvableLocalToolchainName,
1011
};
@@ -24,6 +25,7 @@ pub async fn main(arg0: &str, current_dir: PathBuf, process: &Process) -> Result
2425
.filter(|arg| arg.starts_with('+'))
2526
.map(|name| ResolvableLocalToolchainName::try_from(&name.as_ref()[1..]))
2627
.transpose()?;
28+
let toolchain_specified = toolchain.is_some();
2729

2830
// Build command args now while we know whether or not to skip arg 1.
2931
let cmd_args: Vec<_> = process
@@ -32,9 +34,15 @@ pub async fn main(arg0: &str, current_dir: PathBuf, process: &Process) -> Result
3234
.collect();
3335

3436
let cfg = set_globals(current_dir, true, process)?;
35-
let cmd = cfg
36-
.resolve_local_toolchain(toolchain)
37-
.await?
38-
.command(arg0)?;
37+
let toolchain = cfg.resolve_local_toolchain(toolchain).await?;
38+
let mut cmd = toolchain.command(arg0)?;
39+
if toolchain_specified {
40+
cmd.env(
41+
"RUSTUP_TOOLCHAIN_SOURCE",
42+
ActiveSource::CommandLine.to_string(),
43+
);
44+
} else if let Ok(Some((_, source))) = cfg.active_toolchain() {
45+
cmd.env("RUSTUP_TOOLCHAIN_SOURCE", source.to_string());
46+
}
3947
run_command_for_dir(cmd, arg0, &cmd_args)
4048
}

src/config.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::fmt::{self, Debug};
1+
use std::fmt::{self, Debug, Display};
22
use std::io;
33
use std::path::{Path, PathBuf};
44
use std::str::FromStr;
@@ -111,6 +111,18 @@ impl ActiveSource {
111111
}
112112
}
113113

114+
impl Display for ActiveSource {
115+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
116+
f.write_str(match self {
117+
Self::Default => "default",
118+
Self::Environment => "env",
119+
Self::CommandLine => "cli",
120+
Self::OverrideDB(_) => "path-override",
121+
Self::ToolchainFile(_) => "toolchain-file",
122+
})
123+
}
124+
}
125+
114126
// Represents a toolchain override from a +toolchain command line option,
115127
// RUSTUP_TOOLCHAIN environment variable, or rust-toolchain.toml file etc. Can
116128
// include components and targets from a rust-toolchain.toml that should be

src/test/mock_bin_src.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,14 @@ fn main() {
106106
let mut out = io::stderr();
107107
writeln!(out, "{}", std::env::current_exe().unwrap().display()).unwrap();
108108
}
109+
Some("--echo-rustup-toolchain-source") => {
110+
let mut out = io::stderr();
111+
if let Ok(rustup_toolchain_source) = std::env::var("RUSTUP_TOOLCHAIN_SOURCE") {
112+
writeln!(out, "{rustup_toolchain_source}").unwrap();
113+
} else {
114+
panic!("RUSTUP_TOOLCHAIN_SOURCE environment variable not set");
115+
}
116+
}
109117
arg => panic!("bad mock proxy commandline: {:?}", arg),
110118
}
111119
}

tests/suite/cli_rustup.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3038,6 +3038,88 @@ error: no active toolchain
30383038
.is_ok();
30393039
}
30403040

3041+
#[tokio::test]
3042+
async fn rustup_toolchain_source_cli() {
3043+
let cx = CliTestContext::new(Scenario::SimpleV2).await;
3044+
cx.config
3045+
.expect(&["rustup", "install", "nightly"])
3046+
.await
3047+
.is_ok();
3048+
cx.config
3049+
.expect(["cargo", "+nightly", "--echo-rustup-toolchain-source"])
3050+
.await
3051+
.with_stderr(snapbox::str![[r#"
3052+
...
3053+
cli
3054+
3055+
"#]]);
3056+
}
3057+
3058+
#[tokio::test]
3059+
async fn rustup_toolchain_source_env() {
3060+
let cx = CliTestContext::new(Scenario::SimpleV2).await;
3061+
cx.config
3062+
.expect_with_env(
3063+
["cargo", "--echo-rustup-toolchain-source"],
3064+
[("RUSTUP_TOOLCHAIN", "nightly")],
3065+
)
3066+
.await
3067+
.with_stderr(snapbox::str![[r#"
3068+
...
3069+
env
3070+
3071+
"#]]);
3072+
}
3073+
3074+
#[tokio::test]
3075+
async fn rustup_toolchain_source_path_override() {
3076+
let cx = CliTestContext::new(Scenario::SimpleV2).await;
3077+
cx.config
3078+
.expect(["rustup", "override", "set", "nightly"])
3079+
.await
3080+
.is_ok();
3081+
cx.config
3082+
.expect(["cargo", "--echo-rustup-toolchain-source"])
3083+
.await
3084+
.with_stderr(snapbox::str![[r#"
3085+
...
3086+
path-override
3087+
3088+
"#]]);
3089+
}
3090+
3091+
#[tokio::test]
3092+
async fn rustup_toolchain_source_toolchain_file() {
3093+
let cx = CliTestContext::new(Scenario::SimpleV2).await;
3094+
let toolchain_file = cx.config.current_dir().join("rust-toolchain.toml");
3095+
raw::write_file(&toolchain_file, "[toolchain]\nchannel='nightly'").unwrap();
3096+
cx.config
3097+
.expect(["cargo", "--echo-rustup-toolchain-source"])
3098+
.await
3099+
.with_stderr(snapbox::str![[r#"
3100+
...
3101+
toolchain-file
3102+
3103+
"#]]);
3104+
}
3105+
3106+
#[tokio::test]
3107+
async fn rustup_toolchain_source_default() {
3108+
let cx = CliTestContext::new(Scenario::SimpleV2).await;
3109+
cx.config
3110+
.expect(&["rustup", "default", "stable"])
3111+
.await
3112+
.is_ok();
3113+
cx.config
3114+
.expect(["cargo", "--echo-rustup-toolchain-source"])
3115+
.await
3116+
.with_stderr(snapbox::str![[r#"
3117+
...
3118+
default
3119+
3120+
"#]]);
3121+
}
3122+
30413123
#[tokio::test]
30423124
async fn directory_override_doesnt_need_to_exist_unless_it_is_selected() {
30433125
let cx = CliTestContext::new(Scenario::SimpleV2).await;

0 commit comments

Comments
 (0)