diff --git a/executable/FnmApp.re b/executable/FnmApp.re index dca37b0..4f22381 100644 --- a/executable/FnmApp.re +++ b/executable/FnmApp.re @@ -6,6 +6,7 @@ module Commands = { let listRemote = () => Lwt_main.run(ListRemote.run()); let listLocal = () => Lwt_main.run(ListLocal.run()); let install = version => Lwt_main.run(Install.run(~version)); + let uninstall = version => Lwt_main.run(Uninstall.run(~version)); let env = ( isFishShell, @@ -74,6 +75,25 @@ let install = { ); }; +let uninstall = { + let doc = "Uninstall a node version"; + let man = []; + + let selectedVersion = { + let doc = "Uninstall the node version specified in $(docv)."; + Arg.( + required + & pos(0, some(string), None) + & info([], ~docv="VERSION", ~doc) + ); + }; + + ( + Term.(const(Commands.uninstall) $ selectedVersion), + Term.info("uninstall", ~version, ~doc, ~exits=Term.default_exits, ~man), + ); +}; + let listLocal = { let doc = "List all the installed versions"; let man = []; @@ -248,6 +268,6 @@ let defaultCmd = { let _ = Term.eval_choice( defaultCmd, - [install, use, alias, listLocal, listRemote, env], + [install, uninstall, use, alias, listLocal, listRemote, env], ) |> Term.exit; diff --git a/executable/Uninstall.re b/executable/Uninstall.re new file mode 100644 index 0000000..3ea32c3 --- /dev/null +++ b/executable/Uninstall.re @@ -0,0 +1,43 @@ +open Fnm; +open Lwt; + +let run = (~version) => { + Versions.getInstalledVersions() + >|= List.find_opt(x => Versions.Local.(x.name == version)) + >>= ( + installedVersion => + switch (installedVersion) { + | None => + Logger.log( + + "The version " + version + " is not installed." + , + ); + exit(1); + | Some(installedVersion) => + { + Logger.log( + + "Uninstalling node " + + Versions.Local.(installedVersion.name) + + , + ); + }; + let%lwt _ = Versions.Local.remove(installedVersion); + Logger.log( + + "Node version " + + Versions.Local.(installedVersion.name) + + " has correctly been removed." + , + ) + |> Lwt.return; + } + ); +}; diff --git a/library/Fs.re b/library/Fs.re index 3843cb7..1ca5972 100644 --- a/library/Fs.re +++ b/library/Fs.re @@ -43,6 +43,27 @@ let readlink = path => | err => Lwt.return_error(err) }; +// Credit: https://github.com/fastpack/fastpack/blob/9f6aa7d5b83ffef03e73a15679200576ff9dbcb7/FastpackUtil/FS.re#L94 +let rec rmdir = dir => { + let%lwt files = Lwt_unix.files_of_directory(dir) |> Lwt_stream.to_list; + let%lwt () = + Lwt_list.iter_s( + filename => + switch (filename) { + | "." + | ".." => Lwt.return_unit + | _ => + let path = Filename.concat(dir, filename); + switch%lwt (Lwt_unix.stat(path)) { + | {st_kind: Lwt_unix.S_DIR, _} => rmdir(path) + | _ => Lwt_unix.unlink(path) + }; + }, + files, + ); + Lwt_unix.rmdir(dir); +}; + type path = | Exists(string) | Missing(string); diff --git a/library/Versions.re b/library/Versions.re index 5205c80..0b11ad1 100644 --- a/library/Versions.re +++ b/library/Versions.re @@ -35,6 +35,8 @@ module Local = { let toDirectory = name => Filename.concat(Directories.nodeVersions, name); + let remove = version => Fs.rmdir(version.fullPath); + let getLatestInstalledNameByPrefix = prefix => { open Lwt; let%lwt versions =