@@ -61,6 +61,10 @@ class CycloneDxLicenseExpression(ToDictMixin):
6161 """
6262 expression : str = attr .ib (default = None )
6363
64+ @property
65+ def identifier (self ):
66+ return self .expression
67+
6468 @classmethod
6569 def from_package (cls , package ):
6670 """
@@ -81,6 +85,10 @@ class CycloneDxProperty(ToDictMixin):
8185 name : str = attr .ib ()
8286 value : str = attr .ib ()
8387
88+ @property
89+ def identifier (self ):
90+ return f"{ self .name } -{ self .value } "
91+
8492
8593@attr .s
8694class CycloneDxHashObject (ToDictMixin ):
@@ -98,6 +106,10 @@ class CycloneDxHashObject(ToDictMixin):
98106 alg : str = attr .ib ()
99107 content : str = attr .ib ()
100108
109+ @property
110+ def identifier (self ):
111+ return f"{ self .alg } -{ self .content } "
112+
101113 @classmethod
102114 def from_package (cls , package ):
103115 """
@@ -159,6 +171,10 @@ class CycloneDxExternalRef(ToDictMixin):
159171 comment : str = attr .ib (default = None )
160172 hashes : List [CycloneDxHashObject ] = attr .ib (factory = list )
161173
174+ @property
175+ def identifier (self ):
176+ return f"{ self .url } -{ self .type } -{ self .comment } "
177+
162178 @classmethod
163179 def from_package (cls , package : dict ):
164180 """
@@ -290,7 +306,8 @@ def from_package(cls, package):
290306 properties .append (
291307 CycloneDxProperty (
292308 name = 'WARNING' ,
293- value = f'WARNING: component skipped in CycloneDX output: { package !r} '
309+ value = f'WARNING: component skipped in CycloneDX output:'
310+ f' purl: { package ["purl" ]} at datafile_paths: { package ["datafile_paths" ]} '
294311 )
295312 )
296313
@@ -428,8 +445,8 @@ def merge_lists(x, y):
428445 Merge ``y`` list items in list ``x`` avoiding duplicate entries.
429446 Return the updated ``x``.
430447 """
431- seen = set (x )
432- new = (i for i in y if i not in seen )
448+ seen = set ([ item . identifier for item in x ] )
449+ new = (item for item in y if item . identifier not in seen )
433450 x .extend (new )
434451 return x
435452
0 commit comments