Skip to content

Commit

Permalink
Fix 'conan remove': output only confirmed entries (#14478)
Browse files Browse the repository at this point in the history
* output only confirmed entries

* wip

---------

Co-authored-by: memsharded <james@conan.io>
  • Loading branch information
Tobulus and memsharded authored Aug 28, 2023
1 parent 613478e commit 5e2b861
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 9 deletions.
29 changes: 25 additions & 4 deletions conan/cli/commands/remove.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,15 @@ def remove(conan_api: ConanAPI, parser, *args):

ui = UserInput(conan_api.config.get("core:non_interactive"))
remote = conan_api.remotes.get(args.remote) if args.remote else None
cache_name = "Local Cache" if not remote else remote.name

def confirmation(message):
return args.confirm or ui.request_boolean(message)

if args.list:
listfile = make_abs_path(args.list)
multi_package_list = MultiPackagesList.load(listfile)
package_list = multi_package_list["Local Cache" if not remote else remote.name]
package_list = multi_package_list[cache_name]
refs_to_remove = package_list.refs()
if not refs_to_remove: # the package list might contain only refs, no revs
ConanOutput().warning("Nothing to remove, package list do not contain recipe revisions")
Expand All @@ -79,16 +80,36 @@ def confirmation(message):
raise ConanException('--package-query supplied but the pattern does not match packages')
package_list = conan_api.list.select(ref_pattern, args.package_query, remote)
multi_package_list = MultiPackagesList()
multi_package_list.add("Local Cache" if not remote else remote.name, package_list)
multi_package_list.add(cache_name, package_list)

# TODO: This iteration and removal of not-confirmed is ugly and complicated, improve it
for ref, ref_bundle in package_list.refs().items():
if ref_bundle.get("packages") is None:
ref_dict = package_list.recipes[str(ref)]["revisions"]
packages = ref_bundle.get("packages")
if packages is None:
if confirmation(f"Remove the recipe and all the packages of '{ref.repr_notime()}'?"):
conan_api.remove.recipe(ref, remote=remote)
else:
ref_dict.pop(ref.revision)
if not ref_dict:
package_list.recipes.pop(str(ref))
continue
for pref, _ in package_list.prefs(ref, ref_bundle).items():
prefs = package_list.prefs(ref, ref_bundle)
if not prefs:
ConanOutput().info(f"No binaries to remove for '{ref.repr_notime()}'")
ref_dict.pop(ref.revision)
if not ref_dict:
package_list.recipes.pop(str(ref))
continue

for pref, _ in prefs.items():
if confirmation(f"Remove the package '{pref.repr_notime()}'?"):
conan_api.remove.package(pref, remote=remote)
else:
pref_dict = packages[pref.package_id]["revisions"]
pref_dict.pop(pref.revision)
if not pref_dict:
packages.pop(pref.package_id)

return {
"results": multi_package_list.serialize(),
Expand Down
20 changes: 15 additions & 5 deletions conans/test/integration/command_v2/test_combined_pkglist_flows.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,16 +231,26 @@ def test_remove_all(self, client, remote):
assert "There are no matching recipe references" in client.out

@pytest.mark.parametrize("remote", [False, True])
def test_remove_packages(self, client, remote):
def test_remove_packages_no_revisions(self, client, remote):
# It is necessary to do *#* for actually removing something
remote = "-r=default" if remote else ""
client.run(f"list *#*:* {remote} --format=json", redirect_stdout="pkglist.json")
client.run(f"remove --list=pkglist.json {remote} -c")
assert "No binaries to remove for 'zli/1.0.0#f034dc90894493961d92dd32a9ee3b78'" in client.out
assert "No binaries to remove for 'zlib/1.0.0@user/channel" \
"#ffd4bc45820ddb320ab224685b9ba3fb" in client.out

@pytest.mark.parametrize("remote", [False, True])
def test_remove_packages(self, client, remote):
# It is necessary to do *#* for actually removing something
remote = "-r=default" if remote else ""
client.run(f"list *#*:*#* {remote} --format=json", redirect_stdout="pkglist.json")
client.run(f"remove --list=pkglist.json {remote} -c")

assert "Removed recipe and all binaries" not in client.out
assert "zli/1.0.0#f034dc90894493961d92dd32a9ee3b78:" \
" Removed binaries" in client.out
assert "zlib/1.0.0@user/channel#ffd4bc45820ddb320ab224685b9ba3fb:" \
" Removed binaries" in client.out
assert "zli/1.0.0#f034dc90894493961d92dd32a9ee3b78: Removed binaries" in client.out
assert "zlib/1.0.0@user/channel#ffd4bc45820ddb320ab224685b9ba3fb: " \
"Removed binaries" in client.out
client.run(f"list *:* {remote}")
assert "zli/1.0.0" in client.out
assert "zlib/1.0.0@user/channel" in client.out

0 comments on commit 5e2b861

Please sign in to comment.