open Fnm; exception System_Version_Not_Supported; exception Ambiguous_Arguments; let startsWith = (~prefix, str) => Base.String.prefix(str, String.length(prefix)) != prefix; let unsafeRun = (~cmd, ~version as maybeVersion, ~useFileVersion) => { let%lwt version = switch (maybeVersion, useFileVersion) { | (None, false) => Lwt.return_none | (Some(_), true) => Lwt.fail(Ambiguous_Arguments) | (None, true) => Fnm.Dotfiles.getVersion() |> Lwt.map(x => Some(x)) | (Some(version), false) => Lwt.return_some(version) }; let%lwt currentVersion = switch (version) { | None => Lwt.return(Directories.currentVersion) | Some(version) => let%lwt matchingVersion = LocalVersionResolver.getVersion(version); let matchingVersionPath = switch (matchingVersion) { | Alias(path) => Versions.Aliases.toDirectory(path) | Local(path) => Versions.Local.toDirectory(path) | System => raise(System_Version_Not_Supported) }; Lwt.return(matchingVersionPath); }; let fnmPath = Filename.concat(currentVersion, "bin"); let path = Opt.(Sys.getenv_opt("PATH") or ""); let pathEnv = Printf.sprintf("PATH=%s:%s", fnmPath, path); let cmd = cmd |> Array.copy |> Array.append([|"env", pathEnv|]); let%lwt exitCode = Lwt_process.exec( ~stdin=`Keep, ~stdout=`Keep, ~stderr=`Keep, ~env=Unix.environment(), ("", cmd), ); switch (exitCode) { | Unix.WEXITED(0) => Lwt.return_ok() | Unix.WEXITED(x) | Unix.WSTOPPED(x) | Unix.WSIGNALED(x) => Lwt.return_error(x) }; }; let run = (~cmd, ~version, ~useFileVersion) => { try%lwt(unsafeRun(~cmd, ~version, ~useFileVersion)) { | Ambiguous_Arguments => Console.error( "Error: " "You passed both " "--using" " and " "--using-file" ".\n" "Please provide only one of them." , ); Lwt.return_error(1); | System_Version_Not_Supported => Console.error( "Error: " "System version is not supported in " "`fnm exec`" , ); Lwt.return_error(1); | LocalVersionResolver.Version_Not_Installed(versionName) => Console.error( "Error: " "Version " versionName " is not installed." , ); Lwt.return_error(1); | Dotfiles.Version_Not_Provided => Console.error( "No .nvmrc or .node-version file was found in the current directory. Please provide a version number." , ); Lwt.return_error(1); }; };