This commit is contained in:
Dominik Picheta 2013-12-20 13:31:59 +00:00
commit e789a7a325
2 changed files with 36 additions and 15 deletions

View file

@ -1,7 +1,8 @@
# 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 httpclient, parseopt, os, strutils, osproc, pegs, tables, parseutils, strtabs import httpclient, parseopt, os, strutils, osproc, pegs, tables, parseutils,
strtabs, json
import packageinfo, version, common, tools, download, algorithm import packageinfo, version, common, tools, download, algorithm
@ -272,7 +273,7 @@ proc buildFromDir(pkgInfo: TPackageInfo, paths: seq[string]) =
doCmd("nimrod $# -d:release $# \"$#\"" % doCmd("nimrod $# -d:release $# \"$#\"" %
[pkgInfo.backend, args, realDir / bin.changeFileExt("nim")]) [pkgInfo.backend, args, realDir / bin.changeFileExt("nim")])
proc installFromDir(dir: string, latest: bool, options: TOptions): seq[string] = proc installFromDir(dir: string, latest: bool, options: TOptions, url: string): seq[string] =
## Returns where package has been installed to. ## Returns where package has been installed to.
## The return value of this function is used by ## The return value of this function is used by
## ``processDeps`` to gather a list of paths to pass to the nimrod compiler. ## ``processDeps`` to gather a list of paths to pass to the nimrod compiler.
@ -329,6 +330,10 @@ proc installFromDir(dir: string, latest: bool, options: TOptions): seq[string] =
else: else:
copyFilesRec(realDir, realDir, pkgDestDir, pkgInfo) copyFilesRec(realDir, realDir, pkgDestDir, pkgInfo)
# Save a babelmeta.json file.
var babelmeta = %{"url": %url}
writeFile(pkgDestDir / "babelmeta.json", $babelmeta)
result = paths # Return the paths to the dependencies of this package. result = paths # Return the paths to the dependencies of this package.
result.add pkgDestDir result.add pkgDestDir
@ -353,7 +358,7 @@ proc downloadPkg(pkg: TPackage, verRange: PVersionRange): string =
proc install(packages: seq[tuple[name: string, verRange: PVersionRange]], proc install(packages: seq[tuple[name: string, verRange: PVersionRange]],
options: TOptions, doPrompt = true): seq[string] = options: TOptions, doPrompt = true): seq[string] =
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(babelDir / "packages.json"): if not existsFile(babelDir / "packages.json"):
@ -369,12 +374,12 @@ proc install(packages: seq[tuple[name: string, verRange: PVersionRange]],
if pv.name.startsWith(peg" @'://' "): if pv.name.startsWith(peg" @'://' "):
let meth = checkUrlType(pv.name) let meth = checkUrlType(pv.name)
let downloadDir = downloadPkg(pv.name, pv.verRange, meth) let downloadDir = downloadPkg(pv.name, pv.verRange, meth)
result = installFromDir(downloadDir, false, options) result = installFromDir(downloadDir, false, options, pv.name)
else: else:
var pkg: TPackage var pkg: TPackage
if getPackage(pv.name, babelDir / "packages.json", pkg): if getPackage(pv.name, babelDir / "packages.json", pkg):
let downloadDir = downloadPkg(pkg, pv.verRange) let downloadDir = downloadPkg(pkg, pv.verRange)
result = installFromDir(downloadDir, false, options) result = installFromDir(downloadDir, false, options, pkg.url)
else: else:
# If package is not found give the user a chance to update package.json # If package is not found give the user a chance to update package.json
if doPrompt and if doPrompt and

View file

@ -34,6 +34,9 @@ type
dvcsTag*: string dvcsTag*: string
web*: string # Info url for humans. web*: string # Info url for humans.
TMetadata* = object
url*: string
proc initPackageInfo(): TPackageInfo = proc initPackageInfo(): TPackageInfo =
result.mypath = "" result.mypath = ""
result.name = "" result.name = ""
@ -209,6 +212,18 @@ proc fromJson(obj: PJSonNode): TPackage =
result.description = obj.requiredField("description") result.description = obj.requiredField("description")
result.web = obj.optionalField("web") result.web = obj.optionalField("web")
proc readMetadata*(path: string): TMetadata =
## Reads the metadata present in ``~/.babel/pkgs/pkg-0.1/babelmeta.json``
let bmeta = path / "babelmeta.json"
if not existsFile(bmeta):
result.url = ""
echo("WARNING: No babelmeta.json file found in " & path)
return
# TODO: Make this an error.
let cont = readFile(path / "babelmeta.json")
let jsonmeta = parseJson(cont)
result.url = jsonmeta["url"].str
proc getPackage*(pkg: string, packagesPath: string, resPkg: var TPackage): bool = proc getPackage*(pkg: string, packagesPath: string, resPkg: var TPackage): bool =
## Searches ``packagesPath`` file saving into ``resPkg`` the found package. ## Searches ``packagesPath`` file saving into ``resPkg`` the found package.
## ##
@ -244,32 +259,33 @@ proc getPkgInfo*(dir: string): TPackageInfo =
raise newException(EBabel, "Specified directory does not contain a .babel file.") raise newException(EBabel, "Specified directory does not contain a .babel file.")
result = readPackageInfo(babelFile) result = readPackageInfo(babelFile)
proc getInstalledPkgs*(libsDir: string): seq[TPackageInfo] = proc getInstalledPkgs*(libsDir: string): seq[tuple[pkginfo: TPackageInfo, meta: TMetaData]] =
## Gets a list of installed packages. ## Gets a list of installed packages.
## ##
## ``libsDir`` is in most cases: ~/.babel/libs/ ## ``libsDir`` is in most cases: ~/.babel/pkgs/
result = @[] result = @[]
for kind, path in walkDir(libsDir): for kind, path in walkDir(libsDir):
if kind == pcDir: if kind == pcDir:
let babelFile = findBabelFile(path) let babelFile = findBabelFile(path)
if babelFile != "": if babelFile != "":
result.add(readPackageInfo(babelFile)) let meta = readMetadata(path)
result.add((readPackageInfo(babelFile), meta))
else: else:
# TODO: Abstract logging. # TODO: Abstract logging.
echo("WARNING: No .babel file found for ", path) echo("WARNING: No .babel file found for ", path)
proc findPkg*(pkglist: seq[TPackageInfo], proc findPkg*(pkglist: seq[tuple[pkginfo: TPackageInfo, meta: TMetaData]],
dep: tuple[name: string, ver: PVersionRange], dep: tuple[name: string, ver: PVersionRange],
r: var TPackageInfo): bool = r: var TPackageInfo): bool =
## Searches ``pkglist`` for a package of which version is withing the range ## Searches ``pkglist`` for a package of which version is within the range
## of ``dep.ver``. ``True`` is returned if a package is found. If multiple ## of ``dep.ver``. ``True`` is returned if a package is found. If multiple
## packages are found the newest one is returned (the one with the highest ## packages are found the newest one is returned (the one with the highest
## version number) ## version number)
for pkg in pkglist: for pkg in pkglist:
if pkg.name != dep.name: continue if pkg.pkginfo.name != dep.name and pkg.meta.url != dep.name: continue
if withinRange(newVersion(pkg.version), dep.ver): if withinRange(newVersion(pkg.pkginfo.version), dep.ver):
if not result or newVersion(r.version) < newVersion(pkg.version): if not result or newVersion(r.version) < newVersion(pkg.pkginfo.version):
r = pkg r = pkg.pkginfo
result = true result = true
proc getRealDir*(pkgInfo: TPackageInfo): string = proc getRealDir*(pkgInfo: TPackageInfo): string =
@ -281,7 +297,7 @@ proc getRealDir*(pkgInfo: TPackageInfo): string =
result = pkgInfo.mypath.splitFile.dir result = pkgInfo.mypath.splitFile.dir
proc getNameVersion*(pkgpath: string): tuple[name, version: string] = proc getNameVersion*(pkgpath: string): tuple[name, version: string] =
## Splits ``pkgpath`` in the format ``/home/user/.babel/libs/package-0.1`` ## Splits ``pkgpath`` in the format ``/home/user/.babel/pkgs/package-0.1``
## into ``(packagea, 0.1)`` ## into ``(packagea, 0.1)``
result.name = "" result.name = ""
result.version = "" result.version = ""