diff --git a/support/testing/tests/utils/test_generate_cyclonedx.py b/support/testing/tests/utils/test_generate_cyclonedx.py index ddad92598b..54250058a0 100644 --- a/support/testing/tests/utils/test_generate_cyclonedx.py +++ b/support/testing/tests/utils/test_generate_cyclonedx.py @@ -129,6 +129,9 @@ class TestGenerateCycloneDX(unittest.TestCase): bar_deps = next(d for d in result["dependencies"] if d["ref"] == "package-bar") self.assertEqual(bar_deps["dependsOn"], ["package-foo"]) + project_deps = next(d for d in result["dependencies"] if d["ref"] == "buildroot") + self.assertEqual(project_deps["dependsOn"], ["host-tool", "package-foo"]) + def test_virtual(self): result = self._run_script(["--virtual"]) diff --git a/utils/generate-cyclonedx b/utils/generate-cyclonedx index 35198a47cf..f4d5afd847 100755 --- a/utils/generate-cyclonedx +++ b/utils/generate-cyclonedx @@ -385,6 +385,25 @@ def br2_parse_deps(ref, show_info_dict, virtual=False) -> list: return list(deps) +def br2_root_deps(show_info_dict, virtual=False) -> list: + """Retrieve the list of direct dependencies of the root component. + + This function returns all components that are not a dependency of any + other component. + + Args: + show_info_dict (dict): The JSON output of the show-info command. + virtual (bool): Whether to resolve virtual dependencies to their providers. + + Returns: + list: List of direct dependencies of the root component. + """ + indirect = set() + for ref in show_info_dict: + indirect.update(br2_parse_deps(ref, show_info_dict, virtual)) + return [ref for ref in show_info_dict if ref not in indirect] + + def main(): parser = argparse.ArgumentParser( description='''Create a CycloneDX SBoM for the Buildroot configuration. @@ -447,7 +466,7 @@ def main(): cyclonedx_component(name, comp) for name, comp in filtered_show_info_dict.items() ], "dependencies": [ - cyclonedx_dependency(args.project_name, list(filtered_show_info_dict)), + cyclonedx_dependency(args.project_name, br2_root_deps(filtered_show_info_dict, args.virtual)), *[cyclonedx_dependency(ref, br2_parse_deps(ref, show_info_dict, args.virtual)) for ref in filtered_show_info_dict], ],