Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 14 additions & 22 deletions src/cli/rustup_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,9 @@ use std::fmt;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::ExitStatus;
use std::str::FromStr;

use anyhow::{anyhow, Error, Result};
use clap::{
builder::{PossibleValue, PossibleValuesParser},
Args, CommandFactory, Parser, Subcommand, ValueEnum,
};
use clap::{builder::PossibleValue, Args, CommandFactory, Parser, Subcommand, ValueEnum};
use clap_complete::Shell;
use itertools::Itertools;

Expand Down Expand Up @@ -333,8 +329,8 @@ struct UpdateOpts {
)]
toolchain: Vec<PartialToolchainDesc>,

#[arg(long, value_parser = PossibleValuesParser::new(Profile::names()))]
profile: Option<String>,
#[arg(long, value_enum)]
profile: Option<Profile>,

/// Add specific components on installation
#[arg(short, long, value_delimiter = ',', num_args = 1..)]
Expand Down Expand Up @@ -518,20 +514,14 @@ enum SetSubcmd {

/// The default components installed with a toolchain
Profile {
#[arg(
default_value = Profile::default_name(),
value_parser = PossibleValuesParser::new(Profile::names()),
)]
profile_name: String,
#[arg(value_enum, default_value_t)]
profile_name: Profile,
},

/// The rustup auto self update mode
AutoSelfUpdate {
#[arg(
default_value = SelfUpdateMode::default_mode(),
value_parser = PossibleValuesParser::new(SelfUpdateMode::modes()),
)]
auto_self_update_mode: String,
#[arg(value_enum, default_value_t)]
auto_self_update_mode: SelfUpdateMode,
},
}

Expand Down Expand Up @@ -710,11 +700,11 @@ pub async fn main(current_dir: PathBuf) -> Result<utils::ExitCode> {
.set_default_host_triple(host_triple)
.map(|_| utils::ExitCode(0)),
SetSubcmd::Profile { profile_name } => {
cfg.set_profile(&profile_name).map(|_| utils::ExitCode(0))
cfg.set_profile(profile_name).map(|_| utils::ExitCode(0))
}
SetSubcmd::AutoSelfUpdate {
auto_self_update_mode,
} => set_auto_self_update(cfg, &auto_self_update_mode),
} => set_auto_self_update(cfg, auto_self_update_mode),
},
RustupSubcmd::Completions { shell, command } => output_completion_script(shell, command),
}
Expand Down Expand Up @@ -819,8 +809,7 @@ async fn update(cfg: &mut Cfg, opts: UpdateOpts) -> Result<utils::ExitCode> {
&& self_update_mode == SelfUpdateMode::Enable
&& !opts.no_self_update;
let forced = opts.force_non_host;
if let Some(p) = &opts.profile {
let p = Profile::from_str(p)?;
if let Some(p) = opts.profile {
cfg.set_profile_override(p);
}
let cfg = &cfg;
Expand Down Expand Up @@ -1515,7 +1504,10 @@ async fn man(
Ok(utils::ExitCode(0))
}

fn set_auto_self_update(cfg: &mut Cfg, auto_self_update_mode: &str) -> Result<utils::ExitCode> {
fn set_auto_self_update(
cfg: &mut Cfg,
auto_self_update_mode: SelfUpdateMode,
) -> Result<utils::ExitCode> {
if self_update::NEVER_SELF_UPDATE {
let process = process();
let mut args = process.args_os();
Expand Down
54 changes: 34 additions & 20 deletions src/cli/self_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ use std::{env, fmt};

use anyhow::{anyhow, Context, Result};
use cfg_if::cfg_if;
use clap::builder::PossibleValue;
use clap::ValueEnum;
use itertools::Itertools;
use same_file::Handle;
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -88,7 +91,7 @@ pub use windows::complete_windows_uninstall;
pub(crate) struct InstallOpts<'a> {
pub default_host_triple: Option<String>,
pub default_toolchain: Option<MaybeOfficialToolchainName>,
pub profile: String,
pub profile: Profile,
pub no_modify_path: bool,
pub no_update_toolchain: bool,
pub components: &'a [&'a str],
Expand All @@ -107,7 +110,7 @@ impl<'a> InstallOpts<'a> {
targets,
} = self;

cfg.set_profile(&profile)?;
cfg.set_profile(profile)?;

if let Some(default_host_triple) = &default_host_triple {
// Set host triple now as it will affect resolution of toolchain_str
Expand Down Expand Up @@ -202,13 +205,13 @@ impl<'a> InstallOpts<'a> {
.unwrap_or("stable".into()),
)?)?);

self.profile = common::question_str(
self.profile = <Profile as FromStr>::from_str(&common::question_str(
&format!(
"Profile (which tools and data to install)? ({})",
Profile::names().join("/")
Profile::value_variants().iter().join("/"),
),
&self.profile,
)?;
self.profile.as_str(),
)?)?;

self.no_modify_path =
!common::question_bool("Modify PATH variable?", !self.no_modify_path)?;
Expand Down Expand Up @@ -241,21 +244,36 @@ pub(crate) const NEVER_SELF_UPDATE: bool = true;
#[cfg(not(feature = "no-self-update"))]
pub(crate) const NEVER_SELF_UPDATE: bool = false;

#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "kebab-case")]
pub enum SelfUpdateMode {
#[default]
Enable,
Disable,
CheckOnly,
}

impl SelfUpdateMode {
pub(crate) fn modes() -> &'static [&'static str] {
&["enable", "disable", "check-only"]
pub(crate) fn as_str(&self) -> &'static str {
match self {
Self::Enable => "enable",
Self::Disable => "disable",
Self::CheckOnly => "check-only",
}
}
}

pub(crate) fn default_mode() -> &'static str {
"enable"
impl ValueEnum for SelfUpdateMode {
fn value_variants<'a>() -> &'a [Self] {
&[Self::Enable, Self::Disable, Self::CheckOnly]
}

fn to_possible_value(&self) -> Option<PossibleValue> {
Some(PossibleValue::new(self.as_str()))
}

fn from_str(input: &str, _: bool) -> Result<Self, String> {
<Self as FromStr>::from_str(input).map_err(|e| e.to_string())
}
}

Expand All @@ -270,19 +288,15 @@ impl FromStr for SelfUpdateMode {
_ => Err(anyhow!(format!(
"unknown self update mode: '{}'; valid modes are {}",
mode,
Self::modes().join(", "),
Self::value_variants().iter().join(", ")
))),
}
}
}

impl std::fmt::Display for SelfUpdateMode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
SelfUpdateMode::Enable => "enable",
SelfUpdateMode::Disable => "disable",
SelfUpdateMode::CheckOnly => "check-only",
})
f.write_str(self.as_str())
}
}

Expand Down Expand Up @@ -1313,7 +1327,7 @@ mod tests {

use crate::cli::common;
use crate::cli::self_update::InstallOpts;
use crate::dist::dist::PartialToolchainDesc;
use crate::dist::dist::{PartialToolchainDesc, Profile};
use crate::test::{test_dir, with_rustup_home, Env};
use crate::{currentprocess, for_host};

Expand All @@ -1329,8 +1343,8 @@ mod tests {

let opts = InstallOpts {
default_host_triple: None,
default_toolchain: None, // No toolchain specified
profile: "default".to_owned(), // default profile
default_toolchain: None, // No toolchain specified
profile: Profile::Default, // default profile
no_modify_path: false,
components: &[],
targets: &[],
Expand Down
12 changes: 4 additions & 8 deletions src/cli/setup_mode.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::path::PathBuf;

use anyhow::Result;
use clap::{builder::PossibleValuesParser, Parser};
use clap::Parser;

use crate::{
cli::{
Expand Down Expand Up @@ -43,12 +43,8 @@ struct RustupInit {
#[arg(long)]
default_toolchain: Option<MaybeOfficialToolchainName>,

#[arg(
long,
value_parser = PossibleValuesParser::new(Profile::names()),
default_value = Profile::default_name(),
)]
profile: String,
#[arg(long, value_enum, default_value_t)]
profile: Profile,

/// Component name to also install
#[arg(short, long, value_delimiter = ',', num_args = 1..)]
Expand Down Expand Up @@ -110,7 +106,7 @@ pub async fn main(current_dir: PathBuf) -> Result<utils::ExitCode> {
return Ok(utils::ExitCode(0));
}

if &profile == "complete" {
if profile == Profile::Complete {
warn!("{}", common::WARN_COMPLETE_PROFILE);
}

Expand Down
56 changes: 20 additions & 36 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,33 +370,23 @@ impl Cfg {
Ok(())
}

pub(crate) fn set_profile(&mut self, profile: &str) -> Result<()> {
match Profile::from_str(profile) {
Ok(p) => {
self.profile_override = None;
self.settings_file.with_mut(|s| {
s.profile = Some(p);
Ok(())
})?;
(self.notify_handler)(Notification::SetProfile(profile));
Ok(())
}
Err(err) => Err(err),
}
pub(crate) fn set_profile(&mut self, profile: Profile) -> Result<()> {
self.profile_override = None;
self.settings_file.with_mut(|s| {
s.profile = Some(profile);
Ok(())
})?;
(self.notify_handler)(Notification::SetProfile(profile.as_str()));
Ok(())
}

pub(crate) fn set_auto_self_update(&mut self, mode: &str) -> Result<()> {
match SelfUpdateMode::from_str(mode) {
Ok(update_mode) => {
self.settings_file.with_mut(|s| {
s.auto_self_update = Some(update_mode);
Ok(())
})?;
(self.notify_handler)(Notification::SetSelfUpdate(mode));
Ok(())
}
Err(err) => Err(err),
}
pub(crate) fn set_auto_self_update(&mut self, mode: SelfUpdateMode) -> Result<()> {
self.settings_file.with_mut(|s| {
s.auto_self_update = Some(mode);
Ok(())
})?;
(self.notify_handler)(Notification::SetSelfUpdate(mode.as_str()));
Ok(())
}

pub(crate) fn set_toolchain_override(&mut self, toolchain_override: &ResolvableToolchainName) {
Expand All @@ -414,22 +404,16 @@ impl Cfg {
if let Some(p) = self.profile_override {
return Ok(p);
}
self.settings_file.with(|s| {
let p = match s.profile {
Some(p) => p,
None => Profile::Default,
};
Ok(p)
})
self.settings_file
.with(|s| Ok(s.profile.unwrap_or_default()))
}

pub(crate) fn get_self_update_mode(&self) -> Result<SelfUpdateMode> {
self.settings_file.with(|s| {
let mode = match &s.auto_self_update {
Some(mode) => mode.clone(),
Ok(match s.auto_self_update {
Some(mode) => mode,
None => SelfUpdateMode::Enable,
};
Ok(mode)
})
})
}

Expand Down
Loading