Skip to content

Commit

Permalink
feat: add filtering options to ls-remote (#1063)
Browse files Browse the repository at this point in the history
* feat: add remote version sorting and filtering

* use `UserVersion` for filtering

* add additional lts filter

* refactor: use `Vec::retain` instead of filtering and collecting

* fix docstring for sort option

* change docstring for filter argument

* refactor vec filtering

Co-authored-by: Brennan Kinney <[email protected]>

* refactor to use `sort_by_key` and `reverse`

Co-authored-by: Brennan Kinney <[email protected]>

* add latest flag

* make filter an option as well

* move sort into command as it is presentational

* fix getting latest version

* refactors

* update docs/commands.md

* sort upon installation

* fix clippy

* don't mention rust structs in the cli docs

* sort by default

* remove leftover temp dir from test

---------

Co-authored-by: Brennan Kinney <[email protected]>
Co-authored-by: Gal Schlezinger <[email protected]>
  • Loading branch information
3 people authored May 27, 2024
1 parent 536fceb commit 121128f
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/fifty-emus-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"fnm": minor
---

feat: add remote version sorting and filtering
18 changes: 18 additions & 0 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ List all remote Node.js versions
Usage: fnm list-remote [OPTIONS]
Options:
--filter <FILTER>
Filter versions by a user-defined version or a semver range
--node-dist-mirror <NODE_DIST_MIRROR>
<https://nodejs.org/dist/> mirror
Expand All @@ -92,6 +95,21 @@ Options:
[env: FNM_DIR]
--lts [<LTS>]
Show only LTS versions (optionally filter by LTS codename)
--sort <SORT>
Version sorting order
[default: asc]
Possible values:
- desc: Sort versions in descending order (latest to earliest)
- asc: Sort versions in ascending order (earliest to latest)
--latest
Only show the latest matching version
--log-level <LOG_LEVEL>
The log level of fnm commands
Expand Down
67 changes: 63 additions & 4 deletions src/commands/ls_remote.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,79 @@
use crate::config::FnmConfig;
use crate::remote_node_index;
use crate::user_version::UserVersion;

use colored::Colorize;
use thiserror::Error;

#[derive(clap::Parser, Debug)]
pub struct LsRemote {}
pub struct LsRemote {
/// Filter versions by a user-defined version or a semver range
#[arg(long)]
filter: Option<UserVersion>,

/// Show only LTS versions (optionally filter by LTS codename)
#[arg(long)]
#[allow(clippy::option_option)]
lts: Option<Option<String>>,

/// Version sorting order
#[arg(long, default_value = "asc")]
sort: SortingMethod,

/// Only show the latest matching version
#[arg(long)]
latest: bool,
}

#[derive(clap::ValueEnum, Clone, Debug, PartialEq)]
pub enum SortingMethod {
#[clap(name = "desc")]
/// Sort versions in descending order (latest to earliest)
Descending,
#[clap(name = "asc")]
/// Sort versions in ascending order (earliest to latest)
Ascending,
}

impl super::command::Command for LsRemote {
type Error = Error;

fn apply(self, config: &FnmConfig) -> Result<(), Self::Error> {
let all_versions = remote_node_index::list(&config.node_dist_mirror)?;
let mut all_versions = remote_node_index::list(&config.node_dist_mirror)?;

if let Some(lts) = &self.lts {
match lts {
Some(codename) => all_versions.retain(|v| {
v.lts
.as_ref()
.is_some_and(|v_lts| v_lts.eq_ignore_ascii_case(codename))
}),
None => all_versions.retain(|v| v.lts.is_some()),
};
}

if let Some(filter) = &self.filter {
all_versions.retain(|v| filter.matches(&v.version, config));
}

if self.latest {
all_versions.truncate(1);
}

all_versions.sort_by_key(|v| v.version.clone());
if let SortingMethod::Descending = self.sort {
all_versions.reverse();
}

if all_versions.is_empty() {
eprintln!("{}", "No versions were found!".red());
return Ok(());
}

for version in all_versions {
for version in &all_versions {
print!("{}", version.version);
if let Some(lts) = &version.lts {
print!(" ({lts})");
print!("{}", format!(" ({lts})").cyan());
}
println!();
}
Expand Down

0 comments on commit 121128f

Please sign in to comment.