Skip to content

Non-hierarchical merge with dependency (or at least unified) #480

@Falco20019

Description

@Falco20019

I tried with hierarchical and non-hierarchical merging on two layers of SBOMs. While hierarchical would achieve what I want, it massively increase the amount of components and dependencies by adding lots of duplication whereas non-hierarchical nicely merges the dependencies but is not adding the dependsOn for each metadata.component as the hierarchical does.

Is there any way to get nicely merged SBOMs with dependency without this duplication? My structure that I need (all coming from single SBOMs) looks like this:

  • main.cdx.json (merged)
    • project1.cdx.json (merged)
      • subproject1.cdx.json
      • subproject2.cdx.json
      • subproject3.cdx.json
      • subproject4.cdx.json
    • project2.cdx.json
    • project3.cdx.json
    • project4.cdx.json
    • project5.cdx.json
    • project6.cdx.json

Without the --hierarchical I sadly don't have a nice way to simply add the (which is the only thing I miss on the call without the flag):

  {
    "ref": "project1@version1",
    "dependsOn": [
      "subproject1@version1",
      "subproject2@version1",
      "subproject3@version1",
      "subproject4@version1"
    ]
  },
  {
    "ref": "main@version",
    "dependsOn": [
      "project1@version1",
      "project2@version2",
      "project3@version3",
      "project4@version4",
      "project5@version5",
      "project6@version6"
    ]
  }

Without this, DepdendencyTrack won't be able to pick up the dependency tree and also logically it would be missing in my use-case. Doing --hierarhical currently creates the dependencies like this (not even speaking about the components):

[
  {
    "ref": "project1@version1:subproject1@version1:subproject1@version1",
    "dependsOn": [
      "project1@version1:subproject1@version1:pkg:nuget/Aspire.MongoDB.Driver@13.1.1",
      "project1@version1:subproject1@version1:pkg:nuget/Serilog@4.3.0",
      "project1@version1:subproject1@version1:pkg:nuget/Serilog.AspNetCore@10.0.0",
      "project1@version1:subproject1@version1:pkg:nuget/Serilog.Enrichers.Span@3.1.0",
      "project1@version1:subproject1@version1:pkg:nuget/Serilog.Exceptions@8.4.0",
      "project1@version1:subproject1@version1:pkg:nuget/Serilog.Sinks.Async@2.1.0",
      "project1@version1:subproject1@version1:pkg:nuget/Serilog.Sinks.Grafana.Loki@8.3.2",
      "project1@version1:subproject1@version1:pkg:nuget/Serilog.Sinks.OpenTelemetry@4.2.0"
    ]
  },
  {
    "ref": "project1@version1:subproject2@version1:subproject2@version1",
    "dependsOn": [
      "project1@version1:subproject2@version1:pkg:nuget/Aspire.MongoDB.Driver@13.1.1",
      "project1@version1:subproject2@version1:pkg:nuget/Serilog@4.3.0",
      "project1@version1:subproject2@version1:pkg:nuget/Serilog.AspNetCore@10.0.0",
      "project1@version1:subproject2@version1:pkg:nuget/Serilog.Enrichers.Span@3.1.0",
      "project1@version1:subproject2@version1:pkg:nuget/Serilog.Exceptions@8.4.0",
      "project1@version1:subproject2@version1:pkg:nuget/Serilog.Sinks.Async@2.1.0",
      "project1@version1:subproject2@version1:pkg:nuget/Serilog.Sinks.Grafana.Loki@8.3.2",
      "project1@version1:subproject2@version1:pkg:nuget/Serilog.Sinks.OpenTelemetry@4.2.0"
    ]
  },
  {
    "ref": "project1@version1:subproject3@version1:subproject3@version1",
    "dependsOn": [
      "project1@version1:subproject3@version1:pkg:nuget/Aspire.MongoDB.Driver@13.1.1",
      "project1@version1:subproject3@version1:pkg:nuget/Serilog@4.3.0",
      "project1@version1:subproject3@version1:pkg:nuget/Serilog.AspNetCore@10.0.0",
      "project1@version1:subproject3@version1:pkg:nuget/Serilog.Enrichers.Span@3.1.0",
      "project1@version1:subproject3@version1:pkg:nuget/Serilog.Exceptions@8.4.0",
      "project1@version1:subproject3@version1:pkg:nuget/Serilog.Sinks.Async@2.1.0",
      "project1@version1:subproject3@version1:pkg:nuget/Serilog.Sinks.Grafana.Loki@8.3.2",
      "project1@version1:subproject3@version1:pkg:nuget/Serilog.Sinks.OpenTelemetry@4.2.0"
    ]
  },
  {
    "ref": "project1@version1:project1@version1",
    "dependsOn": [
      "project1@version1:subproject1@version1:subproject1@version1",
      "project1@version1:subproject2@version1:subproject2@version1",
      "project1@version1:subproject3@version1:subproject3@version1",
      "project1@version1:subproject4@version1:subproject4@version1"
    ]
  },
  {
    "ref": "main@version",
    "dependsOn": [
      "project1@version1:project1@version1",
      "project2@version2:project2@version2",
      "project3@version3:project3@version3",
      "project4@version4:project4@version4",
      "project5@version5:project5@version5",
      "project6@version6:project6@version6"
    ]
  }
]

In cases where all components are exactly the same, I would love to see them merged before export to something like this:

[
  {
    "ref": "subproject1@version1",
    "dependsOn": [
      "pkg:nuget/Aspire.MongoDB.Driver@13.1.1",
      "pkg:nuget/Serilog@4.3.0",
      "pkg:nuget/Serilog.AspNetCore@10.0.0",
      "pkg:nuget/Serilog.Enrichers.Span@3.1.0",
      "pkg:nuget/Serilog.Exceptions@8.4.0",
      "pkg:nuget/Serilog.Sinks.Async@2.1.0",
      "pkg:nuget/Serilog.Sinks.Grafana.Loki@8.3.2",
      "pkg:nuget/Serilog.Sinks.OpenTelemetry@4.2.0"
    ]
  },
  {
    "ref": "subproject2@version1",
    "dependsOn": [
      "pkg:nuget/Aspire.MongoDB.Driver@13.1.1",
      "pkg:nuget/Serilog@4.3.0",
      "pkg:nuget/Serilog.AspNetCore@10.0.0",
      "pkg:nuget/Serilog.Enrichers.Span@3.1.0",
      "pkg:nuget/Serilog.Exceptions@8.4.0",
      "pkg:nuget/Serilog.Sinks.Async@2.1.0",
      "pkg:nuget/Serilog.Sinks.Grafana.Loki@8.3.2",
      "pkg:nuget/Serilog.Sinks.OpenTelemetry@4.2.0"
    ]
  },
  {
    "ref": "subproject3@version1",
    "dependsOn": [
      "pkg:nuget/Aspire.MongoDB.Driver@13.1.1",
      "pkg:nuget/Serilog@4.3.0",
      "pkg:nuget/Serilog.AspNetCore@10.0.0",
      "pkg:nuget/Serilog.Enrichers.Span@3.1.0",
      "pkg:nuget/Serilog.Exceptions@8.4.0",
      "pkg:nuget/Serilog.Sinks.Async@2.1.0",
      "pkg:nuget/Serilog.Sinks.Grafana.Loki@8.3.2",
      "pkg:nuget/Serilog.Sinks.OpenTelemetry@4.2.0"
    ]
  },
  {
    "ref": "project1@version1",
    "dependsOn": [
      "subproject1@version1",
      "subproject2@version1",
      "subproject3@version1",
      "subproject4@version1"
    ]
  },
  {
    "ref": "main@version",
    "dependsOn": [
      "project1@version1",
      "project2@version2",
      "project3@version3",
      "project4@version4",
      "project5@version5",
      "project6@version6"
    ]
  }
]

It's fine to keep project1@version1: prefixes if name conflicts are found, but duplicating ALL components for no reason is not what I expect.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions