Babel can now tell when you are trying to install a new version, and will upgrade it for you. There is still no system for dependencies to import the version they want though.

This commit is contained in:
Dominik Picheta 2011-01-30 13:43:49 +00:00
commit 417fdc074d
2 changed files with 101 additions and 30 deletions

View file

@ -45,16 +45,16 @@ proc dependExists(name: string, verRange: PVersionRange): Bool =
for kind, path in walkDir(getBabelDir() / "packages"): for kind, path in walkDir(getBabelDir() / "packages"):
if kind == pcFile: if kind == pcFile:
var file = path.extractFilename() var file = path.extractFilename()
if file == name.addFileExt("babel"): if file.startswith(name & "-"):
if verRange.kind != verAny: if verRange.kind != verAny:
var conf = parseBabel(path) var ver = ""
var verRet = conf.verify() # This will have a dot at the end, it doesn't cause trouble though.
if verRet == "": var ret = file.parseToken(ver, digits + {'.'}, name.len() + 1)
if withinRange(newVersion(conf.version), verRange): if ret != 0:
if withinRange(newVersion(ver), verRange):
return True return True
else: else:
raise newException(EInstall, "Package has an invalid .babel file: " & raise newException(EInstall, "Invalid .babel file: " & file)
verRet)
else: return True else: return True
return False return False
@ -84,9 +84,26 @@ proc verifyDepends(proj: TProject): seq[TDepend] =
if not dependExists(nameStr, verRange): if not dependExists(nameStr, verRange):
result.add((nameStr, verRange)) result.add((nameStr, verRange))
proc createDirDebug(dir: string) =
# Have to check, so that it doesn't echo...
if not existsDir(dir):
stdout.write("Creating directory " & dir & "...")
createDir(dir)
echo(" Done!")
proc createDirs(dirs: seq[string]) = proc createDirs(dirs: seq[string]) =
for i in items(dirs): for i in items(dirs):
createDir(i) createDirDebug(i)
proc copyFileDebug(file, copyTo: string) =
stdout.write("Copying " & file & " to " & copyTo & "...")
copyFile(file, copyTo)
echo(" Done!")
proc moveFileDebug(file, moveTo: string) =
stdout.write("Moving " & file & " to " & moveTo & "...")
moveFile(file, moveTo)
echo(" Done!")
proc copyFiles(proj: TProject) = proc copyFiles(proj: TProject) =
# This will create a $home/.babel and lib/ or bin/. It will also copy all the # This will create a $home/.babel and lib/ or bin/. It will also copy all the
@ -98,21 +115,17 @@ proc copyFiles(proj: TProject) =
if proj.library: if proj.library:
# TODO: How will we handle multiple versions? # TODO: How will we handle multiple versions?
var projDir = babelDir / "lib" / proj.name # $babel/lib/name var projDir = babelDir / "lib" / proj.name # $babel/lib/name
createDir(projDir) createDirDebug(projDir)
# Copy the files # Copy the files
for i in items(proj.modules): for i in items(proj.modules):
var file = proj.confDir / i.addFileExt("nim") var file = proj.confDir / i.addFileExt("nim")
var copyTo = projDir / i.addFileExt("nim") var copyTo = projDir / i.addFileExt("nim")
stdout.write("Copying " & file & " to " & copyTo & "...") copyFileDebug(file, copyTo)
copyFile(file, copyTo)
echo(" Done!")
if proj.files.len > 0: if proj.files.len > 0:
for i in items(proj.files): for i in items(proj.files):
var file = proj.confDir / i var file = proj.confDir / i
var copyTo = projDir / i var copyTo = projDir / i
stdout.write("Copying " & file & " to " & copyTo & "...") copyFileDebug(file, copyTo)
copyFile(file, copyTo)
echo(" Done!")
elif proj.executable: elif proj.executable:
var exeSrcFile = proj.confDir / proj.exeFile.addFileExt("nim") var exeSrcFile = proj.confDir / proj.exeFile.addFileExt("nim")
@ -121,16 +134,53 @@ proc copyFiles(proj: TProject) =
var exeCmpFile = exeSrcFile.changeFileExt(ExeExt) var exeCmpFile = exeSrcFile.changeFileExt(ExeExt)
var copyTo = babelDir / "bin" / proj.exeFile.addFileExt(ExeExt) var copyTo = babelDir / "bin" / proj.exeFile.addFileExt(ExeExt)
stdout.write("Copying " & exeCmpFile & " to " & copyTo & "...") copyFileDebug(exeCmpFile, copyTo)
copyFile(exeCmpFile, copyTo)
echo(" Done!")
# Copy the .babel file into the packages folder. # Copy the .babel file into the packages folder.
var babelFile = proj.confDir / proj.name.addFileExt("babel") var babelFile = proj.confDir / proj.name.addFileExt("babel")
var copyTo = babelDir / "packages" / proj.name.addFileExt("babel") # addFileExt fails in this situation. Although it's fine without .babel
stdout.write("Copying " & babelFile & " to " & copyTo & "...") var copyTo = babelDir / "packages" /
copyFile(babelFile, copyTo) (proj.name & "-" & proj.version)
echo(" Done!") copyFileDebug(babelFile, copyTo)
proc upgrade(proj: TProject) =
## This proc moves the files in lib/package into lib/package/lastVersion
## It then copies the new version into lib/package.
var babelDir = getBabelDir()
# Find the config for the latest (currently installed) package version in
# packages/
var latestVersion = "0"
var path = ""
for kind, confPath in walkDir(babelDir / "packages"):
if kind == pcFile:
var file = confPath.extractFilename()
if file.startsWith(proj.name & "-"):
var ver = ""
# This will have a dot at the end, it doesn't cause trouble though.
discard file.parseToken(ver, digits + {'.'}, proj.name.len() + 1)
echo(ver)
if ver > latestVersion:
latestVersion = ver
path = confPath
assert(path != "")
if proj.library:
echo("Reading " & path & "...")
var latestConf = parseBabel(path)
var newVerDir = babelDir / "lib" / latestConf.name / latestConf.version
createDirDebug(newVerDir)
# Move the files
for kind, path in walkDir(babelDir / "lib" / latestConf.name):
if kind == pcFile:
moveFileDebug(path, newVerDir / path.extractFilename())
# Install the new version
copyFiles(proj)
proc install*(name: string, filename: string = "") = proc install*(name: string, filename: string = "") =
## Install package by the name of ``name``, filename specifies where to look for it ## Install package by the name of ``name``, filename specifies where to look for it
@ -151,12 +201,13 @@ proc install*(name: string, filename: string = "") =
if ret != "": if ret != "":
raise newException(EInstall, "Verifying the .babel file failed: " & ret) raise newException(EInstall, "Verifying the .babel file failed: " & ret)
var upgrade = False # Specifies whether to upgrade
# Check whether this package is already installed # Check whether this package is already installed
# TODO: Different versions if dependExists(babelFile.name, newVREq(babelFile.version)):
# TODO: Commented for testing -- Uncomment. raise newException(EInstall,
#if dependExists(babelFile.name, newVRAny()): "This package is already installed!")
# raise newException(EInstall, elif dependExists(babelFile.name, newVREarlier(babelFile.version)):
# "This package is already installed: TODO: different versions.") upgrade = True
if babelFile.depends.len == 1: if babelFile.depends.len == 1:
echo("Verifying 1 dependency...") echo("Verifying 1 dependency...")
@ -168,8 +219,13 @@ proc install*(name: string, filename: string = "") =
else: else:
echo("All dependencies verified!") echo("All dependencies verified!")
echo("Installing " & babelFile.name & "...") if not upgrade:
echo("Installing " & babelFile.name & "-" & babelFile.version & "...")
babelFile.copyFiles() babelFile.copyFiles()
else:
echo("Upgrading " & babelFile.name & " to version " &
babelFile.version & "...")
babelFile.upgrade()
echo("Package " & babelFile.name & " successfully installed.") echo("Package " & babelFile.name & " successfully installed.")

View file

@ -9,12 +9,13 @@ type
verEqLater, # >= V -- Equal or later verEqLater, # >= V -- Equal or later
verEqEarlier, # <= V -- Equal or earlier verEqEarlier, # <= V -- Equal or earlier
verIntersect, # > V & < V verIntersect, # > V & < V
verEq, # V
verAny # * verAny # *
PVersionRange* = ref TVersionRange PVersionRange* = ref TVersionRange
TVersionRange* = object TVersionRange* = object
case kind*: TVersionRangeEnum case kind*: TVersionRangeEnum
of verLater, verEarlier, verEqLater, verEqEarlier: of verLater, verEarlier, verEqLater, verEqEarlier, verEq:
ver*: TVersion ver*: TVersion
of verIntersect: of verIntersect:
verILeft, verIRight: PVersionRange verILeft, verIRight: PVersionRange
@ -60,6 +61,8 @@ proc withinRange*(ver: TVersion, ran: PVersionRange): Bool =
return ver >= ran.ver return ver >= ran.ver
of verEqEarlier: of verEqEarlier:
return ver <= ran.ver return ver <= ran.ver
of verEq:
return ver == ran.ver
of verIntersect: of verIntersect:
return withinRange(ver, ran.verILeft) and withinRange(ver, ran.verIRight) return withinRange(ver, ran.verILeft) and withinRange(ver, ran.verIRight)
of verAny: of verAny:
@ -131,6 +134,8 @@ proc `$`*(verRange: PVersionRange): String =
result = ">= " result = ">= "
of verEqEarlier: of verEqEarlier:
result = "<= " result = "<= "
of verEq:
result = ""
of verIntersect: of verIntersect:
result = $verRange.verILeft & " & " & $verRange.verIRight result = $verRange.verILeft & " & " & $verRange.verIRight
of verAny: of verAny:
@ -142,6 +147,16 @@ proc newVRAny*(): PVersionRange =
new(result) new(result)
result.kind = verAny result.kind = verAny
proc newVREarlier*(ver: String): PVersionRange =
new(result)
result.kind = verEarlier
result.ver = newVersion(ver)
proc newVREq*(ver: string): PVersionRange =
new(result)
result.kind = verEq
result.ver = newVersion(ver)
when isMainModule: when isMainModule:
assert(newVersion("1.0") < newVersion("1.4")) assert(newVersion("1.0") < newVersion("1.4"))
assert(newVersion("1.0.1") > newVersion("1.0")) assert(newVersion("1.0.1") > newVersion("1.0"))