Implements #421.

This commit is contained in:
Dominik Picheta 2018-02-23 22:27:14 +00:00
commit 25ffe273f7
4 changed files with 54 additions and 31 deletions

View file

@ -434,13 +434,16 @@ proc installFromDir(dir: string, requestedVer: VersionRange, options: Options,
Success, HighPriority)
proc getDownloadInfo*(pv: PkgTuple, options: Options,
doPrompt: bool): (DownloadMethod, string) =
doPrompt: bool): (DownloadMethod, string,
Table[string, string]) =
if pv.name.isURL:
return (checkUrlType(pv.name), pv.name)
let (url, metadata) = getUrlData(pv.name)
return (checkUrlType(url), url, metadata)
else:
var pkg: Package
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:
# If package is not found give the user a chance to refresh
# package.json
@ -464,9 +467,10 @@ proc install(packages: seq[PkgTuple],
else:
# Install each package.
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) =
downloadPkg(url, pv.ver, meth, options)
downloadPkg(url, pv.ver, meth, subdir, options)
try:
# Run pre-install hook in download directory now that package is downloaded
cd downloadDir:
@ -1005,8 +1009,9 @@ proc develop(options: Options) =
let hint = "Remove the directory, or run this command somewhere else."
raiseNimbleError(msg, hint)
let (meth, url) = getDownloadInfo(pv, options, true)
discard downloadPkg(url, pv.ver, meth, options, downloadDir)
let (meth, url, metadata) = getDownloadInfo(pv, options, true)
let subdir = metadata.getOrDefault("subdir")
discard downloadPkg(url, pv.ver, meth, subdir, options, downloadDir)
developFromDir(downloadDir, options)
proc test(options: Options) =

View file

@ -1,7 +1,7 @@
# Copyright (C) Dominik Picheta. All rights reserved.
# 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
@ -132,13 +132,24 @@ proc checkUrlType*(url: string): DownloadMethod =
elif doCmdEx("hg identify " & url).exitCode == QuitSuccess:
return DownloadMethod.hg
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 =
name.startsWith(peg" @'://' ")
proc doDownload*(url: string, downloadDir: string, verRange: VersionRange,
downMethod: DownloadMethod, options: Options): Version =
proc doDownload(url: string, downloadDir: string, verRange: VersionRange,
downMethod: DownloadMethod,
options: Options): Version =
## Downloads the repository specified by ``url`` using the specified download
## method.
##
@ -159,16 +170,6 @@ proc doDownload*(url: string, downloadDir: string, verRange: VersionRange,
# Result should already be set to #head here.
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)
if verRange.kind == verSpecial:
# We want a specific commit/branch/tag here.
@ -197,8 +198,6 @@ proc doDownload*(url: string, downloadDir: string, verRange: VersionRange,
else:
# If no commits have been tagged on the repo we just clone HEAD.
doClone(downMethod, url, downloadDir) # Grab HEAD.
verifyClone()
of DownloadMethod.hg:
doClone(downMethod, url, downloadDir)
result = getHeadName(downMethod)
@ -210,10 +209,9 @@ proc doDownload*(url: string, downloadDir: string, verRange: VersionRange,
priority = MediumPriority)
doCheckout(downMethod, downloadDir, latest.tag)
verifyClone()
proc downloadPkg*(url: string, verRange: VersionRange,
downMethod: DownloadMethod,
subdir: string,
options: Options,
downloadPath = ""): (string, Version) =
## 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.
##
## Returns the directory where it was downloaded and the concrete version
## which was downloaded.
## Returns the directory where it was downloaded (subdir is appended) and
## the concrete version which was downloaded.
let downloadDir =
if downloadPath == "":
(getNimbleTempDir() / getDownloadDirName(url, verRange))
@ -241,13 +239,28 @@ proc downloadPkg*(url: string, verRange: VersionRange,
if modUrl.contains("github.com") and modUrl.endswith("/"):
modUrl = modUrl[0 .. ^2]
display("Downloading", "$1 using $2" % [modUrl, $downMethod],
priority = HighPriority)
if subdir.len > 0:
display("Downloading", "$1 using $2 (subdir is '$3')" %
[modUrl, $downMethod, subdir],
priority = HighPriority)
else:
display("Downloading", "$1 using $2" % [modUrl, $downMethod],
priority = HighPriority)
result = (
downloadDir,
downloadDir / subdir,
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) =
let downMethod = pkg.downloadMethod.getDownloadMethod()
case downMethod

View file

@ -304,7 +304,7 @@ proc findNimbleFile*(dir: string; error: bool): string =
elif hits == 0:
if error:
raise newException(NimbleError,
"Specified directory does not contain a .nimble file.")
"Specified directory ($1) does not contain a .nimble file." % dir)
else:
display("Warning:", "No .nimble or .nimble-link file found for " &
dir, Warning, HighPriority)

View file

@ -675,3 +675,8 @@ suite "check command":
check outp.processOutput.inLines("failure")
check outp.processOutput.inLines("validation failed")
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