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",