Skip to content

Commit 66fdf0f

Browse files
committed
install: add --profile flag to override profile
Previously, the profile to use when installing a new toolchain had to be set globally through `rustup set profile`, or at rustup-init time. Sometimes this is inconvenient, because you only want to use a particular profile when installing a specific toolchain. This patch allows users to pass `--profile` to `rustup install` to override the profile used for that one install. Fixes #2004.
1 parent d427b76 commit 66fdf0f

File tree

4 files changed

+75
-9
lines changed

4 files changed

+75
-9
lines changed

src/cli/rustup_mode.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub fn main() -> Result<()> {
3333
let matches = cli().get_matches();
3434
let verbose = matches.is_present("verbose");
3535
let quiet = matches.is_present("quiet");
36-
let cfg = &common::set_globals(verbose, quiet)?;
36+
let cfg = &mut common::set_globals(verbose, quiet)?;
3737

3838
if maybe_upgrade_data(cfg, &matches)? {
3939
return Ok(());
@@ -89,8 +89,8 @@ pub fn main() -> Result<()> {
8989
(_, _) => unreachable!(),
9090
},
9191
("set", Some(c)) => match c.subcommand() {
92-
("default-host", Some(m)) => set_default_host_triple(&cfg, m)?,
93-
("profile", Some(m)) => set_profile(&cfg, m)?,
92+
("default-host", Some(m)) => set_default_host_triple(cfg, m)?,
93+
("profile", Some(m)) => set_profile(cfg, m)?,
9494
(_, _) => unreachable!(),
9595
},
9696
("completions", Some(c)) => {
@@ -169,6 +169,13 @@ pub fn cli() -> App<'static, 'static> {
169169
.required(true)
170170
.multiple(true),
171171
)
172+
.arg(
173+
Arg::with_name("profile")
174+
.long("profile")
175+
.takes_value(true)
176+
.possible_values(Profile::names())
177+
.required(false)
178+
)
172179
.arg(
173180
Arg::with_name("no-self-update")
174181
.help("Don't perform self-update when running the `rustup install` command")
@@ -258,6 +265,13 @@ pub fn cli() -> App<'static, 'static> {
258265
.required(true)
259266
.multiple(true),
260267
)
268+
.arg(
269+
Arg::with_name("profile")
270+
.long("profile")
271+
.takes_value(true)
272+
.possible_values(Profile::names())
273+
.required(false)
274+
)
261275
.arg(
262276
Arg::with_name("no-self-update")
263277
.help("Don't perform self update when running the `rustup toolchain install` command")
@@ -772,8 +786,13 @@ fn check_updates(cfg: &Cfg) -> Result<()> {
772786
Ok(())
773787
}
774788

775-
fn update(cfg: &Cfg, m: &ArgMatches<'_>) -> Result<()> {
789+
fn update(cfg: &mut Cfg, m: &ArgMatches<'_>) -> Result<()> {
776790
let self_update = !m.is_present("no-self-update") && !self_update::NEVER_SELF_UPDATE;
791+
if let Some(p) = m.value_of("profile") {
792+
let p = Profile::from_str(p)?;
793+
cfg.set_profile_override(p);
794+
}
795+
let cfg = &cfg;
777796
if let Some(names) = m.values_of("toolchain") {
778797
for name in names {
779798
update_bare_triple_check(cfg, name)?;
@@ -1307,7 +1326,7 @@ fn set_default_host_triple(cfg: &Cfg, m: &ArgMatches<'_>) -> Result<()> {
13071326
Ok(())
13081327
}
13091328

1310-
fn set_profile(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
1329+
fn set_profile(cfg: &mut Cfg, m: &ArgMatches) -> Result<()> {
13111330
cfg.set_profile(&m.value_of("profile-name").unwrap())?;
13121331
Ok(())
13131332
}

src/cli/self_update.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -746,7 +746,7 @@ fn maybe_install_rust(
746746
verbose: bool,
747747
quiet: bool,
748748
) -> Result<()> {
749-
let cfg = common::set_globals(verbose, quiet)?;
749+
let mut cfg = common::set_globals(verbose, quiet)?;
750750
cfg.set_profile(profile_str)?;
751751

752752
// If there is already an install, then `toolchain_str` may not be

src/config.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ impl Display for OverrideReason {
3232
}
3333

3434
pub struct Cfg {
35+
pub profile_override: Option<dist::Profile>,
3536
pub rustup_dir: PathBuf,
3637
pub settings_file: SettingsFile,
3738
pub toolchains_dir: PathBuf,
@@ -94,6 +95,7 @@ impl Cfg {
9495
let dist_root = dist_root_server.clone() + "/dist";
9596

9697
let cfg = Self {
98+
profile_override: None,
9799
rustup_dir,
98100
settings_file,
99101
toolchains_dir,
@@ -116,6 +118,10 @@ impl Cfg {
116118
Ok(cfg)
117119
}
118120

121+
pub fn set_profile_override(&mut self, profile: dist::Profile) {
122+
self.profile_override = Some(profile);
123+
}
124+
119125
pub fn set_default(&self, toolchain: &str) -> Result<()> {
120126
self.settings_file.with_mut(|s| {
121127
s.default_toolchain = Some(toolchain.to_owned());
@@ -125,10 +131,11 @@ impl Cfg {
125131
Ok(())
126132
}
127133

128-
pub fn set_profile(&self, profile: &str) -> Result<()> {
134+
pub fn set_profile(&mut self, profile: &str) -> Result<()> {
129135
if !dist::Profile::names().contains(&profile) {
130136
return Err(ErrorKind::UnknownProfile(profile.to_owned()).into());
131137
}
138+
self.profile_override = None;
132139
self.settings_file.with_mut(|s| {
133140
s.profile = Some(profile.to_owned());
134141
Ok(())
@@ -145,6 +152,9 @@ impl Cfg {
145152
// a user upgrades from a version of Rustup without profiles to a version of
146153
// Rustup with profiles.
147154
pub fn get_profile(&self) -> Result<dist::Profile> {
155+
if let Some(p) = self.profile_override {
156+
return Ok(p);
157+
}
148158
self.settings_file.with(|s| {
149159
let p = match &s.profile {
150160
Some(p) => p,

tests/cli-v2.rs

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
pub mod mock;
55

66
use crate::mock::clitools::{
7-
self, expect_err, expect_not_stderr_ok, expect_not_stdout_ok, expect_ok, expect_ok_ex,
8-
expect_stderr_ok, expect_stdout_ok, set_current_dist_date, this_host_triple, Config, Scenario,
7+
self, expect_component_executable, expect_component_not_executable, expect_err,
8+
expect_not_stderr_ok, expect_not_stdout_ok, expect_ok, expect_ok_ex, expect_stderr_ok,
9+
expect_stdout_ok, set_current_dist_date, this_host_triple, Config, Scenario,
910
};
1011
use std::fs;
1112
use std::io::Write;
@@ -73,6 +74,42 @@ fn install_toolchain_from_version() {
7374
});
7475
}
7576

77+
#[test]
78+
fn install_with_profile() {
79+
setup_complex(&|config| {
80+
// Start with a config that uses the "complete" profile
81+
set_current_dist_date(config, "2015-01-01");
82+
expect_ok(config, &["rustup", "set", "profile", "complete"]);
83+
84+
// Installing with minimal profile should only install rustc
85+
expect_ok(
86+
config,
87+
&[
88+
"rustup",
89+
"toolchain",
90+
"install",
91+
"--profile",
92+
"minimal",
93+
"nightly",
94+
"--no-self-update",
95+
],
96+
);
97+
expect_ok(config, &["rustup", "default", "nightly"]);
98+
99+
expect_component_executable(config, "rustup");
100+
expect_component_executable(config, "rustc");
101+
expect_component_not_executable(config, "cargo");
102+
103+
// After an update, we should _still_ only have the profile-dictated components
104+
set_current_dist_date(config, "2015-01-02");
105+
expect_ok(config, &["rustup", "update", "nightly", "--no-self-update"]);
106+
107+
expect_component_executable(config, "rustup");
108+
expect_component_executable(config, "rustc");
109+
expect_component_not_executable(config, "cargo");
110+
});
111+
}
112+
76113
#[test]
77114
fn default_existing_toolchain() {
78115
setup(&|config| {

0 commit comments

Comments
 (0)