From 66fdf0f06a0074cb528190d1538d1d0b86294c5b Mon Sep 17 00:00:00 2001 From: Jon Gjengset Date: Sat, 19 Oct 2019 15:50:44 -0400 Subject: [PATCH] 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. --- src/cli/rustup_mode.rs | 29 ++++++++++++++++++++++++----- src/cli/self_update.rs | 2 +- src/config.rs | 12 +++++++++++- tests/cli-v2.rs | 41 +++++++++++++++++++++++++++++++++++++++-- 4 files changed, 75 insertions(+), 9 deletions(-) diff --git a/src/cli/rustup_mode.rs b/src/cli/rustup_mode.rs index 77042252d5..a450b2ad0f 100644 --- a/src/cli/rustup_mode.rs +++ b/src/cli/rustup_mode.rs @@ -33,7 +33,7 @@ pub fn main() -> Result<()> { let matches = cli().get_matches(); let verbose = matches.is_present("verbose"); let quiet = matches.is_present("quiet"); - let cfg = &common::set_globals(verbose, quiet)?; + let cfg = &mut common::set_globals(verbose, quiet)?; if maybe_upgrade_data(cfg, &matches)? { return Ok(()); @@ -89,8 +89,8 @@ pub fn main() -> Result<()> { (_, _) => unreachable!(), }, ("set", Some(c)) => match c.subcommand() { - ("default-host", Some(m)) => set_default_host_triple(&cfg, m)?, - ("profile", Some(m)) => set_profile(&cfg, m)?, + ("default-host", Some(m)) => set_default_host_triple(cfg, m)?, + ("profile", Some(m)) => set_profile(cfg, m)?, (_, _) => unreachable!(), }, ("completions", Some(c)) => { @@ -169,6 +169,13 @@ pub fn cli() -> App<'static, 'static> { .required(true) .multiple(true), ) + .arg( + Arg::with_name("profile") + .long("profile") + .takes_value(true) + .possible_values(Profile::names()) + .required(false) + ) .arg( Arg::with_name("no-self-update") .help("Don't perform self-update when running the `rustup install` command") @@ -258,6 +265,13 @@ pub fn cli() -> App<'static, 'static> { .required(true) .multiple(true), ) + .arg( + Arg::with_name("profile") + .long("profile") + .takes_value(true) + .possible_values(Profile::names()) + .required(false) + ) .arg( Arg::with_name("no-self-update") .help("Don't perform self update when running the `rustup toolchain install` command") @@ -772,8 +786,13 @@ fn check_updates(cfg: &Cfg) -> Result<()> { Ok(()) } -fn update(cfg: &Cfg, m: &ArgMatches<'_>) -> Result<()> { +fn update(cfg: &mut Cfg, m: &ArgMatches<'_>) -> Result<()> { let self_update = !m.is_present("no-self-update") && !self_update::NEVER_SELF_UPDATE; + if let Some(p) = m.value_of("profile") { + let p = Profile::from_str(p)?; + cfg.set_profile_override(p); + } + let cfg = &cfg; if let Some(names) = m.values_of("toolchain") { for name in names { update_bare_triple_check(cfg, name)?; @@ -1307,7 +1326,7 @@ fn set_default_host_triple(cfg: &Cfg, m: &ArgMatches<'_>) -> Result<()> { Ok(()) } -fn set_profile(cfg: &Cfg, m: &ArgMatches) -> Result<()> { +fn set_profile(cfg: &mut Cfg, m: &ArgMatches) -> Result<()> { cfg.set_profile(&m.value_of("profile-name").unwrap())?; Ok(()) } diff --git a/src/cli/self_update.rs b/src/cli/self_update.rs index fc63d7ecea..6fdd6f06e3 100644 --- a/src/cli/self_update.rs +++ b/src/cli/self_update.rs @@ -746,7 +746,7 @@ fn maybe_install_rust( verbose: bool, quiet: bool, ) -> Result<()> { - let cfg = common::set_globals(verbose, quiet)?; + let mut cfg = common::set_globals(verbose, quiet)?; cfg.set_profile(profile_str)?; // If there is already an install, then `toolchain_str` may not be diff --git a/src/config.rs b/src/config.rs index d12147b5ef..31bca8a0cc 100644 --- a/src/config.rs +++ b/src/config.rs @@ -32,6 +32,7 @@ impl Display for OverrideReason { } pub struct Cfg { + pub profile_override: Option, pub rustup_dir: PathBuf, pub settings_file: SettingsFile, pub toolchains_dir: PathBuf, @@ -94,6 +95,7 @@ impl Cfg { let dist_root = dist_root_server.clone() + "/dist"; let cfg = Self { + profile_override: None, rustup_dir, settings_file, toolchains_dir, @@ -116,6 +118,10 @@ impl Cfg { Ok(cfg) } + pub fn set_profile_override(&mut self, profile: dist::Profile) { + self.profile_override = Some(profile); + } + pub fn set_default(&self, toolchain: &str) -> Result<()> { self.settings_file.with_mut(|s| { s.default_toolchain = Some(toolchain.to_owned()); @@ -125,10 +131,11 @@ impl Cfg { Ok(()) } - pub fn set_profile(&self, profile: &str) -> Result<()> { + pub fn set_profile(&mut self, profile: &str) -> Result<()> { if !dist::Profile::names().contains(&profile) { return Err(ErrorKind::UnknownProfile(profile.to_owned()).into()); } + self.profile_override = None; self.settings_file.with_mut(|s| { s.profile = Some(profile.to_owned()); Ok(()) @@ -145,6 +152,9 @@ impl Cfg { // a user upgrades from a version of Rustup without profiles to a version of // Rustup with profiles. pub fn get_profile(&self) -> Result { + if let Some(p) = self.profile_override { + return Ok(p); + } self.settings_file.with(|s| { let p = match &s.profile { Some(p) => p, diff --git a/tests/cli-v2.rs b/tests/cli-v2.rs index 580bab90fc..4706cc5274 100644 --- a/tests/cli-v2.rs +++ b/tests/cli-v2.rs @@ -4,8 +4,9 @@ pub mod mock; use crate::mock::clitools::{ - self, expect_err, expect_not_stderr_ok, expect_not_stdout_ok, expect_ok, expect_ok_ex, - expect_stderr_ok, expect_stdout_ok, set_current_dist_date, this_host_triple, Config, Scenario, + self, expect_component_executable, expect_component_not_executable, expect_err, + expect_not_stderr_ok, expect_not_stdout_ok, expect_ok, expect_ok_ex, expect_stderr_ok, + expect_stdout_ok, set_current_dist_date, this_host_triple, Config, Scenario, }; use std::fs; use std::io::Write; @@ -73,6 +74,42 @@ fn install_toolchain_from_version() { }); } +#[test] +fn install_with_profile() { + setup_complex(&|config| { + // Start with a config that uses the "complete" profile + set_current_dist_date(config, "2015-01-01"); + expect_ok(config, &["rustup", "set", "profile", "complete"]); + + // Installing with minimal profile should only install rustc + expect_ok( + config, + &[ + "rustup", + "toolchain", + "install", + "--profile", + "minimal", + "nightly", + "--no-self-update", + ], + ); + expect_ok(config, &["rustup", "default", "nightly"]); + + expect_component_executable(config, "rustup"); + expect_component_executable(config, "rustc"); + expect_component_not_executable(config, "cargo"); + + // After an update, we should _still_ only have the profile-dictated components + set_current_dist_date(config, "2015-01-02"); + expect_ok(config, &["rustup", "update", "nightly", "--no-self-update"]); + + expect_component_executable(config, "rustup"); + expect_component_executable(config, "rustc"); + expect_component_not_executable(config, "cargo"); + }); +} + #[test] fn default_existing_toolchain() { setup(&|config| {