Skip to content

Commit

Permalink
feat: add latest alias when installing --latest (#896)
Browse files Browse the repository at this point in the history
* create `latest` alias on install

* add e2e tests for `latest`

* merge conditionals

* Add changeset

* fix clippy

---------

Co-authored-by: Gal Schlezinger <gal@spitfire.co.il>
  • Loading branch information
pedrofialho and Schniz committed May 27, 2024
1 parent 1b86087 commit 7b47b3e
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/many-sloths-fry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"fnm": minor
---

`fnm install latest` will now tag the `latest` alias
32 changes: 32 additions & 0 deletions e2e/__snapshots__/latest.test.ts.snap
Original file line number Diff line number Diff line change
@@ -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'"
`;
19 changes: 19 additions & 0 deletions e2e/latest.test.ts
Original file line number Diff line number Diff line change
@@ -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)
})
})
}
26 changes: 16 additions & 10 deletions src/commands/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
9 changes: 9 additions & 0 deletions src/user_version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ impl UserVersion {
}
}
}

/// The inferred alias for the user version, if it exists.
pub fn inferred_alias(&self) -> Option<Version> {
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<Item = &'a str>>(i: &mut It) -> Option<T> {
Expand Down

0 comments on commit 7b47b3e

Please sign in to comment.