Implement configurable babelDir. Fixes #29.

This commit is contained in:
Dominik Picheta 2014-06-20 23:08:48 +01:00
commit d8068adef6
2 changed files with 46 additions and 31 deletions

View file

@ -4,7 +4,8 @@
import httpclient, parseopt, os, strutils, osproc, pegs, tables, parseutils, import httpclient, parseopt, os, strutils, osproc, pegs, tables, parseutils,
strtabs, json, algorithm, sets strtabs, json, algorithm, sets
import babelpkg/packageinfo, babelpkg/version, babelpkg/tools, babelpkg/download import babelpkg/packageinfo, babelpkg/version, babelpkg/tools, babelpkg/download,
babelpkg/config
when not defined(windows): when not defined(windows):
from posix import getpid from posix import getpid
@ -14,6 +15,7 @@ type
forcePrompts: TForcePrompt forcePrompts: TForcePrompt
queryVersions: bool queryVersions: bool
action: TAction action: TAction
config: TConfig
TActionType = enum TActionType = enum
ActionNil, ActionUpdate, ActionInstall, ActionSearch, ActionList, ActionNil, ActionUpdate, ActionInstall, ActionSearch, ActionList,
@ -67,8 +69,18 @@ proc writeVersion() =
echo("babel v$# compiled at $# $#" % [babelVersion, compileDate, compileTime]) echo("babel v$# compiled at $# $#" % [babelVersion, compileDate, compileTime])
quit(QuitSuccess) quit(QuitSuccess)
proc getBabelDir(options: TOptions): string =
options.config.babelDir
proc getPkgsDir(options: TOptions): string =
options.config.babelDir / "pkgs"
proc getBinDir(options: TOptions): string =
options.config.babelDir / "bin"
proc parseCmdLine(): TOptions = proc parseCmdLine(): TOptions =
result.action.typ = ActionNil result.action.typ = ActionNil
result.config = parseConfig()
for kind, key, val in getOpt(): for kind, key, val in getOpt():
case kind case kind
of cmdArgument: of cmdArgument:
@ -137,17 +149,18 @@ proc prompt(options: TOptions, question: string): bool =
else: else:
return false return false
let babelDir = getHomeDir() / ".babel" proc update(options: TOptions) =
let pkgsDir = babelDir / "pkgs"
let binDir = babelDir / "bin"
proc update(url: string = defaultPackageURL) =
## Downloads the package list from the specified URL. ## Downloads the package list from the specified URL.
## ##
## If the download is successful, the global didUpdatePackages is set to ## If the download is successful, the global didUpdatePackages is set to
## true. Otherwise an exception is raised on error. ## true. Otherwise an exception is raised on error.
let url =
if options.action.typ == ActionUpdate and options.action.optionalURL != "":
options.action.optionalURL
else:
defaultPackageURL
echo("Downloading package list from " & url) echo("Downloading package list from " & url)
downloadFile(url, babelDir / "packages.json") downloadFile(url, options.getBabelDir() / "packages.json")
echo("Done.") echo("Done.")
proc checkInstallFile(pkgInfo: TPackageInfo, proc checkInstallFile(pkgInfo: TPackageInfo,
@ -256,7 +269,7 @@ proc processDeps(pkginfo: TPackageInfo, options: TOptions): seq[string] =
## ##
## Returns the list of paths to pass to the compiler during build phase. ## Returns the list of paths to pass to the compiler during build phase.
result = @[] result = @[]
let pkglist = getInstalledPkgs(pkgsDir) let pkglist = getInstalledPkgs(options.getPkgsDir())
for dep in pkginfo.requires: for dep in pkginfo.requires:
if dep.name == "nimrod": if dep.name == "nimrod":
let nimVer = getNimrodVersion() let nimVer = getNimrodVersion()
@ -328,6 +341,8 @@ proc installFromDir(dir: string, latest: bool, options: TOptions,
## ``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.
var pkgInfo = getPkgInfo(dir) var pkgInfo = getPkgInfo(dir)
let realDir = pkgInfo.getRealDir() let realDir = pkgInfo.getRealDir()
let binDir = options.getBinDir()
let pkgsDir = options.getPkgsDir()
# Dependencies need to be processed before the creation of the pkg dir. # Dependencies need to be processed before the creation of the pkg dir.
let paths = processDeps(pkginfo, options) let paths = processDeps(pkginfo, options)
@ -428,10 +443,10 @@ proc install(packages: seq[tuple[name: string, verRange: PVersionRange]],
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(options.getBabelDir / "packages.json"):
if doPrompt and if doPrompt and
options.prompt("Local packages.json not found, download it from internet?"): options.prompt("Local packages.json not found, download it from internet?"):
update() update(options)
install(packages, options, false) install(packages, options, false)
else: else:
quit("Please run babel update.", QuitFailure) quit("Please run babel update.", QuitFailure)
@ -444,7 +459,7 @@ proc install(packages: seq[tuple[name: string, verRange: PVersionRange]],
result = installFromDir(downloadDir, false, options, pv.name) 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, options.getBabelDir() / "packages.json", pkg):
let downloadDir = downloadPkg(pkg, pv.verRange) let downloadDir = downloadPkg(pkg, pv.verRange)
result = installFromDir(downloadDir, false, options, pkg.url) result = installFromDir(downloadDir, false, options, pkg.url)
else: else:
@ -452,7 +467,7 @@ proc install(packages: seq[tuple[name: string, verRange: PVersionRange]],
if doPrompt and if doPrompt and
options.prompt(pv.name & " not found in local packages.json, " & options.prompt(pv.name & " not found in local packages.json, " &
"check internet for updated packages?"): "check internet for updated packages?"):
update() update(options)
install(@[pv], options, false) install(@[pv], options, false)
else: else:
raise newException(EBabel, "Package not found.") raise newException(EBabel, "Package not found.")
@ -469,9 +484,9 @@ proc search(options: TOptions) =
assert options.action.typ == ActionSearch assert options.action.typ == ActionSearch
if options.action.search == @[]: if options.action.search == @[]:
raise newException(EBabel, "Please specify a search string.") raise newException(EBabel, "Please specify a search string.")
if not existsFile(babelDir / "packages.json"): if not existsFile(options.getBabelDir() / "packages.json"):
raise newException(EBabel, "Please run babel update.") raise newException(EBabel, "Please run babel update.")
let pkgList = getPackageList(babelDir / "packages.json") let pkgList = getPackageList(options.getBabelDir() / "packages.json")
var found = false var found = false
template onFound: stmt = template onFound: stmt =
echoPackage(pkg) echoPackage(pkg)
@ -495,9 +510,9 @@ proc search(options: TOptions) =
echo("No package found.") echo("No package found.")
proc list(options: TOptions) = proc list(options: TOptions) =
if not existsFile(babelDir / "packages.json"): if not existsFile(options.getBabelDir() / "packages.json"):
raise newException(EBabel, "Please run babel update.") raise newException(EBabel, "Please run babel update.")
let pkgList = getPackageList(babelDir / "packages.json") let pkgList = getPackageList(options.getBabelDir() / "packages.json")
for pkg in pkgList: for pkg in pkgList:
echoPackage(pkg) echoPackage(pkg)
if options.queryVersions: if options.queryVersions:
@ -506,7 +521,7 @@ proc list(options: TOptions) =
type VersionAndPath = tuple[version: TVersion, path: string] type VersionAndPath = tuple[version: TVersion, path: string]
proc listPaths(packages: seq[String]) = proc listPaths(options: TOptions) =
## Loops over installing packages displaying their installed paths. ## Loops over installing packages displaying their installed paths.
## ##
## If there are several packages installed, only the last one (the version ## If there are several packages installed, only the last one (the version
@ -516,18 +531,19 @@ proc listPaths(packages: seq[String]) =
## ##
## On success the proc returns normally. ## On success the proc returns normally.
var errors = 0 var errors = 0
for name in packages: for name in options.action.optionalName:
var installed: seq[VersionAndPath] = @[] var installed: seq[VersionAndPath] = @[]
# There may be several, list all available ones and sort by version. # There may be several, list all available ones and sort by version.
for kind, path in walkDir(pkgsDir): for kind, path in walkDir(options.getPkgsDir):
if kind != pcDir or not path.startsWith(pkgsDir / name): continue if kind != pcDir or not path.startsWith(options.getPkgsDir / name):
continue
let babelFile = path / name.addFileExt("babel") let babelFile = path / name.addFileExt("babel")
if existsFile(babelFile): if existsFile(babelFile):
var pkgInfo = getPkgInfo(path) var pkgInfo = getPkgInfo(path)
var v: VersionAndPath var v: VersionAndPath
v.version = newVersion(pkgInfo.version) v.version = newVersion(pkgInfo.version)
v.path = pkgsDir / (pkgInfo.name & '-' & pkgInfo.version) v.path = options.getPkgsDir / (pkgInfo.name & '-' & pkgInfo.version)
installed.add(v) installed.add(v)
else: else:
echo "Warning: No .babel file found for ", path echo "Warning: No .babel file found for ", path
@ -542,12 +558,14 @@ proc listPaths(packages: seq[String]) =
raise newException(EBabel, "At least one of the specified packages was not found") raise newException(EBabel, "At least one of the specified packages was not found")
proc doAction(options: TOptions) = proc doAction(options: TOptions) =
if not existsDir(options.getBabelDir()):
createDir(options.getBabelDir())
if not existsDir(options.getPkgsDir):
createDir(options.getPkgsDir)
case options.action.typ case options.action.typ
of ActionUpdate: of ActionUpdate:
if options.action.optionalURL != "": update(options)
update(options.action.optionalURL)
else:
update()
of ActionInstall: of ActionInstall:
var installList: seq[tuple[name: string, verRange: PVersionRange]] = @[] var installList: seq[tuple[name: string, verRange: PVersionRange]] = @[]
for name in options.action.optionalName: for name in options.action.optionalName:
@ -563,18 +581,13 @@ proc doAction(options: TOptions) =
of ActionList: of ActionList:
list(options) list(options)
of ActionPath: of ActionPath:
listPaths(options.action.optionalName) listPaths(options)
of ActionBuild: of ActionBuild:
build(options) build(options)
of ActionNil: of ActionNil:
assert false assert false
when isMainModule: when isMainModule:
if not existsDir(babelDir):
createDir(babelDir)
if not existsDir(pkgsDir):
createDir(pkgsDir)
when defined(release): when defined(release):
try: try:
parseCmdLine().doAction() parseCmdLine().doAction()

View file

@ -1,3 +1,5 @@
# Copyright (C) Dominik Picheta. All rights reserved.
# BSD License. Look at license.txt for more info.
import osproc, unittest, strutils, os import osproc, unittest, strutils, os
const path = "../src/babel" const path = "../src/babel"