diff --git a/src/commands/use.rs b/src/commands/use.rs index 4b0757c..5ccfe6a 100644 --- a/src/commands/use.rs +++ b/src/commands/use.rs @@ -42,14 +42,13 @@ impl Command for Use { system_version::path() } else if let Some(alias_name) = requested_version.alias_name() { let alias_path = config.aliases_dir().join(&alias_name); - ensure!( - alias_path.exists(), - CantFindVersion { - version: requested_version - } - ); - outln!(config#Info, "Using Node for alias {}", alias_name.cyan()); - alias_path + if alias_path.exists() { + outln!(config#Info, "Using Node for alias {}", alias_name.cyan()); + alias_path + } else { + install_new_version(requested_version, config, self.install_if_missing)?; + return Ok(()); + } } else { let current_version = requested_version.to_version(&all_versions, &config); match current_version { @@ -61,26 +60,7 @@ impl Command for Use { .join("installation") } None => { - ensure!( - self.install_if_missing || should_install_interactively(&requested_version), - CantFindVersion { - version: requested_version - } - ); - - Install { - version: Some(requested_version.clone()), - ..Default::default() - } - .apply(config) - .context(InstallError)?; - - Self { - version: Some(UserVersionReader::Direct(requested_version)), - install_if_missing: self.install_if_missing, - } - .apply(config)?; - + install_new_version(requested_version, config, self.install_if_missing)?; return Ok(()); } } @@ -92,6 +72,34 @@ impl Command for Use { } } +fn install_new_version( + requested_version: UserVersion, + config: &FnmConfig, + install_if_missing: bool, +) -> Result<(), Error> { + ensure!( + install_if_missing || should_install_interactively(&requested_version), + CantFindVersion { + version: requested_version + } + ); + + Install { + version: Some(requested_version.clone()), + ..Default::default() + } + .apply(config) + .context(InstallError)?; + + Use { + version: Some(UserVersionReader::Direct(requested_version)), + install_if_missing: true, + } + .apply(config)?; + + return Ok(()); +} + /// Tries to delete `from`, and then tries to symlink `from` to `to` anyway. /// If the symlinking fails, it will return the errors in the following order: /// * The deletion error (if exists) diff --git a/tests/feature_tests/mod.rs b/tests/feature_tests/mod.rs index fa415e8..a34f46f 100644 --- a/tests/feature_tests/mod.rs +++ b/tests/feature_tests/mod.rs @@ -200,3 +200,21 @@ mod matching_dotfiles { .then(test_node_version("v11.10.0")) }); } + +mod use_alias_install_if_missing { + test_shell!(Bash, Zsh, Fish, PowerShell; { + EvalFnmEnv::default() + .then(WriteFile::new(".node-version", "lts/*")) + .then(Call::new("fnm", vec!["use", "--install-if-missing"])) + .then(OutputContains::new(Call::new("fnm", vec!["ls"]), "lts-latest")) + }); +} + +mod use_alias_not_installed { + test_shell!(Bash, Zsh, Fish, PowerShell; { + EvalFnmEnv::default() + .log_level(Some("error")) + .then(WriteFile::new(".node-version", "lts/*")) + .then(OutputContains::new(IgnoreErrors::new(GetStderr::new(Call::new("fnm", vec!["use"]))), "Requested version lts-latest is not currently installed")) + }); +} diff --git a/tests/feature_tests/snapshots/e2e__feature_tests__use_alias_install_if_missing__Bash.snap b/tests/feature_tests/snapshots/e2e__feature_tests__use_alias_install_if_missing__Bash.snap new file mode 100644 index 0000000..31cf2ef --- /dev/null +++ b/tests/feature_tests/snapshots/e2e__feature_tests__use_alias_install_if_missing__Bash.snap @@ -0,0 +1,11 @@ +--- +source: tests/feature_tests/mod.rs +expression: "&source.trim()" +--- +set -e +shopt -s expand_aliases + +eval "$(fnm env)" +echo 'lts/*' > .node-version +fnm use --install-if-missing +fnm ls | grep lts-latest diff --git a/tests/feature_tests/snapshots/e2e__feature_tests__use_alias_install_if_missing__Fish.snap b/tests/feature_tests/snapshots/e2e__feature_tests__use_alias_install_if_missing__Fish.snap new file mode 100644 index 0000000..e088983 --- /dev/null +++ b/tests/feature_tests/snapshots/e2e__feature_tests__use_alias_install_if_missing__Fish.snap @@ -0,0 +1,8 @@ +--- +source: tests/feature_tests/mod.rs +expression: "&source.trim()" +--- +fnm env | source +echo 'lts/*' > .node-version +fnm use --install-if-missing +fnm ls | grep lts-latest diff --git a/tests/feature_tests/snapshots/e2e__feature_tests__use_alias_install_if_missing__PowerShell.snap b/tests/feature_tests/snapshots/e2e__feature_tests__use_alias_install_if_missing__PowerShell.snap new file mode 100644 index 0000000..85d36b8 --- /dev/null +++ b/tests/feature_tests/snapshots/e2e__feature_tests__use_alias_install_if_missing__PowerShell.snap @@ -0,0 +1,9 @@ +--- +source: tests/feature_tests/mod.rs +expression: "&source.trim()" +--- +$ErrorActionPreference = "Stop" +fnm env | Out-String | Invoke-Expression +echo 'lts/*' > '.node-version' +fnm use --install-if-missing +$($__out__ = $(fnm ls | Select-String 'lts-latest'); echo $__out__; if ($__out__ -eq $null){ exit 1 } else { $__out__ }) diff --git a/tests/feature_tests/snapshots/e2e__feature_tests__use_alias_install_if_missing__Zsh.snap b/tests/feature_tests/snapshots/e2e__feature_tests__use_alias_install_if_missing__Zsh.snap new file mode 100644 index 0000000..4b49db9 --- /dev/null +++ b/tests/feature_tests/snapshots/e2e__feature_tests__use_alias_install_if_missing__Zsh.snap @@ -0,0 +1,9 @@ +--- +source: tests/feature_tests/mod.rs +expression: "&source.trim()" +--- +set -e +eval "$(fnm env)" +echo 'lts/*' > .node-version +fnm use --install-if-missing +fnm ls | grep lts-latest diff --git a/tests/feature_tests/snapshots/e2e__feature_tests__use_alias_not_installed__Bash.snap b/tests/feature_tests/snapshots/e2e__feature_tests__use_alias_not_installed__Bash.snap new file mode 100644 index 0000000..517e2b8 --- /dev/null +++ b/tests/feature_tests/snapshots/e2e__feature_tests__use_alias_not_installed__Bash.snap @@ -0,0 +1,10 @@ +--- +source: tests/feature_tests/mod.rs +expression: "&source.trim()" +--- +set -e +shopt -s expand_aliases + +eval "$(fnm --log-level='error' env)" +echo 'lts/*' > .node-version +fnm use 2>&1 | grep 'Requested version lts-latest is not currently installed' diff --git a/tests/feature_tests/snapshots/e2e__feature_tests__use_alias_not_installed__Fish.snap b/tests/feature_tests/snapshots/e2e__feature_tests__use_alias_not_installed__Fish.snap new file mode 100644 index 0000000..f5c6918 --- /dev/null +++ b/tests/feature_tests/snapshots/e2e__feature_tests__use_alias_not_installed__Fish.snap @@ -0,0 +1,7 @@ +--- +source: tests/feature_tests/mod.rs +expression: "&source.trim()" +--- +fnm --log-level='error' env | source +echo 'lts/*' > .node-version +fnm use 2>&1 | grep 'Requested version lts-latest is not currently installed' diff --git a/tests/feature_tests/snapshots/e2e__feature_tests__use_alias_not_installed__PowerShell.snap b/tests/feature_tests/snapshots/e2e__feature_tests__use_alias_not_installed__PowerShell.snap new file mode 100644 index 0000000..ffebbc6 --- /dev/null +++ b/tests/feature_tests/snapshots/e2e__feature_tests__use_alias_not_installed__PowerShell.snap @@ -0,0 +1,8 @@ +--- +source: tests/feature_tests/mod.rs +expression: "&source.trim()" +--- +$ErrorActionPreference = "Stop" +fnm --log-level='error' env | Out-String | Invoke-Expression +echo 'lts/*' > '.node-version' +$($__out__ = $($($_tmp_err_action = $ErrorActionPreference;$ErrorActionPreference = "Continue";fnm use 2>&1;$ErrorActionPreference = $_tmp_err_action) | Select-String 'Requested version lts-latest is not currently installed'); echo $__out__; if ($__out__ -eq $null){ exit 1 } else { $__out__ }) diff --git a/tests/feature_tests/snapshots/e2e__feature_tests__use_alias_not_installed__Zsh.snap b/tests/feature_tests/snapshots/e2e__feature_tests__use_alias_not_installed__Zsh.snap new file mode 100644 index 0000000..b34e2bf --- /dev/null +++ b/tests/feature_tests/snapshots/e2e__feature_tests__use_alias_not_installed__Zsh.snap @@ -0,0 +1,8 @@ +--- +source: tests/feature_tests/mod.rs +expression: "&source.trim()" +--- +set -e +eval "$(fnm --log-level='error' env)" +echo 'lts/*' > .node-version +fnm use 2>&1 | grep 'Requested version lts-latest is not currently installed'