diff --git a/source/dub/commandline.d b/source/dub/commandline.d index 4af0457..0aa07b3 100644 --- a/source/dub/commandline.d +++ b/source/dub/commandline.d @@ -1242,6 +1242,10 @@ auto location = dub.defaultPlacementLocation; size_t resolveVersion(in Package[] packages) { + // just remove only package version + if (packages.length == 1) + return 0; + writeln("Select version of '", package_id, "' to remove from location '", location, "':"); foreach (i, pack; packages) writefln("%s) %s", i + 1, pack.version_); @@ -1251,19 +1255,23 @@ auto inp = readln(); if (!inp.length) // Ctrl+D return size_t.max; - if (inp.length > 1) { - try { - immutable selection = inp[0 .. $ - 1].to!size_t - 1; - if (selection <= packages.length) - return selection; - } catch (ConvException e) { - } - logError("Please enter a number between 1 and %s.", packages.length + 1); + inp = inp.stripRight; + if (!inp.length) // newline or space + continue; + try { + immutable selection = inp.to!size_t - 1; + if (selection <= packages.length) + return selection; + } catch (ConvException e) { } + logError("Please enter a number between 1 and %s.", packages.length + 1); } } - dub.remove(package_id, m_version, location, m_forceRemove, m_nonInteractive ? null : &resolveVersion); + if (m_nonInteractive || !m_version.empty) + dub.remove(package_id, m_version, location, m_forceRemove); + else + dub.remove(package_id, location, m_forceRemove, &resolveVersion); return 0; } } diff --git a/source/dub/dub.d b/source/dub/dub.d index 2d46817..22c52a3 100644 --- a/source/dub/dub.d +++ b/source/dub/dub.d @@ -730,18 +730,14 @@ Params: package_id = Name of the package to be removed - version_ = Identifying a version or a wild card. If an empty string - is passed, the package will be removed from the location, if - there is only one version retrieved. This will throw an - exception, if there are multiple versions retrieved. location_ = Specifies the location to look for the given package name/version. force_remove = Forces removal of the package, even if untracked files are found in its folder. - resolveVersion = Callback to select package version. + resolve_version = Callback to select package version. */ - void remove(string package_id, string version_, PlacementLocation location, bool force_remove, - scope size_t delegate(in Package[] packages) resolveVersion=null) + void remove(string package_id, PlacementLocation location, bool force_remove, + scope size_t delegate(in Package[] packages) resolve_version) { enforce(!package_id.empty); if (location == PlacementLocation.local) { @@ -751,36 +747,24 @@ } Package[] packages; - const bool wildcardOrEmpty = version_ == RemoveVersionWildcard || version_.empty; // Retrieve packages to be removed. foreach(pack; m_packageManager.getPackageIterator(package_id)) - if ((wildcardOrEmpty || pack.version_ == Version(version_)) && m_packageManager.isManagedPackage(pack)) + if (m_packageManager.isManagedPackage(pack)) packages ~= pack; // Check validity of packages to be removed. if(packages.empty) { throw new Exception("Cannot find package to remove. (" - ~ "id: '" ~ package_id ~ "', version: '" ~ version_ ~ "', location: '" ~ to!string(location) ~ "'" + ~ "id: '" ~ package_id ~ "', location: '" ~ to!string(location) ~ "'" ~ ")"); } - if(version_.empty && packages.length > 1) { - if (resolveVersion is null) { - logError("Cannot remove package '" ~ package_id ~ "', there are multiple possibilities at location\n" - ~ "'" ~ to!string(location) ~ "'."); - logError("Available versions:"); - foreach(pack; packages) - logError(" %s", pack.version_); - throw new Exception("Please specify a individual version using --version=... or use the" - ~ " wildcard --version=" ~ RemoveVersionWildcard ~ " to remove all versions."); - } else { - immutable idx = resolveVersion(packages); - if (idx == size_t.max) - return; - else if (idx != packages.length) - packages = packages[idx .. idx + 1]; - } - } + + immutable idx = resolve_version(packages); + if (idx == size_t.max) + return; + else if (idx != packages.length) + packages = packages[idx .. idx + 1]; logDebug("Removing %s packages.", packages.length); foreach(pack; packages) { @@ -794,6 +778,43 @@ } } + /** Removes a specific version of a package. + + Params: + package_id = Name of the package to be removed + version_ = Identifying a version or a wild card. If an empty string + is passed, the package will be removed from the location, if + there is only one version retrieved. This will throw an + exception, if there are multiple versions retrieved. + location_ = Specifies the location to look for the given package + name/version. + force_remove = Forces removal of the package, even if untracked + files are found in its folder. + */ + void remove(string package_id, string version_, PlacementLocation location, bool force_remove) + { + remove(package_id, location, force_remove, (in packages) { + if (version_ == RemoveVersionWildcard) + return packages.length; + if (version_.empty && packages.length > 1) { + logError("Cannot remove package '" ~ package_id ~ "', there are multiple possibilities at location\n" + ~ "'" ~ to!string(location) ~ "'."); + logError("Available versions:"); + foreach(pack; packages) + logError(" %s", pack.version_); + throw new Exception("Please specify a individual version using --version=... or use the" + ~ " wildcard --version=" ~ RemoveVersionWildcard ~ " to remove all versions."); + } + foreach (i, p; packages) { + if (p.version_ == Version(version_)) + return i; + } + throw new Exception("Cannot find package to remove. (" + ~ "id: '" ~ package_id ~ "', version: '" ~ version_ ~ "', location: '" ~ to!string(location) ~ "'" + ~ ")"); + }); + } + /** Adds a directory to the list of locally known packages. Forwards to `PackageManager.addLocalPackage`. diff --git a/test/interactive-remove.sh b/test/interactive-remove.sh index 69667b2..5c23bef 100755 --- a/test/interactive-remove.sh +++ b/test/interactive-remove.sh @@ -21,8 +21,16 @@ exit 1 fi # validates input -echo -e 'abc\n3\n-1\n2' | $DUB remove dub +echo -e 'abc\n4\n-1\n3' | $DUB remove dub if [ -d $HOME/.dub/packages/dub-0.9.20/dub ] || [ -d $HOME/.dub/packages/dub-0.9.21/dub ]; then echo "Failed to remove all version of dub" 1>&2 exit 1 fi +$DUB fetch dub --version=0.9.20 && [ -d $HOME/.dub/packages/dub-0.9.20/dub ] +$DUB fetch dub --version=0.9.21 && [ -d $HOME/.dub/packages/dub-0.9.21/dub ] +# is non-interactive with --version= +$DUB remove dub --version=\* +if [ -d $HOME/.dub/packages/dub-0.9.20/dub ] || [ -d $HOME/.dub/packages/dub-0.9.21/dub ]; then + echo 'Failed to non-interactively remove specified versions' 1>&2 + exit 1 +fi