getnim/src/getnimpkg/cliparams.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()