From b611fa8e53c23c5a442f5a22baddd8f76f11ea7e Mon Sep 17 00:00:00 2001 From: David Soria Parra Date: Fri, 16 Feb 2024 13:27:57 +0000 Subject: [PATCH] add --modify-path and --no-modify-path to rye self install This adds the option to never modify paths to rye install, even when `--yes` is provided. This addresses #620. We offer a --modify-path and a --no-modify-path option to either always modify or never modify. Providing --yes, will be the same as --modify-path. This is in line with other command line tools like curl, git and ripgrep. We do this by adding a new enum YesNoArg, which can be obtained by providing an ArgGroup with respective modify_path and no_modify_path boolean values. --- rye/src/cli/rye.rs | 66 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/rye/src/cli/rye.rs b/rye/src/cli/rye.rs index c3d1551bef..d6ceddd753 100644 --- a/rye/src/cli/rye.rs +++ b/rye/src/cli/rye.rs @@ -96,6 +96,50 @@ pub struct InstallCommand { /// Use a specific toolchain version. #[arg(long)] toolchain_version: Option, + + #[command(flatten)] + mp: ModifyPath, +} + +#[derive(Parser, Debug)] +#[group(required = false, multiple = false)] +pub struct ModifyPath { + /// Always modify without asking the PATH environment variable. + #[arg(long)] + modify_path: bool, + /// Do not modify the PATH environment variable. + #[arg(long)] + no_modify_path: bool, +} + +#[derive(Debug, Copy, Clone)] +enum YesNoArg { + Yes, + No, + Ask, +} + +impl YesNoArg { + fn with_yes(&self, yes: bool) -> Self { + match (yes, self) { + (true, Self::Ask) => Self::Yes, + _ => *self, + } + } +} +impl From for YesNoArg { + fn from(other: ModifyPath) -> Self { + // Argument parsing logic is a bit complex here: + match (other.modify_path, other.no_modify_path) { + // 1. If --modify-path is set and --no-modify-path is not set, we always modify the path without prompting. + (true, false) => YesNoArg::Yes, + // 2. If --no-modify-path is set and --modify-path is not set, we never modify the path. + (false, true) => YesNoArg::No, + // 3. Otherwise we ask the user + (false, false) => YesNoArg::Ask, + (true, true) => unreachable!(), + } + } } #[derive(Debug, Copy, Clone)] @@ -263,6 +307,7 @@ fn install(args: InstallCommand) -> Result<(), Error> { }, args.toolchain.as_deref(), args.toolchain_version, + YesNoArg::from(args.mp).with_yes(args.yes), ) } @@ -351,6 +396,7 @@ fn perform_install( mode: InstallMode, toolchain_path: Option<&Path>, toolchain_version: Option, + modify_path: YesNoArg, ) -> Result<(), Error> { let mut config = Config::current(); let mut registered_toolchain: Option = None; @@ -547,7 +593,20 @@ fn perform_install( prompt_for_default_toolchain(registered_toolchain.unwrap(), config_doc)?; } - add_rye_to_path(&mode, shims.as_path())?; + match modify_path { + YesNoArg::Yes => { + add_rye_to_path(&mode, shims.as_path(), false)?; + } + YesNoArg::No => { + echo!( + "Skipping PATH modification. You will need to add {} to your PATH manually.", + style(shims.display()).cyan() + ); + } + YesNoArg::Ask => { + add_rye_to_path(&mode, shims.as_path(), true)?; + } + } echo!(); echo!("{}", style("All done!").green()); @@ -558,7 +617,7 @@ fn perform_install( } /// Add rye to the users path. -fn add_rye_to_path(mode: &InstallMode, shims: &Path) -> Result<(), Error> { +fn add_rye_to_path(mode: &InstallMode, shims: &Path, ask: bool) -> Result<(), Error> { let rye_home = env::var("RYE_HOME") .map(Cow::Owned) .unwrap_or(Cow::Borrowed(DEFAULT_HOME)); @@ -581,6 +640,7 @@ fn add_rye_to_path(mode: &InstallMode, shims: &Path) -> Result<(), Error> { echo!("It is highly recommended that you add it."); if matches!(mode, InstallMode::NoPrompts) + || !ask || dialoguer::Confirm::with_theme(tui_theme()) .with_prompt(format!( "Should the installer add Rye to {} via .profile?", @@ -670,7 +730,7 @@ pub fn auto_self_install() -> Result { crate::request_continue_prompt(); } - perform_install(InstallMode::AutoInstall, None, None)?; + perform_install(InstallMode::AutoInstall, None, None, YesNoArg::Yes)?; Ok(true) } }