From 6b82b9ce23ece7c7694daa39ec35e4d88f7abef7 Mon Sep 17 00:00:00 2001 From: Tomer Ohana Date: Tue, 30 Apr 2019 10:44:00 +0300 Subject: [PATCH] Add support for log level (closes #33) (#93) --- README.md | 2 +- executable/Alias.re | 4 +-- executable/Env.re | 12 ++++++-- executable/FnmApp.re | 28 ++++++++++++++++++- executable/Install.re | 14 +++++----- executable/Use.re | 2 +- feature_tests/log-level-error/run.sh | 11 ++++++++ feature_tests/log-level-quiet/run.sh | 13 +++++++++ library/Config.re | 11 ++++++++ library/LogLevel.re | 19 +++++++++++++ library/Logger.re | 17 +++++++++++ library/dune | 2 +- package.json | 3 +- .../Smoke_test.4d362c3c.0.snapshot | 1 + 14 files changed, 123 insertions(+), 16 deletions(-) create mode 100644 feature_tests/log-level-error/run.sh create mode 100644 feature_tests/log-level-quiet/run.sh create mode 100644 library/LogLevel.re create mode 100644 library/Logger.re diff --git a/README.md b/README.md index 832b352..bfc7a45 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ Lists the installed Node versions. Lists the Node versions available to download remotely. -### `fnm env [--multi] [--shell=fish|bash|zsh] [--node-dist-mirror=URI] [--use-on-cd] [--base-dir=DIR]` +### `fnm env [--multi] [--shell=fish|bash|zsh] [--node-dist-mirror=URI] [--use-on-cd] [--base-dir=DIR] [--log-level=quiet|error|all]` Prints the required shell commands in order to configure your shell, Bash compliant by default. diff --git a/executable/Alias.re b/executable/Alias.re index ac9e2ad..4e6c9b3 100644 --- a/executable/Alias.re +++ b/executable/Alias.re @@ -10,7 +10,7 @@ let run = (~name, ~version) => { let%lwt versionInstalled = Lwt_unix.file_exists(versionPath); if (!versionInstalled) { - Console.error( + Logger.error( "Can't find a version installed in " versionPath @@ -19,7 +19,7 @@ let run = (~name, ~version) => { exit(1); }; - Console.log( + Logger.log( "Aliasing " name diff --git a/executable/Env.re b/executable/Env.re index 5932aa0..fee3a0a 100644 --- a/executable/Env.re +++ b/executable/Env.re @@ -70,7 +70,8 @@ let rec printUseOnCd = (~shell) => |} }; -let run = (~forceShell, ~multishell, ~nodeDistMirror, ~fnmDir, ~useOnCd) => { +let run = + (~forceShell, ~multishell, ~nodeDistMirror, ~fnmDir, ~useOnCd, ~logLevel) => { open Lwt; open System.Shell; @@ -103,11 +104,18 @@ let run = (~forceShell, ~multishell, ~nodeDistMirror, ~fnmDir, ~useOnCd) => { nodeDistMirror, ) |> Console.log; + Printf.sprintf( + "export %s=%s", + Config.FNM_LOGLEVEL.name, + Fnm.LogLevel.toString(logLevel), + ) + |> Console.log; | Fish => Printf.sprintf("set -gx PATH %s/bin $PATH;", path) |> Console.log; Printf.sprintf("set -gx %s %s;", Config.FNM_MULTISHELL_PATH.name, path) |> Console.log; - Printf.sprintf("set -gx %s %s;", Config.FNM_DIR.name, fnmDir) |> Console.log; + Printf.sprintf("set -gx %s %s;", Config.FNM_DIR.name, fnmDir) + |> Console.log; Printf.sprintf( "set -gx %s %s", Config.FNM_NODE_DIST_MIRROR.name, diff --git a/executable/FnmApp.re b/executable/FnmApp.re index eb33f0b..dca37b0 100644 --- a/executable/FnmApp.re +++ b/executable/FnmApp.re @@ -7,7 +7,15 @@ module Commands = { let listLocal = () => Lwt_main.run(ListLocal.run()); let install = version => Lwt_main.run(Install.run(~version)); let env = - (isFishShell, isMultishell, nodeDistMirror, fnmDir, shell, useOnCd) => + ( + isFishShell, + isMultishell, + nodeDistMirror, + fnmDir, + shell, + useOnCd, + logLevel, + ) => Lwt_main.run( Env.run( ~forceShell=Fnm.System.Shell.(isFishShell ? Some(Fish) : shell), @@ -15,6 +23,7 @@ module Commands = { ~nodeDistMirror, ~fnmDir, ~useOnCd, + ~logLevel, ), ); }; @@ -187,6 +196,22 @@ let env = { Arg.(value & flag & info(["use-on-cd"], ~doc)); }; + let logLevel = { + let doc = "The log level of fnm commands, can be 'quiet', 'error' or 'all'"; + Arg.( + value + & opt( + enum([ + ("quiet", Fnm.LogLevel.Quiet), + ("error", Fnm.LogLevel.Error), + ("all", Fnm.LogLevel.All), + ]), + Fnm.Config.FNM_LOGLEVEL.get(), + ) + & info(["log-level"], ~doc) + ); + }; + ( Term.( const(Commands.env) @@ -196,6 +221,7 @@ let env = { $ fnmDir $ shell $ useOnCd + $ logLevel ), Term.info("env", ~version, ~doc, ~exits=Term.default_exits, ~man, ~sdocs), ); diff --git a/executable/Install.re b/executable/Install.re index d4f776f..2c03887 100644 --- a/executable/Install.re +++ b/executable/Install.re @@ -3,7 +3,7 @@ open Fnm; let mkDownloadsDir = () => { let exists = Lwt_unix.file_exists(Directories.downloads); if%lwt (exists |> Lwt.map(x => !x)) { - Console.log( + Logger.log( "Creating " Directories.downloads @@ -29,7 +29,7 @@ let main = (~version as versionName) => { let versionName = Versions.format(versionName); let%lwt _ = Versions.throwIfInstalled(versionName); - Console.log( + Logger.log( "Looking for node " versionName @@ -53,7 +53,7 @@ let main = (~version as versionName) => { versionName ++ Versions.Remote.downloadFileSuffix, ); - Console.log( + Logger.log( "Downloading " filepath @@ -67,7 +67,7 @@ let main = (~version as versionName) => { let extractionDestination = Filename.concat(Directories.nodeVersions, versionName); - Console.log( + Logger.log( "Extracting " tarDestination @@ -85,7 +85,7 @@ let main = (~version as versionName) => { let run = (~version) => try%lwt (main(~version)) { | Versions.No_Download_For_System(os, arch) => - Console.log( + Logger.log( "Version exists, but can't find a file for your system:\n" " OS: " @@ -97,7 +97,7 @@ let run = (~version) => ); exit(1); | Versions.Already_installed(version) => - Console.log( + Logger.log( "Version " version @@ -106,7 +106,7 @@ let run = (~version) => ) |> Lwt.return | Versions.Version_not_found(version) => - Console.log( + Logger.log( "Version " version diff --git a/executable/Use.re b/executable/Use.re index c96af8b..cd34341 100644 --- a/executable/Use.re +++ b/executable/Use.re @@ -6,7 +6,7 @@ exception Version_Not_Installed(string); let log = (~quiet, arg) => if (!quiet) { - Console.log(arg); + Logger.log(arg); }; let switchVersion = (~version, ~quiet) => { diff --git a/feature_tests/log-level-error/run.sh b/feature_tests/log-level-error/run.sh new file mode 100644 index 0000000..cdcd053 --- /dev/null +++ b/feature_tests/log-level-error/run.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +eval $(fnm env --log-level=error) +ALIAS="$(fnm install 8.11.3 && (fnm alias 123 abc 2>&1 || true))" + +if [ "$ALIAS" == "" ]; then + echo "Expected the output to contain errors" + exit 1 +fi diff --git a/feature_tests/log-level-quiet/run.sh b/feature_tests/log-level-quiet/run.sh new file mode 100644 index 0000000..4a541b2 --- /dev/null +++ b/feature_tests/log-level-quiet/run.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -e + +eval $(fnm env --log-level=quiet) +INSTALL="$(fnm install v8.11.3 && fnm use v8.11.3 && fnm alias v8.11.3 something)" + +OUTPUT="$INSTALL" +if [ "$OUTPUT" != "" ]; then + echo "Expected the output to be empty, instead got:" + echo $OUTPUT + exit 1 +fi diff --git a/library/Config.re b/library/Config.re index 140cc42..3f53b6d 100644 --- a/library/Config.re +++ b/library/Config.re @@ -63,6 +63,16 @@ module FNM_MULTISHELL_PATH = let default = ""; }); +module FNM_LOGLEVEL = + EnvVar({ + type t = LogLevel.t; + let parse = LogLevel.fromString; + let unparse = LogLevel.toString; + let name = "FNM_LOGLEVEL"; + let doc = "The log level of fnm commands"; + let default = LogLevel.All; + }); + let parseBooleanOrDie = (~name, str) => switch (bool_of_string_opt(str)) { | Some(boolean) => boolean @@ -97,4 +107,5 @@ let getDocs = () => [ FNM_NODE_DIST_MIRROR.docInfo, FNM_MULTISHELL_PATH.docInfo, FNM_INTERACTIVE_CLI.docInfo, + FNM_LOGLEVEL.docInfo, ]; diff --git a/library/LogLevel.re b/library/LogLevel.re new file mode 100644 index 0000000..65ef586 --- /dev/null +++ b/library/LogLevel.re @@ -0,0 +1,19 @@ +type t = + | Quiet + | Error + | All; + +let toString = logLevel => + switch (logLevel) { + | Quiet => "quiet" + | Error => "error" + | All => "all" + }; + +let fromString = logLevelString => + switch (logLevelString) { + | "quiet" => Quiet + | "error" => Error + | "all" => All + | _ => failwith("Unsupported level: " ++ logLevelString) + }; diff --git a/library/Logger.re b/library/Logger.re new file mode 100644 index 0000000..2e623a9 --- /dev/null +++ b/library/Logger.re @@ -0,0 +1,17 @@ +let configuredLogLevel = Config.FNM_LOGLEVEL.get(); + +let log = message => { + switch (configuredLogLevel) { + | LogLevel.All => Console.log(message) + | LogLevel.Error + | LogLevel.Quiet => () + }; +}; + +let error = message => { + switch (configuredLogLevel) { + | LogLevel.All + | LogLevel.Error => Console.error(message) + | LogLevel.Quiet => () + }; +}; diff --git a/library/dune b/library/dune index ae011af..8fac0d0 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 pastel.lib 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 console.lib ) (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 699246a..fb21bdd 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,8 @@ "semver", "cohttp", "cohttp-lwt", - "cohttp-lwt-unix" + "cohttp-lwt-unix", + "console.lib" ], "name": "fnm.lib", "namespace": "Fnm" diff --git a/test/__snapshots__/Smoke_test.4d362c3c.0.snapshot b/test/__snapshots__/Smoke_test.4d362c3c.0.snapshot index 879d6a8..91ab579 100644 --- a/test/__snapshots__/Smoke_test.4d362c3c.0.snapshot +++ b/test/__snapshots__/Smoke_test.4d362c3c.0.snapshot @@ -3,4 +3,5 @@ export PATH=/current/bin:$PATH export FNM_MULTISHELL_PATH=/current export FNM_DIR=/ export FNM_NODE_DIST_MIRROR=https://nodejs.org/dist +export FNM_LOGLEVEL=all