Skip to content

Commit

Permalink
addressed JSON output for #275 including test addiitions
Browse files Browse the repository at this point in the history
Signed-off-by: Paul Horton <[email protected]>
  • Loading branch information
madpah committed Jul 27, 2022
1 parent 9e560db commit e99c122
Show file tree
Hide file tree
Showing 8 changed files with 1,017 additions and 124 deletions.
112 changes: 61 additions & 51 deletions cyclonedx/output/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ def _specialise_output_for_schema_version(self, bom_json: Dict[Any, Any]) -> str
del bom_json['metadata']['properties']

# Iterate Components
if self.get_bom().metadata.component:
bom_json['metadata'] = self._recurse_specialise_component(bom_json=bom_json['metadata'],
base_key='component')
bom_json = self._recurse_specialise_component(bom_json=bom_json)

# Iterate Services
Expand Down Expand Up @@ -155,60 +158,67 @@ def _get_schema_uri(self) -> Optional[str]:

def _recurse_specialise_component(self, bom_json: Dict[Any, Any], base_key: str = 'components') -> Dict[Any, Any]:
if base_key in bom_json.keys():
for i in range(len(bom_json[base_key])):
if not self.component_supports_mime_type_attribute() \
and 'mime-type' in bom_json[base_key][i].keys():
del bom_json[base_key][i]['mime-type']

if not self.component_supports_supplier() and 'supplier' in bom_json[base_key][i].keys():
del bom_json[base_key][i]['supplier']

if not self.component_supports_author() and 'author' in bom_json[base_key][i].keys():
del bom_json[base_key][i]['author']

if self.component_version_optional() and 'version' in bom_json[base_key][i] \
and bom_json[base_key][i].get('version', '') == "":
del bom_json[base_key][i]['version']

if not self.component_supports_pedigree() and 'pedigree' in bom_json[base_key][i].keys():
del bom_json[base_key][i]['pedigree']
elif 'pedigree' in bom_json[base_key][i].keys():
if 'ancestors' in bom_json[base_key][i]['pedigree'].keys():
# recurse into ancestors
bom_json[base_key][i]['pedigree'] = self._recurse_specialise_component(
bom_json=bom_json[base_key][i]['pedigree'], base_key='ancestors'
)
if 'descendants' in bom_json[base_key][i]['pedigree'].keys():
# recurse into descendants
bom_json[base_key][i]['pedigree'] = self._recurse_specialise_component(
bom_json=bom_json[base_key][i]['pedigree'], base_key='descendants'
)
if 'variants' in bom_json[base_key][i]['pedigree'].keys():
# recurse into variants
bom_json[base_key][i]['pedigree'] = self._recurse_specialise_component(
bom_json=bom_json[base_key][i]['pedigree'], base_key='variants'
)

if not self.external_references_supports_hashes() and 'externalReferences' \
in bom_json[base_key][i].keys():
for j in range(len(bom_json[base_key][i]['externalReferences'])):
del bom_json[base_key][i]['externalReferences'][j]['hashes']

if not self.component_supports_properties() and 'properties' in bom_json[base_key][i].keys():
del bom_json[base_key][i]['properties']

# recurse
if 'components' in bom_json[base_key][i].keys():
bom_json[base_key][i] = self._recurse_specialise_component(bom_json=bom_json[base_key][i])

if not self.component_supports_evidence() and 'evidence' in bom_json[base_key][i].keys():
del bom_json[base_key][i]['evidence']

if not self.component_supports_release_notes() and 'releaseNotes' in bom_json[base_key][i].keys():
del bom_json[base_key][i]['releaseNotes']
if isinstance(bom_json[base_key], dict):
bom_json[base_key] = self._specialise_component_data(component_json=bom_json[base_key])
else:
for i in range(len(bom_json[base_key])):
bom_json[base_key][i] = self._specialise_component_data(component_json=bom_json[base_key][i])

return bom_json

def _specialise_component_data(self, component_json: Dict[Any, Any]) -> Dict[Any, Any]:
if not self.component_supports_mime_type_attribute() and 'mime-type' in component_json.keys():
del component_json['mime-type']

if not self.component_supports_supplier() and 'supplier' in component_json.keys():
del component_json['supplier']

if not self.component_supports_author() and 'author' in component_json.keys():
del component_json['author']

if self.component_version_optional() and 'version' in component_json \
and component_json.get('version', '') == "":
del component_json['version']

if not self.component_supports_pedigree() and 'pedigree' in component_json.keys():
del component_json['pedigree']
elif 'pedigree' in component_json.keys():
if 'ancestors' in component_json['pedigree'].keys():
# recurse into ancestors
component_json['pedigree'] = self._recurse_specialise_component(
bom_json=component_json['pedigree'], base_key='ancestors'
)
if 'descendants' in component_json['pedigree'].keys():
# recurse into descendants
component_json['pedigree'] = self._recurse_specialise_component(
bom_json=component_json['pedigree'], base_key='descendants'
)
if 'variants' in component_json['pedigree'].keys():
# recurse into variants
component_json['pedigree'] = self._recurse_specialise_component(
bom_json=component_json['pedigree'], base_key='variants'
)

if not self.external_references_supports_hashes() and 'externalReferences' \
in component_json.keys():
for j in range(len(component_json['externalReferences'])):
del component_json['externalReferences'][j]['hashes']

if not self.component_supports_properties() and 'properties' in component_json.keys():
del component_json['properties']

# recurse
if 'components' in component_json.keys():
component_json = self._recurse_specialise_component(bom_json=component_json)

if not self.component_supports_evidence() and 'evidence' in component_json.keys():
del component_json['evidence']

if not self.component_supports_release_notes() and 'releaseNotes' in component_json.keys():
del component_json['releaseNotes']

return component_json


class JsonV1Dot0(Json, SchemaVersion1Dot0):

Expand Down
2 changes: 1 addition & 1 deletion tests/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ def get_bom_with_component_toml_1() -> Bom:
def get_bom_just_complete_metadata() -> Bom:
bom = Bom()
bom.metadata.authors = [get_org_contact_1(), get_org_contact_2()]
bom.metadata.component = get_component_setuptools_complete(include_pedigree=False)
bom.metadata.component = get_component_setuptools_complete()
bom.metadata.manufacture = get_org_entity_1()
bom.metadata.supplier = get_org_entity_2()
bom.metadata.licenses = [LicenseChoice(license_=License(
Expand Down
64 changes: 64 additions & 0 deletions tests/fixtures/json/1.2/bom_issue_275_components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json",
"bomFormat": "CycloneDX",
"components": [
{
"bom-ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda",
"name": "comp_a",
"type": "library",
"version": "1.0.0"
},
{
"bom-ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857",
"components": [
{
"bom-ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789",
"name": "comp_c",
"type": "library",
"version": "1.0.0"
}
],
"name": "comp_b",
"type": "library",
"version": "1.0.0"
}
],
"dependencies": [
{
"dependsOn": [
"17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda",
"0b049d09-64c0-4490-a0f5-c84d9aacf857"
],
"ref": "be2c6502-7e9a-47db-9a66-e34f729810a3"
},
{
"dependsOn": [],
"ref": "17e3b199-dc0b-42ef-bfdd-1fa81a1e3eda"
},
{
"dependsOn": [
"cd3e9c95-9d41-49e7-9924-8cf0465ae789"
],
"ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857"
}
],
"metadata": {
"component": {
"bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3",
"name": "app",
"type": "library",
"version": "1.0.0"
},
"timestamp": "2022-07-27T10:06:17.101289+00:00",
"tools": [
{
"name": "cyclonedx-python-lib",
"vendor": "CycloneDX",
"version": "0.11.0"
}
]
},
"serialNumber": "urn:uuid:b1d647c9-e4c5-4d8f-be8a-1751ac3ad4d5",
"specVersion": "1.2",
"version": 1
}
Loading

0 comments on commit e99c122

Please sign in to comment.