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:
parent
4bbaece157
commit
417fdc074d
2 changed files with 101 additions and 30 deletions
112
installer.nim
112
installer.nim
|
|
@ -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.")
|
||||||
|
|
||||||
|
|
|
||||||
17
version.nim
17
version.nim
|
|
@ -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"))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue