|
1 | 1 | from conan.api.conan_api import ConanAPI
|
| 2 | +from conan.api.model import PackagesList, ListPattern |
2 | 3 | from conan.api.input import UserInput
|
3 | 4 | from conan.api.output import ConanOutput, Color
|
4 | 5 | from conan.cli.command import OnceArgument, conan_command
|
@@ -27,26 +28,30 @@ def confirmation(message):
|
27 | 28 | remote = conan_api.remotes.get(args.remote) if args.remote else None
|
28 | 29 | output_remote = remote or "Local cache"
|
29 | 30 |
|
30 |
| - # Getting all the recipes |
31 |
| - recipes = conan_api.search.recipes("*/*", remote=remote) |
32 |
| - if recipes and not confirmation("Do you want to remove all the recipes revisions and their packages ones, " |
| 31 | + # List all recipes revisions and all their packages revisions as well |
| 32 | + pkg_list = conan_api.list.select(ListPattern("*/*#*:*#*", rrev=None, prev=None), remote=remote) |
| 33 | + if pkg_list and not confirmation("Do you want to remove all the recipes revisions and their packages ones, " |
33 | 34 | "except the latest package revision from the latest recipe one?"):
|
| 35 | + out.writeln("Aborted") |
34 | 36 | return
|
35 |
| - for recipe in recipes: |
36 |
| - out.writeln(f"{str(recipe)}", fg=recipe_color) |
37 |
| - all_rrevs = conan_api.list.recipe_revisions(recipe, remote=remote) |
38 |
| - latest_rrev = all_rrevs[0] if all_rrevs else None |
39 |
| - for rrev in all_rrevs: |
40 |
| - if rrev != latest_rrev: |
41 |
| - conan_api.remove.recipe(rrev, remote=remote) |
42 |
| - out.writeln(f"Removed recipe revision: {rrev.repr_notime()} " |
43 |
| - f"and all its package revisions [{output_remote}]", fg=removed_color) |
| 37 | + |
| 38 | + # Split the package list into based on their recipe reference |
| 39 | + for sub_pkg_list in pkg_list.split(): |
| 40 | + latest = max(sub_pkg_list.items(), key=lambda item: item[0])[0] |
| 41 | + out.writeln(f"Keeping recipe revision: {latest.repr_notime()} " |
| 42 | + f"and its latest package revisions [{output_remote}]", fg=recipe_color) |
| 43 | + for rref, packages in sub_pkg_list.items(): |
| 44 | + # For the latest recipe revision, keep the latest package revision only |
| 45 | + if latest == rref: |
| 46 | + # Get the latest package timestamp for each package_id |
| 47 | + latest_pref_list = [max([p for p in packages if p.package_id == pkg_id], key=lambda p: p.timestamp) |
| 48 | + for pkg_id in {p.package_id for p in packages}] |
| 49 | + for pref in packages: |
| 50 | + if pref not in latest_pref_list: |
| 51 | + conan_api.remove.package(pref, remote=remote) |
| 52 | + out.writeln(f"Removed package revision: {pref.repr_notime()} [{output_remote}]", fg=removed_color) |
44 | 53 | else:
|
45 |
| - packages = conan_api.list.packages_configurations(rrev, remote=remote) |
46 |
| - for package_ref in packages: |
47 |
| - all_prevs = conan_api.list.package_revisions(package_ref, remote=remote) |
48 |
| - latest_prev = all_prevs[0] if all_prevs else None |
49 |
| - for prev in all_prevs: |
50 |
| - if prev != latest_prev: |
51 |
| - conan_api.remove.package(prev, remote=remote) |
52 |
| - out.writeln(f"Removed package revision: {prev.repr_notime()} [{output_remote}]", fg=removed_color) |
| 54 | + # Otherwise, remove all outdated recipe revisions and their packages |
| 55 | + conan_api.remove.recipe(rref, remote=remote) |
| 56 | + out.writeln(f"Removed recipe revision: {rref.repr_notime()} " |
| 57 | + f"and all its package revisions [{output_remote}]", fg=removed_color) |
0 commit comments