Browse Source
Adds `fnm exec` to run a shell executable with the current node version (or a custom one provided): ``` fnm exec -- node -v # will print the current Node version in fnm fnm exec --using 12 -- node -v # will print the version of the latest node 12 installed fnm exec --using-file -- node -v # will print the version of the current directory's node version (based on `.nvmrc` or `.node-version`) ```remotes/origin/add-simple-redirecting-site
Gal Schlezinger
5 years ago
committed by
GitHub
9 changed files with 202 additions and 39 deletions
@ -0,0 +1,93 @@
@@ -0,0 +1,93 @@
|
||||
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( |
||||
<Pastel color=Pastel.Red> |
||||
<Pastel bold=true> "Error: " </Pastel> |
||||
"You passed both " |
||||
<Pastel color=Pastel.Cyan> "--using" </Pastel> |
||||
" and " |
||||
<Pastel color=Pastel.Cyan> "--using-file" </Pastel> |
||||
".\n" |
||||
"Please provide only one of them." |
||||
</Pastel>, |
||||
); |
||||
Lwt.return_error(1); |
||||
| System_Version_Not_Supported => |
||||
Console.error( |
||||
<Pastel color=Pastel.Red> |
||||
<Pastel bold=true> "Error: " </Pastel> |
||||
"System version is not supported in " |
||||
<Pastel color=Pastel.Yellow> "`fnm exec`" </Pastel> |
||||
</Pastel>, |
||||
); |
||||
Lwt.return_error(1); |
||||
| LocalVersionResolver.Version_Not_Installed(versionName) => |
||||
Console.error( |
||||
<Pastel color=Pastel.Red> |
||||
<Pastel bold=true> "Error: " </Pastel> |
||||
"Version " |
||||
<Pastel color=Pastel.Cyan> versionName </Pastel> |
||||
" is not installed." |
||||
</Pastel>, |
||||
); |
||||
Lwt.return_error(1); |
||||
| Dotfiles.Version_Not_Provided => |
||||
Console.error( |
||||
<Pastel color=Pastel.Red> |
||||
"No .nvmrc or .node-version file was found in the current directory. Please provide a version number." |
||||
</Pastel>, |
||||
); |
||||
Lwt.return_error(1); |
||||
}; |
||||
}; |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash |
||||
|
||||
set -e |
||||
|
||||
fnm install v6.10.0 |
||||
fnm install v8.10.0 |
||||
fnm install v10.10.0 |
||||
fnm use v8.10.0 |
||||
|
||||
fnm exec -- node -v | grep "v8.10.0" |
||||
fnm exec --using 6 -- node -v | grep "v6.10.0" |
||||
fnm exec --using 10 -- node -v | grep "v10.10.0" |
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
exception Version_Not_Installed(string); |
||||
|
||||
/** Parse a local version, including lts and aliases */ |
||||
let getVersion = version => { |
||||
let%lwt parsed = Versions.parse(version); |
||||
let%lwt resultWithLts = |
||||
switch (parsed) { |
||||
| Ok(x) => Lwt.return_ok(x) |
||||
| Error("latest-*") => |
||||
switch%lwt (VersionListingLts.getLatest()) { |
||||
| Error(_) => Lwt.return_error(Version_Not_Installed(version)) |
||||
| Ok({VersionListingLts.lts, _}) => |
||||
Versions.Alias("latest-" ++ lts) |> Lwt.return_ok |
||||
} |
||||
| _ => Version_Not_Installed(version) |> Lwt.return_error |
||||
}; |
||||
resultWithLts |> Result.fold(Lwt.fail, Lwt.return); |
||||
}; |
||||
|
||||
/** |
||||
* Get matches for all versions that match a semver partial |
||||
*/ |
||||
let getMatchingLocalVersions = version => { |
||||
open Versions.Local; |
||||
|
||||
let%lwt installedVersions = Versions.getInstalledVersions(); |
||||
let formattedVersionName = Versions.format(version); |
||||
|
||||
let matchingVersions = |
||||
installedVersions |
||||
|> List.filter(v => |
||||
Versions.isVersionFitsPrefix(formattedVersionName, v.name) |
||||
|| v.name == formattedVersionName |
||||
) |
||||
|> List.sort((a, b) => - compare(a.name, b.name)); |
||||
|
||||
Lwt.return(matchingVersions); |
||||
}; |
Loading…
Reference in new issue