Install #head if version tag does not compile. Fixes #139.
This commit is contained in:
parent
4ffcdf141e
commit
5450dc8213
3 changed files with 73 additions and 42 deletions
|
|
@ -467,8 +467,13 @@ proc buildFromDir(pkgInfo: PackageInfo, paths: seq[string], forRelease: bool) =
|
||||||
let outputOpt = "-o:\"" & pkgInfo.getOutputDir(bin) & "\""
|
let outputOpt = "-o:\"" & pkgInfo.getOutputDir(bin) & "\""
|
||||||
echo("Building ", pkginfo.name, "/", bin, " using ", pkgInfo.backend,
|
echo("Building ", pkginfo.name, "/", bin, " using ", pkgInfo.backend,
|
||||||
" backend...")
|
" backend...")
|
||||||
doCmd(getNimBin() & " $# $# --noBabelPath $# $# \"$#\"" %
|
try:
|
||||||
[pkgInfo.backend, releaseOpt, args, outputOpt, realDir / bin.changeFileExt("nim")])
|
doCmd(getNimBin() & " $# $# --noBabelPath $# $# \"$#\"" %
|
||||||
|
[pkgInfo.backend, releaseOpt, args, outputOpt,
|
||||||
|
realDir / bin.changeFileExt("nim")])
|
||||||
|
except NimbleError:
|
||||||
|
raise newException(BuildFailed, "Build failed for package: " &
|
||||||
|
pkgInfo.name)
|
||||||
|
|
||||||
proc saveNimbleMeta(pkgDestDir, url: string, filesInstalled: HashSet[string]) =
|
proc saveNimbleMeta(pkgDestDir, url: string, filesInstalled: HashSet[string]) =
|
||||||
var nimblemeta = %{"url": %url}
|
var nimblemeta = %{"url": %url}
|
||||||
|
|
@ -608,28 +613,42 @@ proc getNimbleTempDir(): string =
|
||||||
result.add($getpid())
|
result.add($getpid())
|
||||||
|
|
||||||
proc downloadPkg(url: string, verRange: VersionRange,
|
proc downloadPkg(url: string, verRange: VersionRange,
|
||||||
downMethod: DownloadMethod): string =
|
downMethod: DownloadMethod): (string, VersionRange) =
|
||||||
|
## Downloads the repository as specified by ``url`` and ``verRange`` using
|
||||||
|
## the download method specified.
|
||||||
|
##
|
||||||
|
## Returns the directory where it was downloaded and the concrete version
|
||||||
|
## which was downloaded.
|
||||||
let downloadDir = (getNimbleTempDir() / getDownloadDirName(url, verRange))
|
let downloadDir = (getNimbleTempDir() / getDownloadDirName(url, verRange))
|
||||||
createDir(downloadDir)
|
createDir(downloadDir)
|
||||||
echo("Downloading ", url, " into ", downloadDir, " using ", downMethod, "...")
|
echo("Downloading ", url, " into ", downloadDir, " using ", downMethod, "...")
|
||||||
doDownload(url, downloadDir, verRange, downMethod)
|
result = (downloadDir, doDownload(url, downloadDir, verRange, downMethod))
|
||||||
result = downloadDir
|
|
||||||
|
|
||||||
proc downloadPkg(pkg: Package, verRange: VersionRange): string =
|
proc getDownloadInfo*(pv: PkgTuple, options: Options,
|
||||||
let downloadDir = (getNimbleTempDir() / getDownloadDirName(pkg, verRange))
|
doPrompt: bool): (DownloadMethod, string) =
|
||||||
let downMethod = pkg.downloadMethod.getDownloadMethod()
|
if pv.name.isURL:
|
||||||
createDir(downloadDir)
|
return (checkUrlType(pv.name), pv.name)
|
||||||
echo("Downloading ", pkg.name, " into ", downloadDir, " using ", downMethod,
|
else:
|
||||||
"...")
|
var pkg: Package
|
||||||
doDownload(pkg.url, downloadDir, verRange, downMethod)
|
if getPackage(pv.name, options.getNimbleDir() / "packages.json", pkg):
|
||||||
result = downloadDir
|
return (pkg.downloadMethod.getDownloadMethod(), pkg.url)
|
||||||
|
else:
|
||||||
|
# If package is not found give the user a chance to update
|
||||||
|
# package.json
|
||||||
|
if doPrompt and
|
||||||
|
options.prompt(pv.name & " not found in local packages.json, " &
|
||||||
|
"check internet for updated packages?"):
|
||||||
|
update(options)
|
||||||
|
return getDownloadInfo(pv, options, doPrompt)
|
||||||
|
else:
|
||||||
|
raise newException(NimbleError, "Package not found.")
|
||||||
|
|
||||||
proc install(packages: seq[PkgTuple],
|
proc install(packages: seq[PkgTuple],
|
||||||
options: Options,
|
options: Options,
|
||||||
doPrompt = true): tuple[paths: seq[string], pkg: PackageInfo] =
|
doPrompt = true): tuple[paths: seq[string], pkg: PackageInfo] =
|
||||||
if packages == @[]:
|
if packages == @[]:
|
||||||
result = installFromDir(getCurrentDir(), false, options, "")
|
result = installFromDir(getCurrentDir(), false, options, "")
|
||||||
else:
|
else:
|
||||||
# If packages.json is not present ask the user if they want to download it.
|
# If packages.json is not present ask the user if they want to download it.
|
||||||
if not existsFile(options.getNimbleDir / "packages.json"):
|
if not existsFile(options.getNimbleDir / "packages.json"):
|
||||||
if doPrompt and
|
if doPrompt and
|
||||||
|
|
@ -641,25 +660,28 @@ proc install(packages: seq[PkgTuple],
|
||||||
|
|
||||||
# Install each package.
|
# Install each package.
|
||||||
for pv in packages:
|
for pv in packages:
|
||||||
if pv.name.isURL:
|
let (meth, url) = getDownloadInfo(pv, options, doPrompt)
|
||||||
let meth = checkUrlType(pv.name)
|
let (downloadDir, downloadVersion) = downloadPkg(url, pv.ver, meth)
|
||||||
let downloadDir = downloadPkg(pv.name, pv.ver, meth)
|
try:
|
||||||
result = installFromDir(downloadDir, false, options, pv.name)
|
result = installFromDir(downloadDir, false, options, url)
|
||||||
else:
|
except BuildFailed:
|
||||||
var pkg: Package
|
# The package failed to build.
|
||||||
if getPackage(pv.name, options.getNimbleDir() / "packages.json", pkg):
|
# Check if we tried building a tagged version of the package.
|
||||||
let downloadDir = downloadPkg(pkg, pv.ver)
|
if pv.ver.kind != verSpecial:
|
||||||
result = installFromDir(downloadDir, false, options, pkg.url)
|
# If we tried building a tagged version of the package then
|
||||||
else:
|
# ask the user whether they want to try building #head.
|
||||||
# If package is not found give the user a chance to update
|
let promptResult = doPrompt and
|
||||||
# package.json
|
options.prompt(("Build failed for '$1@$2', would you" &
|
||||||
if doPrompt and
|
" like to try installing '$1@#head' (latest unstable)?") %
|
||||||
options.prompt(pv.name & " not found in local packages.json, " &
|
[pv.name, $downloadVersion])
|
||||||
"check internet for updated packages?"):
|
if promptResult:
|
||||||
update(options)
|
let verRange = parseVersionRange("#" & getHeadName(meth))
|
||||||
result = install(@[pv], options, false)
|
result = install(@[(pv.name, verRange)], options, doPrompt)
|
||||||
else:
|
else:
|
||||||
raise newException(NimbleError, "Package not found.")
|
raise newException(BuildFailed,
|
||||||
|
"Aborting installation due to build failure")
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
proc build(options: Options) =
|
proc build(options: Options) =
|
||||||
var pkgInfo = getPkgInfo(getCurrentDir())
|
var pkgInfo = getPkgInfo(getCurrentDir())
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import parseutils, os, osproc, strutils, tables, pegs
|
||||||
|
|
||||||
import packageinfo, version, tools, nimbletypes
|
import packageinfo, version, tools, nimbletypes
|
||||||
|
|
||||||
type
|
type
|
||||||
DownloadMethod* {.pure.} = enum
|
DownloadMethod* {.pure.} = enum
|
||||||
git = "git", hg = "hg"
|
git = "git", hg = "hg"
|
||||||
|
|
||||||
|
|
@ -106,11 +106,11 @@ proc getTagsListRemote*(url: string, meth: DownloadMethod): seq[string] =
|
||||||
let start = i.find("refs/tags/")+"refs/tags/".len
|
let start = i.find("refs/tags/")+"refs/tags/".len
|
||||||
let tag = i[start .. i.len-1]
|
let tag = i[start .. i.len-1]
|
||||||
if not tag.endswith("^{}"): result.add(tag)
|
if not tag.endswith("^{}"): result.add(tag)
|
||||||
|
|
||||||
of DownloadMethod.hg:
|
of DownloadMethod.hg:
|
||||||
# http://stackoverflow.com/questions/2039150/show-tags-for-remote-hg-repository
|
# http://stackoverflow.com/questions/2039150/show-tags-for-remote-hg-repository
|
||||||
raise newException(ValueError, "Hg doesn't support remote tag querying.")
|
raise newException(ValueError, "Hg doesn't support remote tag querying.")
|
||||||
|
|
||||||
proc getVersionList*(tags: seq[string]): Table[Version, string] =
|
proc getVersionList*(tags: seq[string]): Table[Version, string] =
|
||||||
# Returns: TTable of version -> git tag name
|
# Returns: TTable of version -> git tag name
|
||||||
result = initTable[Version, string]()
|
result = initTable[Version, string]()
|
||||||
|
|
@ -147,18 +147,23 @@ proc isURL*(name: string): bool =
|
||||||
name.startsWith(peg" @'://' ")
|
name.startsWith(peg" @'://' ")
|
||||||
|
|
||||||
proc doDownload*(url: string, downloadDir: string, verRange: VersionRange,
|
proc doDownload*(url: string, downloadDir: string, verRange: VersionRange,
|
||||||
downMethod: DownloadMethod) =
|
downMethod: DownloadMethod): VersionRange =
|
||||||
|
## Downloads the repository specified by ``url`` using the specified download
|
||||||
|
## method.
|
||||||
|
##
|
||||||
|
## Returns the version of the repository which has been downloaded.
|
||||||
template getLatestByTag(meth: stmt): stmt {.dirty, immediate.} =
|
template getLatestByTag(meth: stmt): stmt {.dirty, immediate.} =
|
||||||
echo("Found tags...")
|
echo("Found tags...")
|
||||||
# Find latest version that fits our ``verRange``.
|
# Find latest version that fits our ``verRange``.
|
||||||
var latest = findLatest(verRange, versions)
|
var latest = findLatest(verRange, versions)
|
||||||
## Note: HEAD is not used when verRange.kind is verAny. This is
|
## Note: HEAD is not used when verRange.kind is verAny. This is
|
||||||
## intended behaviour, the latest tagged version will be used in this case.
|
## intended behaviour, the latest tagged version will be used in this case.
|
||||||
|
|
||||||
# If no tagged versions satisfy our range latest.tag will be "".
|
# If no tagged versions satisfy our range latest.tag will be "".
|
||||||
# We still clone in that scenario because we want to try HEAD in that case.
|
# We still clone in that scenario because we want to try HEAD in that case.
|
||||||
# https://github.com/nimrod-code/nimble/issues/22
|
# https://github.com/nimrod-code/nimble/issues/22
|
||||||
meth
|
meth
|
||||||
|
result = parseVersionRange($latest.ver)
|
||||||
|
|
||||||
proc verifyClone() =
|
proc verifyClone() =
|
||||||
## Makes sure that the downloaded package's version satisfies the requested
|
## Makes sure that the downloaded package's version satisfies the requested
|
||||||
|
|
@ -169,7 +174,7 @@ proc doDownload*(url: string, downloadDir: string, verRange: VersionRange,
|
||||||
"Downloaded package's version does not satisfy requested version " &
|
"Downloaded package's version does not satisfy requested version " &
|
||||||
"range: wanted $1 got $2." %
|
"range: wanted $1 got $2." %
|
||||||
[$verRange, $pkginfo.version])
|
[$verRange, $pkginfo.version])
|
||||||
|
|
||||||
removeDir(downloadDir)
|
removeDir(downloadDir)
|
||||||
if verRange.kind == verSpecial:
|
if verRange.kind == verSpecial:
|
||||||
# We want a specific commit/branch/tag here.
|
# We want a specific commit/branch/tag here.
|
||||||
|
|
@ -183,6 +188,7 @@ proc doDownload*(url: string, downloadDir: string, verRange: VersionRange,
|
||||||
else:
|
else:
|
||||||
doClone(downMethod, url, downloadDir, tip = false)
|
doClone(downMethod, url, downloadDir, tip = false)
|
||||||
doCheckout(downMethod, downloadDir, $verRange.spe)
|
doCheckout(downMethod, downloadDir, $verRange.spe)
|
||||||
|
result = verRange
|
||||||
else:
|
else:
|
||||||
case downMethod
|
case downMethod
|
||||||
of DownloadMethod.git:
|
of DownloadMethod.git:
|
||||||
|
|
@ -196,17 +202,19 @@ proc doDownload*(url: string, downloadDir: string, verRange: VersionRange,
|
||||||
else:
|
else:
|
||||||
# If no commits have been tagged on the repo we just clone HEAD.
|
# If no commits have been tagged on the repo we just clone HEAD.
|
||||||
doClone(downMethod, url, downloadDir) # Grab HEAD.
|
doClone(downMethod, url, downloadDir) # Grab HEAD.
|
||||||
|
result = parseVersionRange("#head")
|
||||||
|
|
||||||
verifyClone()
|
verifyClone()
|
||||||
of DownloadMethod.hg:
|
of DownloadMethod.hg:
|
||||||
doClone(downMethod, url, downloadDir)
|
doClone(downMethod, url, downloadDir)
|
||||||
|
result = parseVersionRange("#tip")
|
||||||
let versions = getTagsList(downloadDir, downMethod).getVersionList()
|
let versions = getTagsList(downloadDir, downMethod).getVersionList()
|
||||||
|
|
||||||
if versions.len > 0:
|
if versions.len > 0:
|
||||||
getLatestByTag:
|
getLatestByTag:
|
||||||
echo("Switching to latest tagged version: ", latest.tag)
|
echo("Switching to latest tagged version: ", latest.tag)
|
||||||
doCheckout(downMethod, downloadDir, latest.tag)
|
doCheckout(downMethod, downloadDir, latest.tag)
|
||||||
|
|
||||||
verifyClone()
|
verifyClone()
|
||||||
|
|
||||||
proc echoPackageVersions*(pkg: Package) =
|
proc echoPackageVersions*(pkg: Package) =
|
||||||
|
|
|
||||||
|
|
@ -5,3 +5,4 @@
|
||||||
|
|
||||||
type
|
type
|
||||||
NimbleError* = object of Exception
|
NimbleError* = object of Exception
|
||||||
|
BuildFailed* = object of NimbleError
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue