From 4bc0c17fe93ad455f176849b6d728cb4fc64eac4 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Sun, 15 Dec 2013 00:55:36 +0000 Subject: [PATCH] A URL can now be specified for installation. --- babel.nim | 32 ++++++++++++++++++++++++-------- download.nim | 35 ++++++++++++++++++++++++----------- 2 files changed, 48 insertions(+), 19 deletions(-) diff --git a/babel.nim b/babel.nim index 4d7a43e..2540b06 100644 --- a/babel.nim +++ b/babel.nim @@ -321,6 +321,14 @@ proc installFromDir(dir: string, latest: bool, options: TOptions): string = echo(pkgInfo.name & " installed successfully.") +proc downloadPkg(url: string, verRange: PVersionRange, + downMethod: TDownloadMethod): string = + let downloadDir = (getTempDir() / "babel" / "url_unknown") + if not existsDir(getTempDir() / "babel"): createDir(getTempDir() / "babel") + echo("Downloading ", url, " into ", downloadDir, "...") + doDownload(url, downloadDir, verRange, downMethod) + result = downloadDir + proc downloadPkg(pkg: TPackage, verRange: PVersionRange): string = let downloadDir = (getTempDir() / "babel" / pkg.name) if not existsDir(getTempDir() / "babel"): createDir(getTempDir() / "babel") @@ -333,6 +341,7 @@ proc install(packages: seq[tuple[name: string, verRange: PVersionRange]], if packages == @[]: result = installFromDir(getCurrentDir(), false, options) else: + # If packages.json is not present ask the user if they want to download it. if not existsFile(babelDir / "packages.json"): if doPrompt and options.prompt("Local packages.json not found, download it from internet?"): @@ -341,18 +350,25 @@ proc install(packages: seq[tuple[name: string, verRange: PVersionRange]], else: quit("Please run babel update.", QuitFailure) + # Install each package. for pv in packages: - var pkg: TPackage - if getPackage(pv.name, babelDir / "packages.json", pkg): - let downloadDir = downloadPkg(pkg, pv.verRange) + if pv.name.startsWith(peg" @'://' "): + let meth = checkUrlType(pv.name) + let downloadDir = downloadPkg(pv.name, pv.verRange, meth) result = installFromDir(downloadDir, false, options) else: - if doPrompt and - options.prompt(pv.name & " not found in local packages.json, check internet for updated packages?"): - update() - install(@[pv], options, false) + var pkg: TPackage + if getPackage(pv.name, babelDir / "packages.json", pkg): + let downloadDir = downloadPkg(pkg, pv.verRange) + result = installFromDir(downloadDir, false, options) else: - raise newException(EBabel, "Package not found.") + # 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() + install(@[pv], options, false) + else: + raise newException(EBabel, "Package not found.") proc build(options: TOptions) = var pkgInfo = getPkgInfo(getCurrentDir()) diff --git a/download.nim b/download.nim index 2f83a38..a64dc82 100644 --- a/download.nim +++ b/download.nim @@ -6,7 +6,7 @@ import parseutils, os, osproc, strutils, tables import packageinfo, common, version, tools type - TDownloadMethod {.pure.} = enum + TDownloadMethod* {.pure.} = enum Git = "git", Hg = "hg" proc getSpecificDir(meth: TDownloadMethod): string = @@ -109,7 +109,17 @@ proc getHeadName*(meth: TDownloadMethod): string = of TDownloadMethod.Git: "head" of TDownloadMethod.Hg: "tip" -proc doDownload*(pkg: TPackage, downloadDir: string, verRange: PVersionRange) = +proc checkUrlType*(url: string): TDownloadMethod = + ## Determines the download method based on the URL. + if execCmdEx("git ls-remote " & url).exitCode == QuitSuccess: + return TDownloadMethod.Git + elif execCmdEx("hg identify " & url).exitCode == QuitSuccess: + return TDownloadMethod.Hg + else: + raise newException(EBabel, "Unable to identify url.") + +proc doDownload*(url: string, downloadDir: string, verRange: PVersionRange, + downMethod: TDownloadMethod) = template getLatestByTag(meth: stmt): stmt {.dirty, immediate.} = echo("Found tags...") # Find latest version that fits our ``verRange``. @@ -124,40 +134,38 @@ proc doDownload*(pkg: TPackage, downloadDir: string, verRange: PVersionRange) = let pkginfo = getPkgInfo(downloadDir) if pkginfo.version.newVersion notin verRange: raise newException(EBabel, - "No versions of " & pkg.name & + "No versions of " & url & " exist (this usually means that `git tag` returned nothing)." & "Git HEAD also does not satisfy version range: " & $verRange) - let downMethod = pkg.downloadMethod.getDownloadMethod() - echo "Downloading ", pkg.name, " using ", downMethod, "..." removeDir(downloadDir) if verRange.kind == verSpecial: # We want a specific commit/branch/tag here. if verRange.spe == newSpecial(getHeadName(downMethod)): - doClone(downMethod, pkg.url, downloadDir) # Grab HEAD. + doClone(downMethod, url, downloadDir) # Grab HEAD. else: # We don't know if we got a commit hash or a branch here, and # we can't clone a specific commit (with depth 1) according to: # http://stackoverflow.com/a/7198956/492186 - doClone(downMethod, pkg.url, downloadDir, tip = false) + doClone(downMethod, url, downloadDir, tip = false) doCheckout(downMethod, downloadDir, $verRange.spe) else: case downMethod of TDownloadMethod.Git: # For Git we have to query the repo remotely for its tags. This is # necessary as cloning with a --depth of 1 removes all tag info. - let versions = getTagsListRemote(pkg.url, downMethod).getVersionList() + let versions = getTagsListRemote(url, downMethod).getVersionList() if versions.len > 0: getLatestByTag: echo("Cloning latest tagged version: ", latest.tag) - doClone(downMethod, pkg.url, downloadDir, latest.tag) + doClone(downMethod, url, downloadDir, latest.tag) else: # If no commits have been tagged on the repo we just clone HEAD. - doClone(downMethod, pkg.url, downloadDir) # Grab HEAD. + doClone(downMethod, url, downloadDir) # Grab HEAD. if verRange.kind != verAny: verifyHead() of TDownloadMethod.Hg: - doClone(downMethod, pkg.url, downloadDir) + doClone(downMethod, url, downloadDir) let versions = getTagsList(downloadDir, downMethod).getVersionList() if versions.len > 0: @@ -167,6 +175,11 @@ proc doDownload*(pkg: TPackage, downloadDir: string, verRange: PVersionRange) = elif verRange.kind != verAny: verifyHead() +proc doDownload*(pkg: TPackage, downloadDir: string, verRange: PVersionRange) = + let downMethod = pkg.downloadMethod.getDownloadMethod() + echo "Downloading ", pkg.name, " using ", downMethod, "..." + doDownload(pkg.url, downloadDir, verRange, downMethod) + proc echoPackageVersions*(pkg: TPackage) = let downMethod = pkg.downloadMethod.getDownloadMethod() case downMethod