Implements #421.
This commit is contained in:
parent
7d3f3f9127
commit
25ffe273f7
4 changed files with 54 additions and 31 deletions
|
|
@ -434,13 +434,16 @@ proc installFromDir(dir: string, requestedVer: VersionRange, options: Options,
|
||||||
Success, HighPriority)
|
Success, HighPriority)
|
||||||
|
|
||||||
proc getDownloadInfo*(pv: PkgTuple, options: Options,
|
proc getDownloadInfo*(pv: PkgTuple, options: Options,
|
||||||
doPrompt: bool): (DownloadMethod, string) =
|
doPrompt: bool): (DownloadMethod, string,
|
||||||
|
Table[string, string]) =
|
||||||
if pv.name.isURL:
|
if pv.name.isURL:
|
||||||
return (checkUrlType(pv.name), pv.name)
|
let (url, metadata) = getUrlData(pv.name)
|
||||||
|
return (checkUrlType(url), url, metadata)
|
||||||
else:
|
else:
|
||||||
var pkg: Package
|
var pkg: Package
|
||||||
if getPackage(pv.name, options, pkg):
|
if getPackage(pv.name, options, pkg):
|
||||||
return (pkg.downloadMethod.getDownloadMethod(), pkg.url)
|
let (url, metadata) = getUrlData(pkg.url)
|
||||||
|
return (pkg.downloadMethod.getDownloadMethod(), url, metadata)
|
||||||
else:
|
else:
|
||||||
# If package is not found give the user a chance to refresh
|
# If package is not found give the user a chance to refresh
|
||||||
# package.json
|
# package.json
|
||||||
|
|
@ -464,9 +467,10 @@ proc install(packages: seq[PkgTuple],
|
||||||
else:
|
else:
|
||||||
# Install each package.
|
# Install each package.
|
||||||
for pv in packages:
|
for pv in packages:
|
||||||
let (meth, url) = getDownloadInfo(pv, options, doPrompt)
|
let (meth, url, metadata) = getDownloadInfo(pv, options, doPrompt)
|
||||||
|
let subdir = metadata.getOrDefault("subdir")
|
||||||
let (downloadDir, downloadVersion) =
|
let (downloadDir, downloadVersion) =
|
||||||
downloadPkg(url, pv.ver, meth, options)
|
downloadPkg(url, pv.ver, meth, subdir, options)
|
||||||
try:
|
try:
|
||||||
# Run pre-install hook in download directory now that package is downloaded
|
# Run pre-install hook in download directory now that package is downloaded
|
||||||
cd downloadDir:
|
cd downloadDir:
|
||||||
|
|
@ -1005,8 +1009,9 @@ proc develop(options: Options) =
|
||||||
let hint = "Remove the directory, or run this command somewhere else."
|
let hint = "Remove the directory, or run this command somewhere else."
|
||||||
raiseNimbleError(msg, hint)
|
raiseNimbleError(msg, hint)
|
||||||
|
|
||||||
let (meth, url) = getDownloadInfo(pv, options, true)
|
let (meth, url, metadata) = getDownloadInfo(pv, options, true)
|
||||||
discard downloadPkg(url, pv.ver, meth, options, downloadDir)
|
let subdir = metadata.getOrDefault("subdir")
|
||||||
|
discard downloadPkg(url, pv.ver, meth, subdir, options, downloadDir)
|
||||||
developFromDir(downloadDir, options)
|
developFromDir(downloadDir, options)
|
||||||
|
|
||||||
proc test(options: Options) =
|
proc test(options: Options) =
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# Copyright (C) Dominik Picheta. All rights reserved.
|
# Copyright (C) Dominik Picheta. All rights reserved.
|
||||||
# BSD License. Look at license.txt for more info.
|
# BSD License. Look at license.txt for more info.
|
||||||
|
|
||||||
import parseutils, os, osproc, strutils, tables, pegs
|
import parseutils, os, osproc, strutils, tables, pegs, uri
|
||||||
|
|
||||||
import packageinfo, packageparser, version, tools, common, options, cli
|
import packageinfo, packageparser, version, tools, common, options, cli
|
||||||
|
|
||||||
|
|
@ -132,13 +132,24 @@ proc checkUrlType*(url: string): DownloadMethod =
|
||||||
elif doCmdEx("hg identify " & url).exitCode == QuitSuccess:
|
elif doCmdEx("hg identify " & url).exitCode == QuitSuccess:
|
||||||
return DownloadMethod.hg
|
return DownloadMethod.hg
|
||||||
else:
|
else:
|
||||||
raise newException(NimbleError, "Unable to identify url.")
|
raise newException(NimbleError, "Unable to identify url: " & url)
|
||||||
|
|
||||||
|
proc getUrlData*(url: string): (string, Table[string, string]) =
|
||||||
|
var uri = parseUri(url)
|
||||||
|
# TODO: use uri.parseQuery once it lands... this code is quick and dirty.
|
||||||
|
var subdir = ""
|
||||||
|
if uri.query.startsWith("subdir="):
|
||||||
|
subdir = uri.query[7 .. ^1]
|
||||||
|
|
||||||
|
uri.query = ""
|
||||||
|
return ($uri, {"subdir": subdir}.toTable())
|
||||||
|
|
||||||
proc isURL*(name: string): bool =
|
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, options: Options): Version =
|
downMethod: DownloadMethod,
|
||||||
|
options: Options): Version =
|
||||||
## Downloads the repository specified by ``url`` using the specified download
|
## Downloads the repository specified by ``url`` using the specified download
|
||||||
## method.
|
## method.
|
||||||
##
|
##
|
||||||
|
|
@ -159,16 +170,6 @@ proc doDownload*(url: string, downloadDir: string, verRange: VersionRange,
|
||||||
# Result should already be set to #head here.
|
# Result should already be set to #head here.
|
||||||
assert(not result.isNil)
|
assert(not result.isNil)
|
||||||
|
|
||||||
proc verifyClone() =
|
|
||||||
## Makes sure that the downloaded package's version satisfies the requested
|
|
||||||
## version range.
|
|
||||||
let pkginfo = getPkgInfo(downloadDir, options)
|
|
||||||
if pkginfo.version.newVersion notin verRange:
|
|
||||||
raise newException(NimbleError,
|
|
||||||
"Downloaded package's version does not satisfy requested version " &
|
|
||||||
"range: wanted $1 got $2." %
|
|
||||||
[$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.
|
||||||
|
|
@ -197,8 +198,6 @@ 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.
|
||||||
|
|
||||||
verifyClone()
|
|
||||||
of DownloadMethod.hg:
|
of DownloadMethod.hg:
|
||||||
doClone(downMethod, url, downloadDir)
|
doClone(downMethod, url, downloadDir)
|
||||||
result = getHeadName(downMethod)
|
result = getHeadName(downMethod)
|
||||||
|
|
@ -210,10 +209,9 @@ proc doDownload*(url: string, downloadDir: string, verRange: VersionRange,
|
||||||
priority = MediumPriority)
|
priority = MediumPriority)
|
||||||
doCheckout(downMethod, downloadDir, latest.tag)
|
doCheckout(downMethod, downloadDir, latest.tag)
|
||||||
|
|
||||||
verifyClone()
|
|
||||||
|
|
||||||
proc downloadPkg*(url: string, verRange: VersionRange,
|
proc downloadPkg*(url: string, verRange: VersionRange,
|
||||||
downMethod: DownloadMethod,
|
downMethod: DownloadMethod,
|
||||||
|
subdir: string,
|
||||||
options: Options,
|
options: Options,
|
||||||
downloadPath = ""): (string, Version) =
|
downloadPath = ""): (string, Version) =
|
||||||
## Downloads the repository as specified by ``url`` and ``verRange`` using
|
## Downloads the repository as specified by ``url`` and ``verRange`` using
|
||||||
|
|
@ -221,8 +219,8 @@ proc downloadPkg*(url: string, verRange: VersionRange,
|
||||||
##
|
##
|
||||||
## If `downloadPath` isn't specified a location in /tmp/ will be used.
|
## If `downloadPath` isn't specified a location in /tmp/ will be used.
|
||||||
##
|
##
|
||||||
## Returns the directory where it was downloaded and the concrete version
|
## Returns the directory where it was downloaded (subdir is appended) and
|
||||||
## which was downloaded.
|
## the concrete version which was downloaded.
|
||||||
let downloadDir =
|
let downloadDir =
|
||||||
if downloadPath == "":
|
if downloadPath == "":
|
||||||
(getNimbleTempDir() / getDownloadDirName(url, verRange))
|
(getNimbleTempDir() / getDownloadDirName(url, verRange))
|
||||||
|
|
@ -241,13 +239,28 @@ proc downloadPkg*(url: string, verRange: VersionRange,
|
||||||
if modUrl.contains("github.com") and modUrl.endswith("/"):
|
if modUrl.contains("github.com") and modUrl.endswith("/"):
|
||||||
modUrl = modUrl[0 .. ^2]
|
modUrl = modUrl[0 .. ^2]
|
||||||
|
|
||||||
display("Downloading", "$1 using $2" % [modUrl, $downMethod],
|
if subdir.len > 0:
|
||||||
priority = HighPriority)
|
display("Downloading", "$1 using $2 (subdir is '$3')" %
|
||||||
|
[modUrl, $downMethod, subdir],
|
||||||
|
priority = HighPriority)
|
||||||
|
else:
|
||||||
|
display("Downloading", "$1 using $2" % [modUrl, $downMethod],
|
||||||
|
priority = HighPriority)
|
||||||
result = (
|
result = (
|
||||||
downloadDir,
|
downloadDir / subdir,
|
||||||
doDownload(modUrl, downloadDir, verRange, downMethod, options)
|
doDownload(modUrl, downloadDir, verRange, downMethod, options)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if verRange.kind != verSpecial:
|
||||||
|
## Makes sure that the downloaded package's version satisfies the requested
|
||||||
|
## version range.
|
||||||
|
let pkginfo = getPkgInfo(result[0], options)
|
||||||
|
if pkginfo.version.newVersion notin verRange:
|
||||||
|
raise newException(NimbleError,
|
||||||
|
"Downloaded package's version does not satisfy requested version " &
|
||||||
|
"range: wanted $1 got $2." %
|
||||||
|
[$verRange, $pkginfo.version])
|
||||||
|
|
||||||
proc echoPackageVersions*(pkg: Package) =
|
proc echoPackageVersions*(pkg: Package) =
|
||||||
let downMethod = pkg.downloadMethod.getDownloadMethod()
|
let downMethod = pkg.downloadMethod.getDownloadMethod()
|
||||||
case downMethod
|
case downMethod
|
||||||
|
|
|
||||||
|
|
@ -304,7 +304,7 @@ proc findNimbleFile*(dir: string; error: bool): string =
|
||||||
elif hits == 0:
|
elif hits == 0:
|
||||||
if error:
|
if error:
|
||||||
raise newException(NimbleError,
|
raise newException(NimbleError,
|
||||||
"Specified directory does not contain a .nimble file.")
|
"Specified directory ($1) does not contain a .nimble file." % dir)
|
||||||
else:
|
else:
|
||||||
display("Warning:", "No .nimble or .nimble-link file found for " &
|
display("Warning:", "No .nimble or .nimble-link file found for " &
|
||||||
dir, Warning, HighPriority)
|
dir, Warning, HighPriority)
|
||||||
|
|
|
||||||
|
|
@ -675,3 +675,8 @@ suite "check command":
|
||||||
check outp.processOutput.inLines("failure")
|
check outp.processOutput.inLines("failure")
|
||||||
check outp.processOutput.inLines("validation failed")
|
check outp.processOutput.inLines("validation failed")
|
||||||
check outp.processOutput.inLines("package 'x' has an incorrect structure")
|
check outp.processOutput.inLines("package 'x' has an incorrect structure")
|
||||||
|
|
||||||
|
suite "multi":
|
||||||
|
test "can install package from git subdir":
|
||||||
|
let args = ["install", "-y", "https://github.com/nimble-test/multi?subdir=alpha"]
|
||||||
|
check execNimble(args).exitCode == QuitSuccess
|
||||||
Loading…
Add table
Add a link
Reference in a new issue