Skip to content

Commit 08811ab

Browse files
add CLI version parameter
This adds new a new -fv option to specify the version of the output format if it supports versions. Removes the old SPDX version handling. Signed-off-by: Armin Tänzer <[email protected]>
1 parent c489827 commit 08811ab

33 files changed

+124
-192
lines changed

setup.cfg

+5-10
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,11 @@ tern.formats =
5252
yaml = tern.formats.yaml.generator:YAML
5353
html = tern.formats.html.generator:HTML
5454
cyclonedxjson = tern.formats.cyclonedx.cyclonedxjson.generator:CycloneDXJSON
55-
spdxjson22 = tern.formats.spdx_new.spdxjson22.generator:SpdxJSON22
56-
spdxyaml22 = tern.formats.spdx_new.spdxyaml22.generator:SpdxYAML22
57-
spdxxml22 = tern.formats.spdx_new.spdxxml22.generator:SpdxXML22
58-
spdxrdf22 = tern.formats.spdx_new.spdxrdf22.generator:SpdxRDF22
59-
spdxtagvalue22 = tern.formats.spdx_new.spdxtagvalue22.generator:SpdxTagValue22
60-
spdxjson23 = tern.formats.spdx_new.spdxjson23.generator:SpdxJSON23
61-
spdxyaml23 = tern.formats.spdx_new.spdxyaml23.generator:SpdxYAML23
62-
spdxxml23 = tern.formats.spdx_new.spdxxml23.generator:SpdxXML23
63-
spdxrdf23 = tern.formats.spdx_new.spdxrdf23.generator:SpdxRDF23
64-
spdxtagvalue23 = tern.formats.spdx_new.spdxtagvalue23.generator:SpdxTagValue23
55+
spdxjson_new = tern.formats.spdx_new.spdxjson.generator:SpdxJSON
56+
spdxyaml_new = tern.formats.spdx_new.spdxyaml.generator:SpdxYAML
57+
spdxxml_new = tern.formats.spdx_new.spdxxml.generator:SpdxXML
58+
spdxrdf_new = tern.formats.spdx_new.spdxrdf.generator:SpdxRDF
59+
spdxtagvalue_new = tern.formats.spdx_new.spdxtagvalue.generator:SpdxTagValue
6560
tern.extensions =
6661
cve_bin_tool = tern.extensions.cve_bin_tool.executor:CveBinTool
6762
scancode = tern.extensions.scancode.executor:Scancode

tern/__main__.py

+3
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,9 @@ def main():
216216
"available formats: "
217217
"spdxtagvalue, spdxjson, cyclonedxjson, json, "
218218
"yaml, html")
219+
parser_report.add_argument('-fv', '--format-version',
220+
metavar='FORMAT_VERSION',
221+
help="Specify the version of the report format.")
219222
parser_report.add_argument('-o', '--output-file', default=None,
220223
metavar='FILE',
221224
help="Write the report to a file. "

tern/formats/cyclonedx/cyclonedxjson/generator.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,14 @@ def get_document_dict(image_obj_list):
5050

5151

5252
class CycloneDXJSON(generator.Generate):
53-
def generate(self, image_obj_list, print_inclusive=False):
53+
def generate(self, image_obj_list, format_version, print_inclusive=False):
5454
''' Generate a CycloneDX document
5555
The whole document should be stored in a dictionary which can be
5656
converted to JSON and dumped to a file using the write_report function
5757
in report.py. '''
5858
logger.debug('Generating CycloneDX JSON document...')
59+
if format_version is not None:
60+
logger.warning("The version parameter is not supported for CycloneDX JSON.")
5961

6062
report = get_document_dict(image_obj_list)
6163

tern/formats/default/generator.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,11 @@ def print_licenses_only(image_obj_list):
140140

141141

142142
class Default(generator.Generate):
143-
def generate(self, image_obj_list, print_inclusive=False):
143+
def generate(self, image_obj_list, format_version: str, print_inclusive=False):
144144
'''Generate a default report'''
145+
if format_version is not None:
146+
logger.warning("The version parameter is not supported for the default format.")
147+
145148
report = formats.disclaimer.format(
146149
version_info=content.get_tool_version())
147150
logger.debug('Creating a detailed report of components in image...')
@@ -154,8 +157,11 @@ def generate(self, image_obj_list, print_inclusive=False):
154157
return report
155158
return report + print_licenses_only(image_obj_list)
156159

157-
def generate_layer(self, layer):
160+
def generate_layer(self, layer, version: str):
158161
"""Generate a default report for one layer object"""
162+
if version is not None:
163+
logger.warning("The version parameter is not supported for the default format.")
164+
159165
report = formats.disclaimer.format(
160166
version_info=content.get_tool_version())
161167
logger.debug("Generating summary report for layer...")

tern/formats/generator.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@
1010
class Generate(metaclass=ABCMeta):
1111
'''Base class for report plugins'''
1212
@abstractmethod
13-
def generate(self, image_obj_list, print_inclusive=False):
13+
def generate(self, image_obj_list, format_version, print_inclusive=False):
1414
'''Format the report according to the plugin style.
1515
Each subclass is responsible for their own formatting.'''

tern/formats/html/generator.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -321,16 +321,22 @@ def get_report_dict(image_obj_list):
321321

322322

323323
class HTML(generator.Generate):
324-
def generate(self, image_obj_list, print_inclusive=False):
324+
def generate(self, image_obj_list, format_version: str, print_inclusive=False):
325325
'''Given a list of image objects, create a html report
326326
for the images'''
327+
if format_version is not None:
328+
logger.warning("The version parameter is not supported for HTML.")
329+
327330
report_dict = get_report_dict(image_obj_list)
328331
report = create_html_report(report_dict, image_obj_list)
329332
return report
330333

331-
def generate_layer(self, layer):
334+
def generate_layer(self, layer, version: str):
332335
"""Given a layer object, create a html report for the layer"""
333336
logger.debug("Creating HTML report...")
337+
if version is not None:
338+
logger.warning("The version parameter is not supported for HTML.")
339+
334340
report = ""
335341
report = report + '\n' + head_layer % (css, get_tool_version())
336342
report = report + '\n' + report_dict_to_html(layer.to_dict())

tern/formats/json/generator.py

+12-2
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,28 @@
88
"""
99

1010
import json
11+
import logging
12+
1113
from tern.formats import generator
14+
from tern.utils import constants
1215

16+
logger = logging.getLogger(constants.logger_name)
1317

1418
class JSON(generator.Generate):
15-
def generate(self, image_obj_list, print_inclusive=False):
19+
def generate(self, image_obj_list, format_version: str, print_inclusive=False):
1620
'''Given a list of image objects, create a json object string'''
1721
image_list = []
22+
if format_version is not None:
23+
logger.warning("The version parameter is not supported for JSON.")
24+
1825
for image in image_obj_list:
1926
image_list.append({'image': image.to_dict()})
2027
image_dict = {'images': image_list}
2128
return json.dumps(image_dict)
2229

23-
def generate_layer(self, layer):
30+
def generate_layer(self, layer, format_version: str):
2431
"""Create a json object for one layer"""
32+
if format_version is not None:
33+
logger.warning("The version parameter is not supported for JSON.")
34+
2535
return json.dumps(layer.to_dict())

tern/formats/spdx/spdxjson/generator.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
import json
1111
import logging
12-
import pickle
1312

1413
from tern.formats.spdx.spdx import SPDX
1514
from tern.formats.spdx import spdx_common
@@ -141,7 +140,7 @@ def get_document_dict_snapshot(layer_obj, template):
141140

142141

143142
class SpdxJSON(generator.Generate):
144-
def generate(self, image_obj_list, print_inclusive=False):
143+
def generate(self, image_obj_list, format_version: str, print_inclusive=False):
145144
'''Generate an SPDX document
146145
WARNING: This assumes that the list consists of one image or the base
147146
image and a stub image, in which case, the information in the stub
@@ -165,7 +164,7 @@ def generate(self, image_obj_list, print_inclusive=False):
165164

166165
return json.dumps(report)
167166

168-
def generate_layer(self, layer):
167+
def generate_layer(self, layer, format_version: str):
169168
"""Generate an SPDX document containing package and file information
170169
at container build time"""
171170
logger.debug("Generating SPDX JSON document...")

tern/formats/spdx/spdxtagvalue/generator.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def get_document_block(image_obj):
5151

5252

5353
class SpdxTagValue(generator.Generate):
54-
def generate(self, image_obj_list, print_inclusive=False):
54+
def generate(self, image_obj_list, format_version: str, print_inclusive=False):
5555
'''Generate an SPDX document
5656
WARNING: This assumes that the list consists of one image or the base
5757
image and a stub image, in which case, the information in the stub
@@ -142,7 +142,7 @@ def generate(self, image_obj_list, print_inclusive=False):
142142

143143
return report
144144

145-
def generate_layer(self, layer_obj): # pylint: disable=unused-argument
145+
def generate_layer(self, layer_obj, format_version: str): # pylint: disable=unused-argument
146146
"""Currently Unsupported. Provide debug statement"""
147147
logger.critical("Generating SPDX tag-value documents at container "
148148
"build time is currently unsupported")

tern/formats/spdx_new/spdx_formats_helper.py

+13-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@
2020

2121
logger = logging.getLogger(constants.logger_name)
2222

23+
SPDX_VERSION_MAPPING = {
24+
"2.2": "SPDX-2.2",
25+
"2.3": "SPDX-2.3",
26+
}
27+
2328

2429
def get_spdx_from_image_list(image_obj_list: List[Image], spdx_format: str, spdx_version: str) -> str:
2530
"""Generate an SPDX document
@@ -32,7 +37,10 @@ def get_spdx_from_image_list(image_obj_list: List[Image], spdx_format: str, spdx
3237
layer which is also a 'Package' which 'CONTAINS' the real Packages"""
3338
logger.debug(f"Generating SPDX {spdx_format} document...")
3439

35-
spdx_document: Document = make_spdx_model(image_obj_list, spdx_version)
40+
if spdx_version not in SPDX_VERSION_MAPPING:
41+
raise ValueError(f"SPDX version {spdx_version} is not supported by tern.")
42+
43+
spdx_document: Document = make_spdx_model(image_obj_list, SPDX_VERSION_MAPPING[spdx_version])
3644

3745
return convert_document_to_serialized_string(spdx_document, spdx_format)
3846

@@ -42,8 +50,11 @@ def get_spdx_from_layer(layer: ImageLayer, spdx_format: str, spdx_version: str)
4250
at container build time"""
4351
logger.debug(f"Generating SPDX {spdx_format} snapshot document...")
4452

53+
if spdx_version not in SPDX_VERSION_MAPPING:
54+
raise ValueError(f"SPDX version {spdx_version} is not supported by tern.")
55+
4556
template = SPDX()
46-
spdx_document: Document = make_spdx_model_snapshot(layer, template, spdx_version)
57+
spdx_document: Document = make_spdx_model_snapshot(layer, template, SPDX_VERSION_MAPPING[spdx_version])
4758

4859
return convert_document_to_serialized_string(spdx_document, spdx_format)
4960

tern/formats/spdx_new/spdxjson22/generator.py tern/formats/spdx_new/spdxjson/generator.py

+8-6
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# SPDX-License-Identifier: BSD-2-Clause
55

66
"""
7-
SPDX-2.2 JSON document generator
7+
SPDX JSON document generator
88
"""
99
from typing import List
1010

@@ -14,9 +14,11 @@
1414
from tern.formats.spdx_new.spdx_formats_helper import get_spdx_from_image_list, get_spdx_from_layer
1515

1616

17-
class SpdxJSON22(generator.Generate):
18-
def generate(self, image_obj_list: List[Image], print_inclusive=False) -> str:
19-
return get_spdx_from_image_list(image_obj_list, "JSON", "SPDX-2.2")
17+
class SpdxJSON(generator.Generate):
18+
def generate(self, image_obj_list: List[Image], format_version: str, print_inclusive=False) -> str:
19+
if format_version is None:
20+
format_version = "2.2"
21+
return get_spdx_from_image_list(image_obj_list, "JSON", format_version)
2022

21-
def generate_layer(self, layer: ImageLayer) -> str:
22-
return get_spdx_from_layer(layer, "JSON", "SPDX-2.2")
23+
def generate_layer(self, layer: ImageLayer, format_version) -> str:
24+
return get_spdx_from_layer(layer, "JSON", format_version)

tern/formats/spdx_new/spdxjson23/generator.py

-22
This file was deleted.

tern/formats/spdx_new/spdxrdf22/generator.py tern/formats/spdx_new/spdxrdf/generator.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# SPDX-License-Identifier: BSD-2-Clause
55

66
"""
7-
SPDX-2.2 RDF-XML document generator
7+
SPDX RDF-XML document generator
88
"""
99
from typing import List
1010

@@ -14,9 +14,9 @@
1414
from tern.formats.spdx_new.spdx_formats_helper import get_spdx_from_image_list, get_spdx_from_layer
1515

1616

17-
class SpdxRDF22(generator.Generate):
18-
def generate(self, image_obj_list: List[Image], print_inclusive=False) -> str:
19-
return get_spdx_from_image_list(image_obj_list, "RDF-XML", "SPDX-2.2")
17+
class SpdxRDF(generator.Generate):
18+
def generate(self, image_obj_list: List[Image], format_version: str, print_inclusive=False) -> str:
19+
return get_spdx_from_image_list(image_obj_list, "RDF-XML", format_version)
2020

21-
def generate_layer(self, layer: ImageLayer) -> str:
22-
return get_spdx_from_layer(layer, "RDF-XML", "SPDX-2.2")
21+
def generate_layer(self, layer: ImageLayer, format_version: str) -> str:
22+
return get_spdx_from_layer(layer, "RDF-XML", format_version)

tern/formats/spdx_new/spdxrdf23/generator.py

-22
This file was deleted.

tern/formats/spdx_new/spdxtagvalue22/generator.py tern/formats/spdx_new/spdxtagvalue/generator.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# SPDX-License-Identifier: BSD-2-Clause
55

66
"""
7-
SPDX-2.2 Tag-Value document generator
7+
SPDX Tag-Value document generator
88
"""
99

1010
from typing import List
@@ -15,9 +15,9 @@
1515
from tern.formats.spdx_new.spdx_formats_helper import get_spdx_from_image_list, get_spdx_from_layer
1616

1717

18-
class SpdxTagValue22(generator.Generate):
19-
def generate(self, image_obj_list: List[Image], print_inclusive=False) -> str:
20-
return get_spdx_from_image_list(image_obj_list, "Tag-Value", "SPDX-2.2")
18+
class SpdxTagValue(generator.Generate):
19+
def generate(self, image_obj_list: List[Image], format_version: str, print_inclusive=False) -> str:
20+
return get_spdx_from_image_list(image_obj_list, "Tag-Value", format_version)
2121

22-
def generate_layer(self, layer: ImageLayer) -> str:
23-
return get_spdx_from_layer(layer, "Tag-Value", "SPDX-2.2")
22+
def generate_layer(self, layer: ImageLayer, format_version: str) -> str:
23+
return get_spdx_from_layer(layer, "Tag-Value", format_version)

tern/formats/spdx_new/spdxtagvalue23/__init__.py

Whitespace-only changes.

tern/formats/spdx_new/spdxtagvalue23/generator.py

-23
This file was deleted.
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# Copyright (c) 2021 VMware, Inc. All Rights Reserved.
4+
# SPDX-License-Identifier: BSD-2-Clause
5+
6+
"""
7+
SPDX XML document generator
8+
"""
9+
from typing import List
10+
11+
from tern.classes.image import Image
12+
from tern.classes.image_layer import ImageLayer
13+
from tern.formats import generator
14+
from tern.formats.spdx_new.spdx_formats_helper import get_spdx_from_image_list, get_spdx_from_layer
15+
16+
17+
class SpdxXML(generator.Generate):
18+
def generate(self, image_obj_list: List[Image], format_version: str, print_inclusive=False) -> str:
19+
return get_spdx_from_image_list(image_obj_list, "XML", format_version)
20+
21+
def generate_layer(self, layer: ImageLayer, format_version: str) -> str:
22+
return get_spdx_from_layer(layer, "XML", format_version)

tern/formats/spdx_new/spdxxml22/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)