Install and update nightlies ()

* Add nightlies to devel

* Merge issues

* Fix test

* Handle case where latest nightly not found

* Feedback
This commit is contained in:
genotrance 2020-03-01 08:00:13 -06:00 committed by GitHub
parent 6ccefca63c
commit a7b9d24849
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 105 additions and 24 deletions

View file

@ -15,7 +15,7 @@ when defined(windows):
proc installVersion(version: Version, params: CliParams) =
let
extractDir = params.getInstallationDir(version)
updated = gitUpdate(version, extractDir)
updated = gitUpdate(version, extractDir, params)
if not updated:
# Install the requested version.
@ -32,7 +32,7 @@ proc installVersion(version: Version, params: CliParams) =
# directory in order to let `koch` know that it should download a "devel"
# Nimble.
if version.isSpecial:
gitInit(version, extractDir)
gitInit(version, extractDir, params)
# Build the compiler
build(extractDir, version, params)

View file

@ -22,7 +22,7 @@ proc buildCompiler(version: Version, params: CliParams) =
## Assumes that CWD contains the compiler (``build`` should have changed it).
let binDir = getCurrentDir() / "bin"
if fileExists(binDir / "nim".addFileExt(ExeExt)):
if not version.isDevel():
if not version.isDevel() or not params.latest:
display("Compiler:", "Already built", priority = HighPriority)
return
else:
@ -55,14 +55,14 @@ proc buildCompiler(version: Version, params: CliParams) =
if not fileExists(binDir / "nim".addFileExt(ExeExt)):
raise newException(ChooseNimError, "Nim binary is missing. Build failed.")
proc buildTools(version: Version) =
proc buildTools(version: Version, params: CliParams) =
## Assumes that CWD contains the compiler.
let binDir = getCurrentDir() / "bin"
# TODO: I guess we should check for the other tools too?
if fileExists(binDir / "nimble".addFileExt(ExeExt)) and
not version.isDevel():
display("Tools:", "Already built", priority = HighPriority)
return
if fileExists(binDir / "nimble".addFileExt(ExeExt)):
if not version.isDevel() or not params.latest:
display("Tools:", "Already built", priority = HighPriority)
return
let msg = "tools (nimble, nimgrep, nimpretty, nimsuggest, testament)"
display("Building", msg, priority = HighPriority)
@ -114,7 +114,7 @@ proc build*(extractDir: string, version: Version, params: CliParams) =
var success = false
try:
buildCompiler(version, params)
buildTools(version)
buildTools(version, params)
when defined(posix):
setPermissions() # workaround for #147
success = true

View file

@ -16,7 +16,7 @@ type
analytics*: AsyncAnalytics
pendingReports*: int ## Count of pending telemetry reports.
force*: bool
latest*: bool
let doc = """
choosenim: The Nim toolchain installer.
@ -32,13 +32,16 @@ Example:
choosenim stable
Installs (if necessary) Nim from the stable channel (latest stable release)
and then selects it.
choosenim #head
Installs (if necessary) and selects the latest current commit of Nim.
Warning: Your shell may need quotes around `#head`: choosenim "#head".
choosenim 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
choosenim ~/projects/nim
Selects the specified Nim installation.
choosenim update stable
Updates the version installed on the stable release channel.
choosenim 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
choosenim versions [--installed]
Lists the available versions of Nim that choosenim has access to.
@ -195,6 +198,7 @@ proc parseCliParams*(params: var CliParams, proxyExeMode = false) =
of "y", "yes": params.nimbleOptions.forcePrompts = forcePromptYes
of "installed": params.onlyInstalled = true
of "force", "f": params.force = true
of "latest", "l": params.latest = true
else:
if not proxyExeMode:
raise newException(ChooseNimError, "Unknown flag: --" & key)

View file

@ -11,6 +11,7 @@ import cliparams, common, telemetry, utils
const
githubTagReleasesUrl = "https://api.github.com/repos/nim-lang/Nim/tags"
githubNightliesReleasesUrl = "https://api.github.com/repos/nim-lang/nightlies/releases"
githubUrl = "https://github.com/nim-lang/Nim"
websiteUrl = "http://nim-lang.org/download/nim-$1.tar.xz"
csourcesUrl = "https://github.com/nim-lang/csources"
@ -206,21 +207,31 @@ proc needsDownload(params: CliParams, downloadUrl: string,
priority=HighPriority)
return false
proc retrieveUrl*(url: string): string
proc downloadImpl(version: Version, params: CliParams): string =
let arch = getGccArch(params)
if version.isSpecial():
let
commit = getLatestCommit(githubUrl, "devel")
archive = if commit.len != 0: commit else: "devel"
var reference, url = ""
if $version in ["#devel", "#head"] and not params.latest:
# Install nightlies by default for devel channel
let rawContents = retrieveUrl(githubNightliesReleasesUrl)
let parsedContents = parseJson(rawContents)
url = getNightliesUrl(parsedContents, arch)
reference = "devel"
if url.len == 0:
let
commit = getLatestCommit(githubUrl, "devel")
archive = if commit.len != 0: commit else: "devel"
reference =
case normalize($version)
of "#head":
archive
else:
($version)[1 .. ^1]
url = $(parseUri(githubUrl) / (dlArchive % reference))
display("Downloading", "Nim $1 from $2" % [reference, "GitHub"],
priority = HighPriority)
let url = $(parseUri(githubUrl) / (dlArchive % reference))
var outputPath: string
if not needsDownload(params, url, outputPath): return outputPath
@ -353,8 +364,8 @@ proc getOfficialReleases*(params: CliParams): seq[Version] =
template isDevel*(version: Version): bool =
$version in ["#head", "#devel"]
proc gitUpdate*(version: Version, extractDir: string): bool =
if version.isDevel():
proc gitUpdate*(version: Version, extractDir: string, params: CliParams): bool =
if version.isDevel() and params.latest:
let git = findExe("git")
if git.len != 0 and fileExists(extractDir / ".git" / "config"):
result = true
@ -371,7 +382,7 @@ proc gitUpdate*(version: Version, extractDir: string): bool =
display("Warning:", "git" & cmd & " failed: " & outp, Warning, priority = HighPriority)
return false
proc gitInit*(version: Version, extractDir: string) =
proc gitInit*(version: Version, extractDir: string, params: CliParams) =
createDir(extractDir / ".git")
if version.isDevel():
let git = findExe("git")
@ -391,7 +402,7 @@ proc gitInit*(version: Version, extractDir: string) =
break
if init:
discard gitUpdate(version, extractDir)
discard gitUpdate(version, extractDir, params)
when isMainModule:

View file

@ -1,4 +1,4 @@
import httpclient, os, strutils, osproc, uri
import httpclient, json, os, strutils, osproc, uri
import nimblepkg/[cli, version]
import nimarchive
@ -116,3 +116,25 @@ proc getLatestCommit*(repo, branch: string): string =
else:
display("Warning", outp & "\ngit ls-remote failed", Warning, HighPriority)
proc getNightliesUrl*(parsedContents: JsonNode, arch: int): string =
let os =
when defined(windows): "windows"
elif defined(linux): "linux"
elif defined(macosx): "osx"
for jn in parsedContents.getElems():
if jn["name"].getStr().contains("devel"):
for asset in jn["assets"].getElems():
let aname = asset["name"].getStr()
if os in aname:
when not defined(macosx):
if "x" & $arch in aname:
result = asset["browser_download_url"].getStr()
else:
result = asset["browser_download_url"].getStr()
if result.len != 0:
break
if result.len != 0:
break
if result.len == 0:
display("Warning", "Recent nightly release not found, installing latest devel commit.",
Warning, priority = HighPriority)

View file

@ -175,7 +175,7 @@ when defined(linux):
test "can update devel with git":
beginTest()
block:
let (output, exitCode) = exec("devel", liveOutput=true)
let (output, exitCode) = exec(@["devel", "--latest"], liveOutput=true)
check exitCode == QuitSuccess
check inLines(output.processOutput, "extracting")
@ -184,7 +184,7 @@ test "can update devel with git":
check inLines(output.processOutput, "building")
block:
let (output, exitCode) = exec(@["update", "devel"], liveOutput=true)
let (output, exitCode) = exec(@["update", "devel", "--latest"], liveOutput=true)
check exitCode == QuitSuccess
check not inLines(output.processOutput, "extracting")
@ -193,6 +193,50 @@ test "can update devel with git":
check inLines(output.processOutput, "latest changes")
check inLines(output.processOutput, "building")
test "can install and update nightlies":
beginTest()
block:
# Install nightly
let (output, exitCode) = exec("devel", liveOutput=true)
# Travis runs into Github API limit
if not inLines(output.processOutput, "403"):
check exitCode == QuitSuccess
check inLines(output.processOutput, "devel from")
check inLines(output.processOutput, "setting")
when not defined(macosx):
if not inLines(output.processOutput, "recent nightly"):
check inLines(output.processOutput, "already built")
check inLines(output.processOutput, "to Nim #devel")
block:
# Update nightly
let (output, exitCode) = exec(@["update", "devel"], liveOutput=true)
# Travis runs into Github API limit
if not inLines(output.processOutput, "403"):
check exitCode == QuitSuccess
check inLines(output.processOutput, "updating")
check inLines(output.processOutput, "devel from")
check inLines(output.processOutput, "setting")
when not defined(macosx):
if not inLines(output.processOutput, "recent nightly"):
check inLines(output.processOutput, "already built")
block:
# Update to devel latest
let (output, exitCode) = exec(@["update", "devel", "--latest"], liveOutput=true)
check exitCode == QuitSuccess
when not defined(macosx):
check not inLines(output.processOutput, "extracting")
check not inLines(output.processOutput, "setting")
check inLines(output.processOutput, "updating")
check inLines(output.processOutput, "latest changes")
check inLines(output.processOutput, "building")
test "can update self":
# updateSelf() doesn't use options --choosenimDir and --nimbleDir. It's used getAppDir().
# This will rewrite $project/bin dir, it's dangerous.