diff --git a/.changeset/many-sloths-fry.md b/.changeset/many-sloths-fry.md new file mode 100644 index 000000000..a64d094de --- /dev/null +++ b/.changeset/many-sloths-fry.md @@ -0,0 +1,5 @@ +--- +"fnm": minor +--- + +`fnm install latest` will now tag the `latest` alias diff --git a/e2e/__snapshots__/latest.test.ts.snap b/e2e/__snapshots__/latest.test.ts.snap new file mode 100644 index 000000000..8b25da341 --- /dev/null +++ b/e2e/__snapshots__/latest.test.ts.snap @@ -0,0 +1,32 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Bash installs latest: Bash 1`] = ` +"set -e +eval "$(fnm env)" +fnm install --latest +(fnm ls) | grep latest || (echo "Expected output to contain latest" && exit 1) +fnm use 'latest'" +`; + +exports[`Fish installs latest: Fish 1`] = ` +"fnm env | source +fnm install --latest +begin; fnm ls; end | grep latest; or echo "Expected output to contain latest" && exit 1 +fnm use 'latest'" +`; + +exports[`PowerShell installs latest: PowerShell 1`] = ` +"$ErrorActionPreference = "Stop" +fnm env | Out-String | Invoke-Expression +fnm install --latest +$($__out__ = $(fnm ls | Select-String latest); if ($__out__ -eq $null) { exit 1 } else { $__out__ }) +fnm use 'latest'" +`; + +exports[`Zsh installs latest: Zsh 1`] = ` +"set -e +eval "$(fnm env)" +fnm install --latest +(fnm ls) | grep latest || (echo "Expected output to contain latest" && exit 1) +fnm use 'latest'" +`; diff --git a/e2e/latest.test.ts b/e2e/latest.test.ts new file mode 100644 index 000000000..8d2a0fdd6 --- /dev/null +++ b/e2e/latest.test.ts @@ -0,0 +1,19 @@ +import { script } from "./shellcode/script.js" +import { Bash, Fish, PowerShell, Zsh } from "./shellcode/shells.js" +import describe from "./describe.js" + +for (const shell of [Bash, Zsh, Fish, PowerShell]) { + describe(shell, () => { + test(`installs latest`, async () => { + await script(shell) + .then(shell.env({})) + .then(shell.call("fnm", ["install", "--latest"])) + .then( + shell.scriptOutputContains(shell.call("fnm", ["ls"]), "latest") + ) + .then(shell.call("fnm", ["use", "'latest'"])) + .takeSnapshot(shell) + .execute(shell) + }) + }) +} diff --git a/src/commands/install.rs b/src/commands/install.rs index 79013ad1d..a0539edca 100644 --- a/src/commands/install.rs +++ b/src/commands/install.rs @@ -156,25 +156,31 @@ impl Command for Install { enable_corepack(&version, config)?; } - if let UserVersion::Full(Version::Lts(lts_type)) = current_version { - let alias_name = Version::Lts(lts_type).v_str(); - debug!( - "Tagging {} as alias for {}", - alias_name.cyan(), - version.v_str().cyan() - ); - create_alias(config, &alias_name, &version)?; - } - if !config.default_version_dir().exists() { debug!("Tagging {} as the default version", version.v_str().cyan()); create_alias(config, "default", &version)?; } + if let Some(tagged_alias) = current_version.inferred_alias() { + tag_alias(config, &version, &tagged_alias)?; + } + Ok(()) } } +fn tag_alias(config: &FnmConfig, matched_version: &Version, alias: &Version) -> Result<(), Error> { + let alias_name = alias.v_str(); + debug!( + "Tagging {} as alias for {}", + alias_name.cyan(), + matched_version.v_str().cyan() + ); + create_alias(config, &alias_name, matched_version)?; + + Ok(()) +} + fn enable_corepack(version: &Version, config: &FnmConfig) -> Result<(), Error> { let corepack_path = version.installation_path(config); let corepack_path = if cfg!(windows) { diff --git a/src/user_version.rs b/src/user_version.rs index 52c69a12f..eb43d7145 100644 --- a/src/user_version.rs +++ b/src/user_version.rs @@ -50,6 +50,15 @@ impl UserVersion { } } } + + /// The inferred alias for the user version, if it exists. + pub fn inferred_alias(&self) -> Option { + match self { + UserVersion::Full(Version::Latest) => Some(Version::Latest), + UserVersion::Full(Version::Lts(lts_type)) => Some(Version::Lts(lts_type.clone())), + _ => None, + } + } } fn next_of<'a, T: FromStr, It: Iterator>(i: &mut It) -> Option {