Skip to content

Commit 2357410

Browse files
authored
[hotfix] Extension example for clean could not import Conan API search (#193)
* Trigger CI Signed-off-by: Uilian Ries <[email protected]> * Align with Conan develop2 Signed-off-by: Uilian Ries <[email protected]> * Create Conan app Signed-off-by: Uilian Ries <[email protected]> * Fix bad definition Signed-off-by: Uilian Ries <[email protected]> * Use Conan list API properly Signed-off-by: Uilian Ries <[email protected]> * Simplify query Signed-off-by: Uilian Ries <[email protected]> * Use a single select Signed-off-by: Uilian Ries <[email protected]> * Update by using latest Conan list API Signed-off-by: Uilian Ries <[email protected]> * Update variable names Signed-off-by: Uilian Ries <[email protected]> * Fix missing variable name Signed-off-by: Uilian Ries <[email protected]> * Only run tests for Conan clean with version 2.21.0-dev or later Signed-off-by: Uilian Ries <[email protected]> * Validate conan clean for latest packages only Signed-off-by: Uilian Ries <[email protected]> * Print out for debug Signed-off-by: Uilian Ries <[email protected]> * Sort values before be compared Signed-off-by: Uilian Ries <[email protected]> * Use output instead of file Signed-off-by: Uilian Ries <[email protected]> * Fix to avoid removing all pkg IDs Signed-off-by: Uilian Ries <[email protected]> * Make it pass on Windows Signed-off-by: Uilian Ries <[email protected]> --------- Signed-off-by: Uilian Ries <[email protected]>
1 parent 13c1bd7 commit 2357410

File tree

2 files changed

+49
-29
lines changed

2 files changed

+49
-29
lines changed

examples/extensions/commands/ci_test_example.py

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import os
2+
import warnings
3+
import json
24

35
from test.examples_tools import run, tmp_dir
4-
6+
from conan import conan_version
57

68
non_deterministic_conanfile = """\
79
from datetime import datetime
@@ -54,11 +56,24 @@ def install_clean_command():
5456
f.write(non_deterministic_conanfile.format(name="clean_other", comment="# Changing RREV"))
5557
run("conan create .") # different RREV (this is the latest one)
5658

57-
# 3. Run "conan clean" command: Cleaning all the non-latest RREVs (and its packages) and PREVs
58-
output = run("conan clean --force")
59-
assert "Removed package revision: clean_hello/1.0#" in output # removing earlier PREV from clean_hello
60-
assert "Removed recipe revision: clean_other/1.0#" in output # removing earlier RREV from clean_other
61-
# Now, it should have removed nothing
62-
output = run("conan clean --force")
63-
assert "Removed recipe revision: clean_other/1.0#" not in output
64-
assert "Removed package revision: clean_hello/1.0#" not in output
59+
if conan_version >= "2.21.0-dev":
60+
output = run("conan list '*/*#*:*#*' --format=json ")
61+
all_packages = json.loads("\n".join(output.splitlines()[1:]))
62+
output = run("conan list '*/*#latest:*#latest' --format=json")
63+
latest_packages = json.loads("\n".join(output.splitlines()[1:]))
64+
if all_packages == latest_packages:
65+
warnings.warn("Skipping 'conan clean' test because there are no old revisions to clean.")
66+
# 3. Run "conan clean" command: Cleaning all the non-latest RREVs (and its packages) and PREVs
67+
output = run("conan clean --force")
68+
assert "Removed package revision: clean_hello/1.0#" in output # removing earlier PREV from clean_hello
69+
assert "Removed recipe revision: clean_other/1.0#" in output # removing earlier RREV from clean_other
70+
# Now, it should have removed nothing
71+
output = run("conan clean --force")
72+
assert "Removed recipe revision: clean_other/1.0#" not in output
73+
assert "Removed package revision: clean_hello/1.0#" not in output
74+
# Make sure latest revisions are still there
75+
output = run("conan list '*/*#*:*#*' --format=json")
76+
listed_after = json.loads("\n".join(output.splitlines()[1:]))
77+
assert latest_packages == listed_after
78+
else:
79+
warnings.warn("Skipping 'conan clean' test because it requires Conan 2.21 due new API list.")

examples/extensions/commands/clean/cmd_clean.py

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from conan.api.conan_api import ConanAPI
2+
from conan.api.model import PackagesList, ListPattern
23
from conan.api.input import UserInput
34
from conan.api.output import ConanOutput, Color
45
from conan.cli.command import OnceArgument, conan_command
@@ -27,26 +28,30 @@ def confirmation(message):
2728
remote = conan_api.remotes.get(args.remote) if args.remote else None
2829
output_remote = remote or "Local cache"
2930

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, "
3334
"except the latest package revision from the latest recipe one?"):
35+
out.writeln("Aborted")
3436
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)
4453
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

Comments
 (0)