Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 26 additions & 20 deletions examples/extensions/commands/clean/cmd_clean.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from conan.api.conan_api import ConanAPI
from conan.api.model import PackagesList, ListPattern
from conan.api.input import UserInput
from conan.api.output import ConanOutput, Color
from conan.cli.command import OnceArgument, conan_command
Expand Down Expand Up @@ -27,26 +28,31 @@ def confirmation(message):
remote = conan_api.remotes.get(args.remote) if args.remote else None
output_remote = remote or "Local cache"

# Getting all the recipes
recipes = conan_api.search.recipes("*/*", remote=remote)
if recipes and not confirmation("Do you want to remove all the recipes revisions and their packages ones, "
# List all recipes revisions and all their packages revisions as well
pkg_list = conan_api.list.select(ListPattern("*/*#*:*#*", rrev=None, prev=None), remote=remote)
if pkg_list and not confirmation("Do you want to remove all the recipes revisions and their packages ones, "
"except the latest package revision from the latest recipe one?"):
out.writeln("Aborted")
return
for recipe in recipes:
out.writeln(f"{str(recipe)}", fg=recipe_color)
all_rrevs = conan_api.list.recipe_revisions(recipe, remote=remote)
latest_rrev = all_rrevs[0] if all_rrevs else None
for rrev in all_rrevs:
if rrev != latest_rrev:
conan_api.remove.recipe(rrev, remote=remote)
out.writeln(f"Removed recipe revision: {rrev.repr_notime()} "
f"and all its package revisions [{output_remote}]", fg=removed_color)

# Split the package list into recipe bundles based on their recipe reference
for ref_bundle in pkg_list.split():
latest = max(ref_bundle.refs(), key=lambda r: r.revision)
out.writeln(f"Keeping recipe revision: {latest.repr_notime()} "
f"and its latest package revisions [{output_remote}]", fg=recipe_color)
for pkg_ref, pkg_bundle in ref_bundle.refs().items():
# For the latest recipe revision, keep the latest package revision only
if latest == pkg_ref:
prefs = PackagesList.prefs(latest, pkg_bundle)
if prefs:
latest_pref = max(prefs.keys(), key=lambda p: p.revision)
out.writeln(f"Keeping package revision: {latest_pref.repr_notime()} [{output_remote}]", fg=recipe_color)
for pref in prefs.keys():
if latest_pref != pref:
conan_api.remove.package(pref, remote=remote)
out.writeln(f"Removed package revision: {pref.repr_notime()} [{output_remote}]", fg=removed_color)
else:
packages = conan_api.list.packages_configurations(rrev, remote=remote)
for package_ref in packages:
all_prevs = conan_api.list.package_revisions(package_ref, remote=remote)
latest_prev = all_prevs[0] if all_prevs else None
for prev in all_prevs:
if prev != latest_prev:
conan_api.remove.package(prev, remote=remote)
out.writeln(f"Removed package revision: {prev.repr_notime()} [{output_remote}]", fg=removed_color)
# Otherwise, remove all outdated recipe revisions and their packages
conan_api.remove.recipe(pkg_ref, remote=remote)
out.writeln(f"Removed recipe revision: {pkg_ref.repr_notime()} "
f"and all its package revisions [{output_remote}]", fg=removed_color)