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:
parent
68bb97f30a
commit
88f5545c75
6 changed files with 70 additions and 21 deletions
|
|
@ -221,8 +221,8 @@ instead of a name.
|
|||
### nimble uninstall
|
||||
|
||||
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
|
||||
error. You must currently manually remove the reverse dependencies first.
|
||||
a package which other packages depend on will result in an error. You can use the
|
||||
``--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:
|
||||
|
||||
|
|
@ -749,16 +749,16 @@ to ensure that the dependencies you specified are correct.
|
|||
### Compile with `nim` after changing the nimble directory
|
||||
|
||||
The Nim compiler has been preconfigured to look at the default nimble directory while compiling,
|
||||
so no extra step is required to use nimble managed packages in your code.
|
||||
However, if you are using a custom `nimbleDir`, you need to specify the
|
||||
so no extra step is required to use nimble managed packages in your code.
|
||||
However, if you are using a custom `nimbleDir`, you need to specify the
|
||||
`--nimblePath:PATH` option. For example,
|
||||
if your `nimble` directory is located at `/some/custom/path/nimble`, this should work:
|
||||
|
||||
```
|
||||
nim c --nimblePath:/some/custom/path/nimble/pkgs main.nim
|
||||
```
|
||||
```
|
||||
|
||||
Some code editors rely on `nim check` to check for errors under the hood (e.g. VScode),
|
||||
Some code editors rely on `nim check` to check for errors under the hood (e.g. VScode),
|
||||
and the editor extension may not allow users to pass custom option to `nim check`, which
|
||||
will cause `nim check` to scream `Error: cannot open file:<the_package>`. In this case,
|
||||
you will have to use [Nim compiler's configuration files](https://nim-lang.org/docs/nimc.html#compiler-usage-configuration-files). Simply add the line:
|
||||
|
|
|
|||
|
|
@ -846,22 +846,25 @@ proc uninstall(options: Options) =
|
|||
for pkg in pkgList:
|
||||
# Check whether any packages depend on the ones the user is trying to
|
||||
# uninstall.
|
||||
let revDeps = getRevDeps(options, pkg)
|
||||
var reason = ""
|
||||
if revDeps.len == 1:
|
||||
reason = "$1 ($2) depends on it" % [revDeps[0].name, $revDeps[0].ver]
|
||||
if options.uninstallRevDeps:
|
||||
getAllRevDeps(options, pkg, pkgsToDelete)
|
||||
else:
|
||||
for i in 0 ..< revDeps.len:
|
||||
reason.add("$1 ($2)" % [revDeps[i].name, $revDeps[i].ver])
|
||||
if i != revDeps.len-1:
|
||||
reason.add ", "
|
||||
reason.add " depend on it"
|
||||
let revDeps = getRevDeps(options, pkg)
|
||||
var reason = ""
|
||||
if revDeps.len == 1:
|
||||
reason = "$1 ($2) depends on it" % [revDeps[0].name, $revDeps[0].ver]
|
||||
else:
|
||||
for i in 0 ..< revDeps.len:
|
||||
reason.add("$1 ($2)" % [revDeps[i].name, $revDeps[i].ver])
|
||||
if i != revDeps.len-1:
|
||||
reason.add ", "
|
||||
reason.add " depend on it"
|
||||
|
||||
if revDeps.len > 0:
|
||||
errors.add("Cannot uninstall $1 ($2) because $3" %
|
||||
[pkgTup.name, pkg.specialVersion, reason])
|
||||
else:
|
||||
pkgsToDelete.add pkg
|
||||
if revDeps.len > 0:
|
||||
errors.add("Cannot uninstall $1 ($2) because $3" %
|
||||
[pkgTup.name, pkg.specialVersion, reason])
|
||||
else:
|
||||
pkgsToDelete.add pkg
|
||||
|
||||
if pkgsToDelete.len == 0:
|
||||
raise newException(NimbleError, "\n " & errors.join("\n "))
|
||||
|
|
@ -1007,7 +1010,7 @@ proc test(options: Options) =
|
|||
existsBefore = existsFile(binFileName)
|
||||
|
||||
execBackend(optsCopy)
|
||||
|
||||
|
||||
let
|
||||
existsAfter = existsFile(binFileName)
|
||||
canRemove = not existsBefore and existsAfter
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ type
|
|||
Options* = object
|
||||
forcePrompts*: ForcePrompt
|
||||
depsOnly*: bool
|
||||
uninstallRevDeps*: bool
|
||||
queryVersions*: bool
|
||||
queryInstalled*: bool
|
||||
nimbleDir*: string
|
||||
|
|
@ -71,6 +72,7 @@ Commands:
|
|||
The current working directory needs to be the
|
||||
toplevel directory of the Nimble package.
|
||||
uninstall [pkgname, ...] Uninstalls a list of packages.
|
||||
[-i, --inclDeps] Uninstall package and dependent package(s).
|
||||
build Builds a package.
|
||||
c, cc, js [opts, ...] f.nim Builds a file inside a package. Passes options
|
||||
to the Nim compiler.
|
||||
|
|
@ -301,6 +303,12 @@ proc parseFlag*(flag, val: string, result: var Options, kind = cmdLongOption) =
|
|||
result.depsOnly = true
|
||||
else:
|
||||
wasFlagHandled = false
|
||||
of actionUninstall:
|
||||
case f
|
||||
of "incldeps", "i":
|
||||
result.uninstallRevDeps = true
|
||||
else:
|
||||
wasFlagHandled = false
|
||||
of actionCompile, actionDoc, actionBuild:
|
||||
let prefix = if kind == cmdShortOption: "-" else: "--"
|
||||
if val == "":
|
||||
|
|
|
|||
|
|
@ -538,6 +538,10 @@ proc getPkgDest*(pkgInfo: PackageInfo, options: Options): string =
|
|||
let pkgDestDir = options.getPkgsDir() / (pkgInfo.name & versionStr)
|
||||
return pkgDestDir
|
||||
|
||||
proc `==`*(pkg1: PackageInfo, pkg2: PackageInfo): bool =
|
||||
if pkg1.name == pkg2.name and pkg1.myPath == pkg2.myPath:
|
||||
return true
|
||||
|
||||
when isMainModule:
|
||||
doAssert getNameVersion("/home/user/.nimble/libs/packagea-0.1") ==
|
||||
("packagea", "0.1")
|
||||
|
|
|
|||
|
|
@ -76,6 +76,19 @@ proc getRevDeps*(options: Options, pkg: PackageInfo): seq[PkgTuple] =
|
|||
|
||||
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:
|
||||
var nimbleData = %{"reverseDeps": newJObject()}
|
||||
|
||||
|
|
|
|||
|
|
@ -568,6 +568,27 @@ suite "reverse dependencies":
|
|||
verify execNimbleYes("remove", "pkgA")
|
||||
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":
|
||||
cd "revdep/mydep":
|
||||
verify execNimbleYes("install")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue