diff --git a/extensions/commands/art/cmd_build_info.py b/extensions/commands/art/cmd_build_info.py index 5205729..055e9ce 100644 --- a/extensions/commands/art/cmd_build_info.py +++ b/extensions/commands/art/cmd_build_info.py @@ -110,7 +110,7 @@ def _get_requested_by(nodes, node_id, artifact_type): class _BuildInfo: def __init__(self, graph, name, number, repository, with_dependencies=False, - url=None, user=None, password=None): + add_cached_deps=False, url=None, user=None, password=None): self._graph = graph self._name = name self._number = number @@ -120,6 +120,7 @@ def __init__(self, graph, name, number, repository, with_dependencies=False, self._password = password self._cached_artifact_info = {} self._with_dependencies = with_dependencies + self._add_cached_deps = add_cached_deps def get_artifacts(self, node, artifact_type, is_dependency=False): """ @@ -233,13 +234,13 @@ def get_modules(self): except KeyError: raise ConanException("JSON does not contain graph information") - for id, node in nodes.items(): + for node in nodes.values(): ref = node.get("ref") if ref: transitive_dependencies = node.get("dependencies").keys() if node.get("dependencies").keys() else [] + binary = node.get("binary") - # only add the nodes that were marked as built - if node.get("binary") == "Build": + if ref and (binary == "Build" or (binary == "Cache" and self._add_cached_deps)): # recipe module module = { @@ -360,6 +361,10 @@ def build_info_create(conan_api: ConanAPI, parser, subparser, *args): subparser.add_argument("--with-dependencies", help="Whether to add dependencies information or not. Default: false.", action='store_true', default=False) + subparser.add_argument("--add-cached-deps", help="It will add not only the Conan packages that are built " + "but also the ones that are used from the cache but not built. Default: false.", + action='store_true', default=False) + args = parser.parse_args(*args) url, user, password = get_url_user_password(args) @@ -370,7 +375,8 @@ def build_info_create(conan_api: ConanAPI, parser, subparser, *args): # remove the 'conanfile' node data["graph"]["nodes"].pop("0") bi = _BuildInfo(data, args.build_name, args.build_number, args.repository, - with_dependencies=args.with_dependencies, url=url, user=user, password=password) + with_dependencies=args.with_dependencies, + add_cached_deps=args.add_cached_deps, url=url, user=user, password=password) cli_out_write(bi.create()) diff --git a/tests/test_artifactory_commands.py b/tests/test_artifactory_commands.py index 785f495..e7310f5 100644 --- a/tests/test_artifactory_commands.py +++ b/tests/test_artifactory_commands.py @@ -1,7 +1,9 @@ import os import tempfile -from tools import run +from tools import run, save +from conan.tools.scm import Version +from conan import conan_version import pytest @@ -198,6 +200,40 @@ def test_build_info_create_deps(): run('conan remove "*" -c -r extensions-stg') +@pytest.mark.requires_credentials +def test_build_info_create_from_cached_deps(): + # Make sure artifactory repos are empty before starting the test + run("conan remove mypkg* -c -r extensions-stg") + run("conan remove mypkg* -c -r extensions-prod") + + run(f'conan art:server add artifactory {os.getenv("ART_URL")} --user="{os.getenv("CONAN_LOGIN_USERNAME_EXTENSIONS_STG")}" --password="{os.getenv("CONAN_PASSWORD_EXTENSIONS_STG")}"') + + # Create dependency packages and upload them + run("conan new cmake_lib -d name=libc -d version=1.0 --force") + run("conan create . -tf=''") + run("conan new cmake_lib -d name=liba -d version=1.0 -d requires=libc/1.0 --force") + run("conan create . -tf=''") + + run("conan upload '*' --dry-run -c -r extensions-stg") + + # libc node in graph is cached + run("conan install . --format json > install_release.json") + + run(f'conan art:build-info create install_release.json bi_release 1 extensions-stg --server artifactory --with-dependencies > bi_release.json') + + with open("bi_release.json", "r") as file: + build_info = json.load(file) + + assert len(build_info.get("modules")) == 0 + + run(f'conan art:build-info create install_release.json bi_release 1 extensions-stg --server artifactory --with-dependencies --add-cached-deps > bi_release.json') + + with open("bi_release.json", "r") as file: + build_info = json.load(file) + + assert len(build_info.get("modules")) == 2 + + @pytest.mark.requires_credentials def test_fail_if_not_uploaded(): """