From 2ce8517b96cfae99c4b70122d777a00a08c37553 Mon Sep 17 00:00:00 2001 From: Gal Schlezinger Date: Sun, 17 Mar 2019 14:32:59 +0200 Subject: [PATCH] Add support for interactive installation for use (#86) --- executable/Use.re | 32 ++++++++++++++++++++++++++++---- library/Config.re | 39 +++++++++++++++++++++++++++++++++++++-- library/dune | 2 +- package.json | 1 + 4 files changed, 67 insertions(+), 7 deletions(-) diff --git a/executable/Use.re b/executable/Use.re index 31f871276..c96af8b48 100644 --- a/executable/Use.re +++ b/executable/Use.re @@ -69,17 +69,41 @@ let main = (~version as providedVersion, ~quiet) => { switchVersion(~version, ~quiet); }; -let run = (~version, ~quiet) => +let rec askIfInstall = (~version, ~quiet, retry) => { + let%lwt _ = + Lwt_io.write( + Lwt_io.stderr, + "Do you want to install it? [y/n] " , + ); + switch%lwt (Lwt_io.read_line(Lwt_io.stdin)) { + | "Y" + | "y" => + let%lwt _ = Install.run(~version); + retry(~version, ~quiet); + | "N" + | "n" => Lwt_io.write_line(Lwt_io.stderr, "not installing!") + | _ => + let%lwt _ = + Lwt_io.write_line(Lwt_io.stderr, "Invalid response. Please try again:"); + askIfInstall(~version, ~quiet, retry); + }; +}; + +let rec run = (~version, ~quiet) => try%lwt (main(~version, ~quiet)) { - | Version_Not_Installed(version) => + | Version_Not_Installed(versionString) => log( ~quiet, "The following version is not installed: " - version + versionString , ); - exit(1); + if (Fnm.Config.FNM_INTERACTIVE_CLI.get()) { + askIfInstall(~version, ~quiet, run); + } else { + exit(1); + }; | Dotfiles.Conflicting_Dotfiles_Found(v1, v2) => log( ~quiet, diff --git a/library/Config.re b/library/Config.re index c0d362da1..140cc42f9 100644 --- a/library/Config.re +++ b/library/Config.re @@ -16,7 +16,8 @@ module EnvVar = }, ) => { include M; - let getOpt = () => Sys.getenv_opt(name) |> Opt.map(parse); + let optValue = Sys.getenv_opt(name) |> Opt.map(parse); + let getOpt = () => optValue; let get = () => Opt.(getOpt() or default); let docInfo = {name, doc, default: unparse(default)}; }; @@ -62,4 +63,38 @@ module FNM_MULTISHELL_PATH = let default = ""; }); -let getDocs = () => [FNM_DIR.docInfo, FNM_NODE_DIST_MIRROR.docInfo]; +let parseBooleanOrDie = (~name, str) => + switch (bool_of_string_opt(str)) { + | Some(boolean) => boolean + | None => + let errorString = + + str + " isn't a valid option for " + name + " which assumes a boolean value. Consider passing " + "true" + " or " + "false" + "." + ; + Printf.eprintf("%s\n", errorString); + exit(1); + }; + +module FNM_INTERACTIVE_CLI = + EnvVar({ + type t = bool; + let default = Unix.(isatty(stdin) && isatty(stdout) && isatty(stderr)); + let unparse = string_of_bool; + let name = "FNM_INTERACTIVE_CLI"; + let doc = "Should the CLI be interactive? true/false"; + let parse = parseBooleanOrDie(~name); + }); + +let getDocs = () => [ + FNM_DIR.docInfo, + FNM_NODE_DIST_MIRROR.docInfo, + FNM_MULTISHELL_PATH.docInfo, + FNM_INTERACTIVE_CLI.docInfo, +]; diff --git a/library/dune b/library/dune index 5a15e6475..ae011affa 100644 --- a/library/dune +++ b/library/dune @@ -7,6 +7,6 @@ (name Fnm) ; Other libraries list this name in their package.json 'require' field to use this library. (public_name fnm.lib) - (libraries str core lwt ssl lwt_ssl lambdasoup semver cohttp cohttp-lwt cohttp-lwt-unix ) + (libraries pastel.lib str core lwt ssl lwt_ssl lambdasoup semver cohttp cohttp-lwt cohttp-lwt-unix ) (preprocess ( pps lwt_ppx ppx_let )) ; From package.json preprocess field ) \ No newline at end of file diff --git a/package.json b/package.json index a11b72032..a0ffd779a 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "ppx_let" ], "require": [ + "pastel.lib", "str", "core", "lwt",