diff --git a/executable/FnmApp.re b/executable/FnmApp.re
index 26d6818..c628156 100644
--- a/executable/FnmApp.re
+++ b/executable/FnmApp.re
@@ -14,7 +14,7 @@ module Commands = {
let use = (version, quiet) => Use.run(~version, ~quiet) |> runCmd;
let alias = (version, name) => Alias.run(~name, ~version) |> runCmd;
let default = version => Alias.run(~name="default", ~version) |> runCmd;
- let listRemote = () => ListRemote.run() |> runCmd;
+ let listRemote = version => ListRemote.run(~version) |> runCmd;
let listLocal = () => ListLocal.run() |> runCmd;
let install = version => Install.run(~version) |> runCmd;
let uninstall = version => Uninstall.run(~version) |> runCmd;
@@ -146,8 +146,15 @@ let listRemote = {
let sdocs = Manpage.s_common_options;
let man = help_secs;
+ let selectedVersion = {
+ let doc = "Filter by specific $(docv).";
+ Arg.(
+ value & pos(0, some(string), None) & info([], ~docv="VERSION", ~doc)
+ );
+ };
+
(
- Term.(app(const(Commands.listRemote), const())),
+ Term.(const(Commands.listRemote) $ selectedVersion),
Term.info(
"ls-remote",
~version,
diff --git a/executable/ListRemote.re b/executable/ListRemote.re
index d9de1a6..937520b 100644
--- a/executable/ListRemote.re
+++ b/executable/ListRemote.re
@@ -1,26 +1,50 @@
open Fnm;
-let run = () => {
+let run = (~version as maybeVersionName) => {
Console.log("Looking for some node versions upstream...");
let%lwt versions = Versions.getRemoteVersions()
and currentVersion = Versions.getCurrentVersion();
- versions
- |> List.iter(version => {
- open Versions.Remote;
- let str = "* " ++ version.name;
- let color =
- switch (currentVersion, version.installed) {
- | (Some({name: currentVersionName, _}), _)
- when currentVersionName == version.name =>
- Some(Pastel.Cyan)
- | (_, true) => Some(Pastel.Green)
- | (_, false) => None
- };
+ let versions =
+ switch (maybeVersionName) {
+ | None => versions
+ | Some(versionName) =>
+ let formattedVersionName = Versions.format(versionName);
+ versions
+ |> Versions.(
+ List.filter(v =>
+ isVersionFitsPrefix(formattedVersionName, Remote.(v.name))
+ || v.name == formattedVersionName
+ )
+ );
+ };
- Console.log( str );
- });
+ switch (versions) {
+ | [] =>
+ Console.log(
+
+ "No versions found that match your criterias."
+ ,
+ );
+ Lwt.return_error(1);
- Lwt.return_ok();
+ | _ =>
+ versions
+ |> List.iter(version => {
+ open Versions.Remote;
+ let str = "* " ++ version.name;
+ let color =
+ switch (currentVersion, version.installed) {
+ | (Some({name: currentVersionName, _}), _)
+ when currentVersionName == version.name =>
+ Some(Pastel.Cyan)
+ | (_, true) => Some(Pastel.Green)
+ | (_, false) => None
+ };
+ ();
+ Console.log( str );
+ });
+ Lwt.return_ok();
+ };
};
diff --git a/test/TestFnm.re b/test/TestFnm.re
index d9d0379..adcbb92 100644
--- a/test/TestFnm.re
+++ b/test/TestFnm.re
@@ -1,5 +1,6 @@
include SmokeTest;
include TestSemver;
include TestFs;
+include TestListRemote;
TestFramework.cli();
diff --git a/test/TestListRemote.re b/test/TestListRemote.re
new file mode 100644
index 0000000..ee27590
--- /dev/null
+++ b/test/TestListRemote.re
@@ -0,0 +1,116 @@
+open TestFramework;
+
+let allVersions6 = [
+ "v6.0.0",
+ "v6.1.0",
+ "v6.2.0",
+ "v6.2.1",
+ "v6.2.2",
+ "v6.3.0",
+ "v6.3.1",
+ "v6.4.0",
+ "v6.5.0",
+ "v6.6.0",
+ "v6.7.0",
+ "v6.8.0",
+ "v6.8.1",
+ "v6.9.0",
+ "v6.9.1",
+ "v6.9.2",
+ "v6.9.3",
+ "v6.9.4",
+ "v6.9.5",
+ "v6.10.0",
+ "v6.10.1",
+ "v6.10.2",
+ "v6.10.3",
+ "v6.11.0",
+ "v6.11.1",
+ "v6.11.2",
+ "v6.11.3",
+ "v6.11.4",
+ "v6.11.5",
+ "v6.12.0",
+ "v6.12.1",
+ "v6.12.2",
+ "v6.12.3",
+ "v6.13.0",
+ "v6.13.1",
+ "v6.14.0",
+ "v6.14.1",
+ "v6.14.2",
+ "v6.14.3",
+ "v6.14.4",
+ "v6.15.0",
+ "v6.15.1",
+ "v6.16.0",
+ "v6.17.0",
+ "v6.17.1",
+];
+
+let allVersions6_11 = [
+ "v6.11.0",
+ "v6.11.1",
+ "v6.11.2",
+ "v6.11.3",
+ "v6.11.4",
+ "v6.11.5",
+];
+
+describe("List Remote", ({test}) => {
+ let versionRegExp = Str.regexp(".*[0-9]+\.[0-9]+\.[0-9]+\|.*latest-*");
+
+ let filterVersionNumbers = response =>
+ response
+ |> String.split_on_char('\n')
+ |> List.filter(s => Str.string_match(versionRegExp, s, 0))
+ |> List.map(s => Str.replace_first(Str.regexp("\*"), "", s))
+ |> List.map(String.trim);
+
+ let runAndFilterVersionNumbers = args => run(args) |> filterVersionNumbers;
+
+ test("Should display remote versions matching a major version", ({expect}) => {
+ let versionNumbers = runAndFilterVersionNumbers([|"ls-remote", "6"|]);
+
+ expect.lines(versionNumbers).toEqualLines(allVersions6);
+ });
+ test(
+ "Should display remote versions matching a major and minor version",
+ ({expect}) => {
+ let versionNumbers = runAndFilterVersionNumbers([|"ls-remote", "6.11"|]);
+
+ expect.lines(versionNumbers).toEqualLines(allVersions6_11);
+ });
+ test(
+ "Should display remote version matching a specific version", ({expect}) => {
+ let versionNumbers =
+ runAndFilterVersionNumbers([|"ls-remote", "6.11.3"|]);
+
+ expect.int(versionNumbers |> List.length).toBe(1);
+ expect.lines(versionNumbers).toEqual("v6.11.3");
+ });
+ test("Should display latest remote version", ({expect}) => {
+ let versionNumbers =
+ runAndFilterVersionNumbers([|"ls-remote", "latest"|]);
+
+ expect.int(versionNumbers |> List.length).toBe(1);
+ expect.lines(versionNumbers).toEqual("latest");
+ });
+
+ test("Should display latest specific remote version", ({expect}) => {
+ let versionNumbers =
+ runAndFilterVersionNumbers([|"ls-remote", "latest-v6"|]);
+
+ expect.int(versionNumbers |> List.length).toBe(1);
+ expect.lines(versionNumbers).toEqual("latest-v6.x");
+ });
+ test(
+ "Should display an error message if version does not exist", ({expect}) => {
+ let result = run([|"ls-remote", "190385"|]);
+
+ let versionNumbers = result |> filterVersionNumbers;
+
+ expect.int(versionNumbers |> List.length).toBe(0);
+ expect.string(result).toMatch(".*No versions found.*");
+ });
+});