Fixes more problems with the uninstall feature.

This commit is contained in:
Dominik Picheta 2014-06-22 20:41:13 +01:00
commit 35fef81b66
3 changed files with 82 additions and 38 deletions

View file

@ -325,6 +325,18 @@ proc removeRevDep(options: TOptions, pkg: TPackageInfo) =
if thisDep.isNil: continue if thisDep.isNil: continue
options.remove(pkg, depTup, thisDep) options.remove(pkg, depTup, thisDep)
# Clean up empty objects/arrays
var newData = newJObject()
for key, val in options.babelData["reverseDeps"]:
if val.len != 0:
var newVal = newJObject()
for ver, elem in val:
if elem.len != 0:
newVal[ver] = elem
if newVal.len != 0:
newData[key] = newVal
options.babelData["reverseDeps"] = newData
writeFile(options.getBabelDir() / "babeldata.json", pretty(options.babelData)) writeFile(options.getBabelDir() / "babeldata.json", pretty(options.babelData))
proc install(packages: seq[tuple[name: string, verRange: PVersionRange]], proc install(packages: seq[tuple[name: string, verRange: PVersionRange]],
@ -641,34 +653,37 @@ proc uninstall(options: TOptions) =
# Do some verification. # Do some verification.
for pkgTup in options.action.packages: for pkgTup in options.action.packages:
echo("Looking for ", pkgTup.name, " (", $pkgTup.ver, ")...") echo("Looking for ", pkgTup.name, " (", $pkgTup.ver, ")...")
let pkgList = getInstalledPkgs(options.getPkgsDir()) let installedPkgs = getInstalledPkgs(options.getPkgsDir())
var pkg: TPackageInfo var pkgList = findAllPkgs(installedPkgs, pkgTup)
if not findPkg(pkglist, pkgTup, pkg): if pkgList.len == 0:
raise newException(EBabel, "Package not found") raise newException(EBabel, "Package not found")
echo("Checking reverse dependencies...") echo("Checking reverse dependencies...")
# Check whether any packages depend on the one the user is trying to uninstall var errors: seq[string] = @[]
let thisDep = options.babelData["reverseDeps"][pkgTup.name] for pkg in pkgList:
if not thisDep.isNil: # Check whether any packages depend on the ones the user is trying to
for ver, val in thisDep.pairs: # uninstall.
if ver.newVersion in pkgTup.ver and val.len != 0: let thisPkgsDep = options.babelData["reverseDeps"]{pkg.name}{pkg.version}
assert val.kind == JArray if not thisPkgsDep.isNil:
var reason = "" var reason = ""
if val.len == 1: if thisPkgsDep.len == 1:
reason = val[0]["name"].str & " (" & val[0]["version"].str & reason = thisPkgsDep[0]["name"].str &
") depends on it" " (" & thisPkgsDep[0]["version"].str & ") depends on it"
else: else:
for i in 0 .. <val.len: for i in 0 .. <thisPkgsDep.len:
reason.add val[i]["name"].str & " (" & val[i]["version"].str & ")" reason.add thisPkgsDep[i]["name"].str &
if i != <val.len: " (" & thisPkgsDep[i]["version"].str & ")"
if i != <thisPkgsDep.len:
reason.add ", " reason.add ", "
reason.add " depend on it" reason.add " depend on it"
errors.add("Cannot uninstall " & pkgTup.name & " (" & pkg.version &
raise newException(EBabel, "Cannot uninstall " & pkgTup.name & ")" & " because " & reason)
" because " & reason) else:
pkgsToDelete.add pkg pkgsToDelete.add pkg
if pkgsToDelete.len == 0:
raise newException(EBabel, "\n " & errors.join("\n "))
var pkgNames = "" var pkgNames = ""
for i in 0 .. <pkgsToDelete.len: for i in 0 .. <pkgsToDelete.len:
if i != 0: pkgNames.add ", " if i != 0: pkgNames.add ", "

View file

@ -293,6 +293,17 @@ proc findPkg*(pkglist: seq[tuple[pkginfo: TPackageInfo, meta: TMetaData]],
r = pkg.pkginfo r = pkg.pkginfo
result = true result = true
proc findAllPkgs*(pkglist: seq[tuple[pkginfo: TPackageInfo, meta: TMetaData]],
dep: TPkgTuple): seq[TPackageInfo] =
## Searches ``pkglist`` for packages of which version is within the range
## of ``dep.ver``. This is similar to ``findPkg`` but returns multiple
## packages if multiple are found.
result = @[]
for pkg in pkglist:
if pkg.pkginfo.name != dep.name and pkg.meta.url != dep.name: continue
if withinRange(newVersion(pkg.pkginfo.version), dep.ver):
result.add pkg.pkginfo
proc getRealDir*(pkgInfo: TPackageInfo): string = proc getRealDir*(pkgInfo: TPackageInfo): string =
## Returns the ``pkgInfo.srcDir`` or the .mypath directory if package does ## Returns the ``pkgInfo.srcDir`` or the .mypath directory if package does
## not specify the src dir. ## not specify the src dir.

View file

@ -1,10 +1,11 @@
# 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 osproc, unittest, strutils, os import osproc, unittest, strutils, os, sequtils, future
const path = "../src/babel" const path = "../src/babel"
discard execCmdEx("nimrod c " & path) test "can compile babel":
check execCmdEx("nimrod c " & path).exitCode == QuitSuccess
template cd*(dir: string, body: stmt) = template cd*(dir: string, body: stmt) =
## Sets the current dir to ``dir``, executes ``body`` and restores the ## Sets the current dir to ``dir``, executes ``body`` and restores the
@ -14,10 +15,13 @@ template cd*(dir: string, body: stmt) =
body body
setCurrentDir(lastDir) setCurrentDir(lastDir)
proc processOutput(output: string): seq[string] =
output.strip.splitLines().filter((x: string) => (x.len > 0))
test "can install packagebin2": test "can install packagebin2":
let (outp, exitCode) = execCmdEx(path & check execCmdEx(path &
" install -y https://github.com/babel-test/packagebin2.git") " install -y https://github.com/babel-test/packagebin2.git").exitCode ==
check exitCode == QuitSuccess QuitSuccess
test "can reject same version dependencies": test "can reject same version dependencies":
let (outp, exitCode) = execCmdEx(path & let (outp, exitCode) = execCmdEx(path &
@ -30,8 +34,7 @@ test "can reject same version dependencies":
"dependency on PackageA 0.2.0 and PackageA 0.5.0 [EBabel]" "dependency on PackageA 0.2.0 and PackageA 0.5.0 [EBabel]"
test "can update": test "can update":
let (outp, exitCode) = execCmdEx(path & " update") check execCmdEx(path & " update").exitCode == QuitSuccess
check exitCode == QuitSuccess
test "issue #27": test "issue #27":
# Install b # Install b
@ -46,12 +49,27 @@ test "issue #27":
check execCmdEx("../" & path & " install -y").exitCode == QuitSuccess check execCmdEx("../" & path & " install -y").exitCode == QuitSuccess
test "can uninstall": test "can uninstall":
block:
let (outp, exitCode) = execCmdEx(path & " uninstall -y issue27b") let (outp, exitCode) = execCmdEx(path & " uninstall -y issue27b")
let ls = outp.strip.splitLines() let ls = outp.processOutput()
check exitCode != QuitSuccess check exitCode != QuitSuccess
check ls[ls.len-1] == "Error: unhandled exception: Cannot uninstall issue27b" & check ls[ls.len-1] == " Cannot uninstall issue27b (0.1.0) because " &
" because issue27a (0.1.0) depends on it [EBabel]" "issue27a (0.1.0) depends on it [EBabel]"
check execCmdEx(path & " uninstall -y issue27").exitCode == QuitSuccess check execCmdEx(path & " uninstall -y issue27").exitCode == QuitSuccess
check execCmdEx(path & " uninstall -y issue27a").exitCode == QuitSuccess check execCmdEx(path & " uninstall -y issue27a").exitCode == QuitSuccess
check execCmdEx(path & " uninstall -y issue27b").exitCode == QuitSuccess check execCmdEx(path & " uninstall -y issue27b").exitCode == QuitSuccess
# Remove Package*
let (outp, exitCode) = execCmdEx(path & " uninstall -y PackageA")
check exitCode != QuitSuccess
let ls = outp.processOutput()
check ls[ls.len-3].startsWith(" Cannot uninstall PackageA ")
check ls[ls.len-2].startsWith(" Cannot uninstall PackageA ")
check ls[ls.len-1].startsWith(" Cannot uninstall PackageA ")
check execCmdEx(path & " uninstall -y PackageBin2").exitCode == QuitSuccess
# Case insensitive
check execCmdEx(path & " uninstall -y packagea").exitCode == QuitSuccess
check execCmdEx(path & " uninstall -y PackageA").exitCode != QuitSuccess