215 lines
7.1 KiB
Nim
215 lines
7.1 KiB
Nim
import parseopt, strutils, os
|
|
|
|
import nimblepkg/[cli, options, config]
|
|
import nimblepkg/common as nimble_common
|
|
|
|
import common
|
|
|
|
type
|
|
CliParams* = ref object
|
|
commands*: seq[string]
|
|
onlyInstalled*: bool
|
|
getnimDir*: string
|
|
firstInstall*: bool
|
|
nimbleOptions*: Options
|
|
force*: bool
|
|
latest*: bool
|
|
skipClean*: bool
|
|
|
|
let doc = """
|
|
getnim: The Nim toolchain installer.
|
|
|
|
Usage:
|
|
getnim <version/path/channel>
|
|
|
|
Example:
|
|
getnim 0.16.0
|
|
Installs (if necessary) and selects version 0.16.0 of Nim.
|
|
getnim stable
|
|
Installs (if necessary) Nim from the stable channel (latest stable release)
|
|
and then selects it.
|
|
getnim devel [--latest]
|
|
Installs (if necessary) and selects the most recent nightly build of Nim.
|
|
The '--latest' flag selects and builds the latest commit in the devel branch
|
|
getnim ~/projects/nim
|
|
Selects the specified Nim installation.
|
|
getnim update stable
|
|
Updates the version installed on the stable release channel.
|
|
getnim update devel [--latest]
|
|
Updates to the most recent nightly build of Nim.
|
|
The '--latest' flag updates and builds the latest commit in the devel branch
|
|
getnim versions [--installed]
|
|
Lists the available versions of Nim that getnim has access to.
|
|
getnim remove 1.0.6
|
|
Removes (if installed) version 1.0.6 of Nim.
|
|
|
|
Channels:
|
|
stable
|
|
Describes the latest stable release of Nim.
|
|
devel
|
|
Describes the latest development (or nightly) release of Nim taken from
|
|
the devel branch.
|
|
|
|
Commands:
|
|
update <version/channel> Installs the latest release of the specified
|
|
version or channel.
|
|
show Displays the selected version and channel.
|
|
show path Prints only the path of the current Nim version.
|
|
update self Updates getnim itself.
|
|
versions [--installed] Lists available versions of Nim, passing
|
|
`--installed` only displays versions that
|
|
are installed locally (no network requests).
|
|
remove <version> Removes specified version (if installed).
|
|
|
|
Environment variables:
|
|
GITHUB_TOKEN GitHub API Token. Some actions use the GitHub API.
|
|
To avoid anonymous-access rate limits, supply a token
|
|
generated at https://github.com/settings/tokens/new
|
|
with the `public_repo` scope.
|
|
|
|
Options:
|
|
-h --help Show this output.
|
|
-y --yes Agree to every question.
|
|
--version Show version.
|
|
--verbose Show low (and higher) priority output.
|
|
--debug Show debug (and higher) priority output.
|
|
--noColor Don't colorise output.
|
|
|
|
--getnimDir:<dir> Specify the directory where toolchains should be
|
|
installed. Default: ~/.getnim.
|
|
--nimbleDir:<dir> Specify the Nimble directory where binaries will be
|
|
placed. Default: ~/.nimble.
|
|
--firstInstall Used by install script.
|
|
--skipClean Skip cleaning of failed builds.
|
|
"""
|
|
|
|
proc command*(params: CliParams): string =
|
|
return params.commands[0]
|
|
|
|
proc getDownloadDir*(params: CliParams): string =
|
|
return params.getnimDir / "downloads"
|
|
|
|
proc getInstallDir*(params: CliParams): string =
|
|
return params.getnimDir / "toolchains"
|
|
|
|
proc getChannelsDir*(params: CliParams): string =
|
|
return params.getnimDir / "channels"
|
|
|
|
proc getBinDir*(params: CliParams): string =
|
|
return params.nimbleOptions.getBinDir()
|
|
|
|
proc getCurrentFile*(params: CliParams): string =
|
|
## Returns the path to the file which specifies the currently selected
|
|
## installation. The contents of this file is a path to the selected Nim
|
|
## directory.
|
|
return params.getnimDir / "current"
|
|
|
|
proc getCurrentChannelFile*(params: CliParams): string =
|
|
return params.getnimDir / "current-channel"
|
|
|
|
proc getCpuArch*(): int =
|
|
## Get CPU arch on Windows - get env var PROCESSOR_ARCHITECTURE
|
|
var failMsg = ""
|
|
|
|
let
|
|
archEnv = getEnv("PROCESSOR_ARCHITECTURE")
|
|
arch6432Env = getEnv("PROCESSOR_ARCHITEW6432")
|
|
if arch6432Env.len != 0:
|
|
# https://blog.differentpla.net/blog/2013/03/10/processor-architew6432/
|
|
result = 64
|
|
elif "64" in archEnv:
|
|
# https://superuser.com/a/1441469
|
|
result = 64
|
|
elif "86" in archEnv:
|
|
result = 32
|
|
else:
|
|
failMsg = "PROCESSOR_ARCHITECTURE = " & archEnv &
|
|
", PROCESSOR_ARCHITEW6432 = " & arch6432Env
|
|
|
|
# Die if unsupported - better fail than guess
|
|
if result == 0:
|
|
raise newException(GetnimError,
|
|
"Could not detect CPU architecture: " & failMsg)
|
|
|
|
proc getMingwPath*(params: CliParams): string =
|
|
let arch = getCpuArch()
|
|
return params.getInstallDir() / "mingw" & $arch
|
|
|
|
proc getMingwBin*(params: CliParams): string =
|
|
return getMingwPath(params) / "bin"
|
|
|
|
proc getBinArchiveFormat*(): string =
|
|
when defined(windows):
|
|
return ".zip"
|
|
else:
|
|
return ".tar.xz"
|
|
|
|
proc getDownloadPath*(params: CliParams, downloadUrl: string): string =
|
|
let (_, name, ext) = downloadUrl.splitFile()
|
|
return params.getDownloadDir() / name & ext
|
|
|
|
proc writeHelp() =
|
|
echo(doc)
|
|
quit(QuitFailure)
|
|
|
|
proc writeVersion() =
|
|
echo("getnim v$1 ($2 $3) [$4/$5]" %
|
|
[getnimVersion, CompileDate, CompileTime, hostOS, hostCPU])
|
|
quit(QuitSuccess)
|
|
|
|
proc writeNimbleBinDir(params: CliParams) =
|
|
# Special option for scripts that install getnim.
|
|
echo(params.getBinDir())
|
|
quit(QuitSuccess)
|
|
|
|
proc newCliParams*(proxyExeMode: bool): CliParams =
|
|
new result
|
|
result.commands = @[]
|
|
result.getnimDir = getHomeDir() / ".getnim"
|
|
# Init nimble params.
|
|
try:
|
|
result.nimbleOptions = initOptions()
|
|
if not proxyExeMode:
|
|
result.nimbleOptions.config = parseConfig()
|
|
setNimbleDir(result.nimbleOptions)
|
|
except NimbleQuit:
|
|
discard
|
|
|
|
proc parseCliParams*(params: var CliParams, proxyExeMode = false) =
|
|
params = newCliParams(proxyExeMode)
|
|
|
|
for kind, key, val in getopt():
|
|
case kind
|
|
of cmdArgument:
|
|
params.commands.add(key)
|
|
of cmdLongOption, cmdShortOption:
|
|
let normalised = key.normalize()
|
|
# Don't want the proxyExe to return getnim's help/version.
|
|
case normalised
|
|
of "help", "h":
|
|
if not proxyExeMode: writeHelp()
|
|
of "version", "v":
|
|
if not proxyExeMode: writeVersion()
|
|
of "getnimblebin":
|
|
# Used by installer scripts to know where the getnim executable
|
|
# should be copied.
|
|
if not proxyExeMode: writeNimbleBinDir(params)
|
|
of "verbose": setVerbosity(LowPriority)
|
|
of "debug": setVerbosity(DebugPriority)
|
|
of "nocolor": setShowColor(false)
|
|
of "getnimdir": params.getnimDir = val.absolutePath()
|
|
of "nimbledir": params.nimbleOptions.nimbleDir = val.absolutePath()
|
|
of "firstinstall": params.firstInstall = true
|
|
of "y", "yes": params.nimbleOptions.forcePrompts = forcePromptYes
|
|
of "installed": params.onlyInstalled = true
|
|
of "force", "f": params.force = true
|
|
of "latest", "l": params.latest = true
|
|
of "skipclean": params.skipClean = true
|
|
else:
|
|
if not proxyExeMode:
|
|
raise newException(GetnimError, "Unknown flag: --" & key)
|
|
of cmdEnd: assert(false)
|
|
|
|
if params.commands.len == 0 and not proxyExeMode:
|
|
writeHelp()
|