Skip to content

Commit 7209fd3

Browse files
committed
Set RUSTUP_TOOLCHAIN_SOURCE
Make Clippy happy Make Clippy even happier Eliminate overlap with `RUSTUP_TOOLCHAIN` Describe `RUSTUP_TOOLCHAIN_SOURCE` in environment-variables.md Mark `RUSTUP_TOOLCHAIN_SOURCE` as unstable `config` -> `toolchain-file`; `override` -> `path-override` Unconditionally set `RUSTUP_TOOLCHAIN_SOURCE` in proxy `downstream` -> `proxied`
1 parent 6496be0 commit 7209fd3

File tree

5 files changed

+131
-5
lines changed

5 files changed

+131
-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: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
use std::{path::PathBuf, process::ExitStatus};
1+
use std::{
2+
path::PathBuf,
3+
process::{Command, ExitStatus},
4+
};
25

36
use anyhow::Result;
47

58
use crate::{
69
cli::{common::set_globals, job, self_update},
710
command::run_command_for_dir,
11+
config::ActiveReason,
812
process::Process,
913
toolchain::ResolvableLocalToolchainName,
1014
};
@@ -24,6 +28,7 @@ pub async fn main(arg0: &str, current_dir: PathBuf, process: &Process) -> Result
2428
.filter(|arg| arg.starts_with('+'))
2529
.map(|name| ResolvableLocalToolchainName::try_from(&name.as_ref()[1..]))
2630
.transpose()?;
31+
let toolchain_specified = toolchain.is_some();
2732

2833
// Build command args now while we know whether or not to skip arg 1.
2934
let cmd_args: Vec<_> = process
@@ -32,9 +37,25 @@ pub async fn main(arg0: &str, current_dir: PathBuf, process: &Process) -> Result
3237
.collect();
3338

3439
let cfg = set_globals(current_dir, true, process)?;
35-
let cmd = cfg
36-
.resolve_local_toolchain(toolchain)
37-
.await?
38-
.command(arg0)?;
40+
let toolchain = cfg.resolve_local_toolchain(toolchain).await?;
41+
let mut cmd = toolchain.command(arg0)?;
42+
set_env_source(
43+
&mut cmd,
44+
if toolchain_specified {
45+
Some(ActiveReason::CommandLine)
46+
} else if let Ok(Some((_, reason))) = cfg.active_toolchain() {
47+
Some(reason)
48+
} else {
49+
None
50+
},
51+
);
3952
run_command_for_dir(cmd, arg0, &cmd_args)
4053
}
54+
55+
/// Set the `RUSTUP_TOOLCHAIN_SOURCE` environment variable to indicate how the toolchain was
56+
/// determined.
57+
fn set_env_source(cmd: &mut Command, reason: Option<ActiveReason>) {
58+
if let Some(reason) = reason {
59+
cmd.env("RUSTUP_TOOLCHAIN_SOURCE", reason.to_source());
60+
}
61+
}

src/config.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,19 @@ pub(crate) enum ActiveReason {
102102
ToolchainFile(PathBuf),
103103
}
104104

105+
impl ActiveReason {
106+
/// Format `ActiveReason` for setting the `RUSTUP_TOOLCHAIN_SOURCE` environment variable.
107+
pub fn to_source(&self) -> &str {
108+
match self {
109+
Self::Default => "default",
110+
Self::Environment => "env",
111+
Self::CommandLine => "cli",
112+
Self::OverrideDB(_) => "path-override",
113+
Self::ToolchainFile(_) => "toolchain-file",
114+
}
115+
}
116+
}
117+
105118
impl Display for ActiveReason {
106119
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> {
107120
match self {

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)