Allow removal of reverse dependencies with uninstall --deps flag (#601)

* Fix for #398

* Updated fix for #398

* Enable uninstall of reverse deps

* Update README

* Updates based on feedback
This commit is contained in:
genotrance 2019-01-08 13:58:19 -06:00 • committed by Dominik Picheta
commit 88f5545c75
6 changed files with 70 additions and 21 deletions

View file

@ -221,8 +221,8 @@ instead of a name.
### nimble uninstall ### nimble uninstall
The ``uninstall`` command will remove an installed package. Attempting to remove The ``uninstall`` command will remove an installed package. Attempting to remove
a package which other packages depend on is disallowed and will result in an a package which other packages depend on will result in an error. You can use the
error. You must currently manually remove the reverse dependencies first. ``--inclDeps`` or ``-i`` flag to remove all dependent packages along with the package.
Similar to the ``install`` command you can specify a version range, for example: Similar to the ``install`` command you can specify a version range, for example:

View file

@ -846,6 +846,9 @@ proc uninstall(options: Options) =
for pkg in pkgList: for pkg in pkgList:
# Check whether any packages depend on the ones the user is trying to # Check whether any packages depend on the ones the user is trying to
# uninstall. # uninstall.
if options.uninstallRevDeps:
getAllRevDeps(options, pkg, pkgsToDelete)
else:
let revDeps = getRevDeps(options, pkg) let revDeps = getRevDeps(options, pkg)
var reason = "" var reason = ""
if revDeps.len == 1: if revDeps.len == 1:

View file

@ -10,6 +10,7 @@ type
Options* = object Options* = object
forcePrompts*: ForcePrompt forcePrompts*: ForcePrompt
depsOnly*: bool depsOnly*: bool
uninstallRevDeps*: bool
queryVersions*: bool queryVersions*: bool
queryInstalled*: bool queryInstalled*: bool
nimbleDir*: string nimbleDir*: string
@ -71,6 +72,7 @@ Commands:
The current working directory needs to be the The current working directory needs to be the
toplevel directory of the Nimble package. toplevel directory of the Nimble package.
uninstall [pkgname, ...] Uninstalls a list of packages. uninstall [pkgname, ...] Uninstalls a list of packages.
[-i, --inclDeps] Uninstall package and dependent package(s).
build Builds a package. build Builds a package.
c, cc, js [opts, ...] f.nim Builds a file inside a package. Passes options c, cc, js [opts, ...] f.nim Builds a file inside a package. Passes options
to the Nim compiler. to the Nim compiler.
@ -301,6 +303,12 @@ proc parseFlag*(flag, val: string, result: var Options, kind = cmdLongOption) =
result.depsOnly = true result.depsOnly = true
else: else:
wasFlagHandled = false wasFlagHandled = false
of actionUninstall:
case f
of "incldeps", "i":
result.uninstallRevDeps = true
else:
wasFlagHandled = false
of actionCompile, actionDoc, actionBuild: of actionCompile, actionDoc, actionBuild:
let prefix = if kind == cmdShortOption: "-" else: "--" let prefix = if kind == cmdShortOption: "-" else: "--"
if val == "": if val == "":

View file

@ -538,6 +538,10 @@ proc getPkgDest*(pkgInfo: PackageInfo, options: Options): string =
let pkgDestDir = options.getPkgsDir() / (pkgInfo.name & versionStr) let pkgDestDir = options.getPkgsDir() / (pkgInfo.name & versionStr)
return pkgDestDir return pkgDestDir
proc `==`*(pkg1: PackageInfo, pkg2: PackageInfo): bool =
if pkg1.name == pkg2.name and pkg1.myPath == pkg2.myPath:
return true
when isMainModule: when isMainModule:
doAssert getNameVersion("/home/user/.nimble/libs/packagea-0.1") == doAssert getNameVersion("/home/user/.nimble/libs/packagea-0.1") ==
("packagea", "0.1") ("packagea", "0.1")

View file

@ -76,6 +76,19 @@ proc getRevDeps*(options: Options, pkg: PackageInfo): seq[PkgTuple] =
result.add(pkgTup) result.add(pkgTup)
proc getAllRevDeps*(options: Options, pkg: PackageInfo, result: var seq[PackageInfo]) =
if pkg in result:
return
let installedPkgs = getInstalledPkgsMin(options.getPkgsDir(), options)
for rdepTup in getRevDeps(options, pkg):
for rdepInfo in findAllPkgs(installedPkgs, rdepTup):
if rdepInfo in result:
continue
getAllRevDeps(options, rdepInfo, result)
result.add pkg
when isMainModule: when isMainModule:
var nimbleData = %{"reverseDeps": newJObject()} var nimbleData = %{"reverseDeps": newJObject()}

View file

@ -568,6 +568,27 @@ suite "reverse dependencies":
verify execNimbleYes("remove", "pkgA") verify execNimbleYes("remove", "pkgA")
verify execNimbleYes("remove", "mydep") verify execNimbleYes("remove", "mydep")
test "revdep fail test":
cd "revdep/mydep":
verify execNimbleYes("install")
cd "revdep/pkgWithDep":
verify execNimbleYes("install")
let (output, exitCode) = execNimble("uninstall", "mydep")
checkpoint output
check output.processOutput.inLines("cannot uninstall mydep")
check exitCode == QuitFailure
test "revdep -i test":
cd "revdep/mydep":
verify execNimbleYes("install")
cd "revdep/pkgWithDep":
verify execNimbleYes("install")
verify execNimbleYes("remove", "mydep", "-i")
test "issue #373": test "issue #373":
cd "revdep/mydep": cd "revdep/mydep":
verify execNimbleYes("install") verify execNimbleYes("install")