Skip to content

Commit ebe9f2e

Browse files
committed
add transpiling for CDX < 1.7
Signed-off-by: Johannes Feichtner <johannes@web-wack.at>
1 parent 77fd7b7 commit ebe9f2e

12 files changed

Lines changed: 79 additions & 17 deletions

cyclonedx/model/license.py

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020
License related things
2121
"""
2222

23+
from collections.abc import Iterable
2324
from enum import Enum
2425
from json import loads as json_loads
2526
from typing import TYPE_CHECKING, Any, Optional, Union
26-
from collections.abc import Iterable
2727
from warnings import warn
2828
from xml.etree.ElementTree import Element # nosec B405
2929

@@ -519,6 +519,9 @@ def __init__(
519519
self.properties = properties or []
520520

521521
@property
522+
@serializable.view(SchemaVersion1Dot5)
523+
@serializable.view(SchemaVersion1Dot6)
524+
@serializable.view(SchemaVersion1Dot7)
522525
@serializable.type_mapping(BomRef)
523526
@serializable.xml_attribute()
524527
@serializable.xml_name('bom-ref')
@@ -551,6 +554,8 @@ def expression(self, expression: str) -> None:
551554
self._expression = expression
552555

553556
@property
557+
@serializable.view(SchemaVersion1Dot6)
558+
@serializable.view(SchemaVersion1Dot7)
554559
@serializable.xml_attribute()
555560
def acknowledgement(self) -> Optional[LicenseAcknowledgement]:
556561
"""
@@ -575,6 +580,7 @@ def acknowledgement(self, acknowledgement: Optional[LicenseAcknowledgement]) ->
575580
self._acknowledgement = acknowledgement
576581

577582
@property
583+
@serializable.view(SchemaVersion1Dot7)
578584
@serializable.xml_array(serializable.XmlArraySerializationType.FLAT, child_name='details')
579585
@serializable.xml_sequence(1)
580586
def expression_details(self) -> 'SortedSet[ExpressionDetails]':
@@ -591,6 +597,7 @@ def expression_details(self, expression_details: Iterable[ExpressionDetails]) ->
591597
self._expression_details = SortedSet(expression_details)
592598

593599
# @property
600+
# @serializable.view(SchemaVersion1Dot7)
594601
# ...
595602
# @serializable.xml_array(serializable.XmlArraySerializationType.FLAT, child_name='licensing')
596603
# @serializable.xml_sequence(2)
@@ -599,6 +606,7 @@ def expression_details(self, expression_details: Iterable[ExpressionDetails]) ->
599606
#
600607

601608
@property
609+
@serializable.view(SchemaVersion1Dot7)
602610
@serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'property')
603611
@serializable.xml_sequence(3)
604612
def properties(self) -> 'SortedSet[Property]':
@@ -699,6 +707,27 @@ def __supports_expression_details(view: Any) -> bool:
699707
except Exception: # pragma: no cover
700708
return False
701709

710+
@staticmethod
711+
def __transpile_license_expression_details_xml(
712+
expression_detailed: LicenseExpressionDetailed,
713+
view: Optional[type[serializable.ViewType]],
714+
xmlns: Optional[str]
715+
) -> Element:
716+
normalized: Element = expression_detailed.as_xml( # type:ignore[attr-defined]
717+
view_=view, as_string=False, element_name='expression', xmlns=xmlns)
718+
719+
ns_prefix = f'{{{xmlns}}}' if xmlns else ''
720+
details = normalized.findall(f'./{ns_prefix}details')
721+
for details_elem in details:
722+
normalized.remove(details_elem)
723+
724+
expression_value = normalized.get(f'{ns_prefix}expression')
725+
if expression_value:
726+
normalized.text = expression_value
727+
del normalized.attrib[f'{ns_prefix}expression']
728+
729+
return normalized
730+
702731
@classmethod
703732
def json_normalize(cls, o: LicenseRepository, *,
704733
view: Optional[type[serializable.ViewType]],
@@ -708,10 +737,9 @@ def json_normalize(cls, o: LicenseRepository, *,
708737

709738
expression_detailed = next((li for li in o if isinstance(li, LicenseExpressionDetailed)), None)
710739
if expression_detailed:
711-
if cls.__supports_expression_details(view):
712-
return [json_loads(expression_detailed.as_json(view_=view))] # type:ignore[attr-defined]
713-
else:
714-
warn('LicenseExpressionDetailed is not supported in schema versions before 1.7; skipping serialization')
740+
if not cls.__supports_expression_details(view):
741+
warn('LicenseExpressionDetailed is not supported in schema versions < 1.7; ignoring expressionDetails')
742+
return [json_loads(expression_detailed.as_json(view_=view))] # type:ignore[attr-defined]
715743

716744
expression = next((li for li in o if isinstance(li, LicenseExpression)), None)
717745
if expression:
@@ -764,7 +792,8 @@ def xml_normalize(cls, o: LicenseRepository, *,
764792
elem.append(expression_detailed.as_xml( # type:ignore[attr-defined]
765793
view_=view, as_string=False, element_name='expression-detailed', xmlns=xmlns))
766794
else:
767-
warn('LicenseExpressionDetailed is not supported in schema versions before 1.7; skipping serialization')
795+
warn('LicenseExpressionDetailed is not supported in schema versions < 1.7; ignoring details')
796+
elem.append(cls.__transpile_license_expression_details_xml(expression_detailed, view, xmlns))
768797

769798
expression = next((li for li in o if isinstance(li, LicenseExpression)), None)
770799
if expression:

tests/_data/snapshots/get_bom_with_licenses-1.1.xml.bin

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
<component type="library" bom-ref="C4">
2222
<name>c-with-expression-details</name>
2323
<version/>
24-
<licenses/>
24+
<licenses>
25+
<expression>GPL-3.0-or-later OR GPL-2.0</expression>
26+
</licenses>
2527
</component>
2628
<component type="library" bom-ref="C3">
2729
<name>c-with-name</name>

tests/_data/snapshots/get_bom_with_licenses-1.2.json.bin

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@
2727
},
2828
{
2929
"bom-ref": "C4",
30-
"licenses": [],
30+
"licenses": [
31+
{
32+
"expression": "GPL-3.0-or-later OR GPL-2.0"
33+
}
34+
],
3135
"name": "c-with-expression-details",
3236
"type": "library",
3337
"version": ""

tests/_data/snapshots/get_bom_with_licenses-1.2.xml.bin

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@
3333
<component type="library" bom-ref="C4">
3434
<name>c-with-expression-details</name>
3535
<version/>
36-
<licenses/>
36+
<licenses>
37+
<expression>GPL-3.0-or-later OR GPL-2.0</expression>
38+
</licenses>
3739
</component>
3840
<component type="library" bom-ref="C3">
3941
<name>c-with-name</name>

tests/_data/snapshots/get_bom_with_licenses-1.3.json.bin

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@
2727
},
2828
{
2929
"bom-ref": "C4",
30-
"licenses": [],
30+
"licenses": [
31+
{
32+
"expression": "GPL-3.0-or-later OR GPL-2.0"
33+
}
34+
],
3135
"name": "c-with-expression-details",
3236
"type": "library",
3337
"version": ""

tests/_data/snapshots/get_bom_with_licenses-1.3.xml.bin

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@
3838
<component type="library" bom-ref="C4">
3939
<name>c-with-expression-details</name>
4040
<version/>
41-
<licenses/>
41+
<licenses>
42+
<expression>GPL-3.0-or-later OR GPL-2.0</expression>
43+
</licenses>
4244
</component>
4345
<component type="library" bom-ref="C3">
4446
<name>c-with-name</name>

tests/_data/snapshots/get_bom_with_licenses-1.4.json.bin

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@
2525
},
2626
{
2727
"bom-ref": "C4",
28-
"licenses": [],
28+
"licenses": [
29+
{
30+
"expression": "GPL-3.0-or-later OR GPL-2.0"
31+
}
32+
],
2933
"name": "c-with-expression-details",
3034
"type": "library"
3135
},

tests/_data/snapshots/get_bom_with_licenses-1.4.xml.bin

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@
3434
</component>
3535
<component type="library" bom-ref="C4">
3636
<name>c-with-expression-details</name>
37-
<licenses/>
37+
<licenses>
38+
<expression>GPL-3.0-or-later OR GPL-2.0</expression>
39+
</licenses>
3840
</component>
3941
<component type="library" bom-ref="C3">
4042
<name>c-with-name</name>

tests/_data/snapshots/get_bom_with_licenses-1.5.json.bin

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@
2525
},
2626
{
2727
"bom-ref": "C4",
28-
"licenses": [],
28+
"licenses": [
29+
{
30+
"expression": "GPL-3.0-or-later OR GPL-2.0"
31+
}
32+
],
2933
"name": "c-with-expression-details",
3034
"type": "library"
3135
},

tests/_data/snapshots/get_bom_with_licenses-1.5.xml.bin

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@
3434
</component>
3535
<component type="library" bom-ref="C4">
3636
<name>c-with-expression-details</name>
37-
<licenses/>
37+
<licenses>
38+
<expression>GPL-3.0-or-later OR GPL-2.0</expression>
39+
</licenses>
3840
</component>
3941
<component type="library" bom-ref="C3">
4042
<name>c-with-name</name>

0 commit comments

Comments
 (0)