Skip to content

Commit

Permalink
Add generator plugins for all SPDX formats
Browse files Browse the repository at this point in the history
This adds support for the other three SPDX formats:
XML, YAML and RDF-XML

Signed-off-by: Armin Tänzer <armin.taenzer@tngtech.com>
  • Loading branch information
armintaenzertng committed Jun 28, 2023
1 parent 9a293b6 commit 9f80484
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 0 deletions.
3 changes: 3 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ tern.formats =
html = tern.formats.html.generator:HTML
cyclonedxjson = tern.formats.cyclonedx.cyclonedxjson.generator:CycloneDXJSON
spdxjson_new = tern.formats.spdx_new.spdxjson.generator:SpdxJSON
spdxyaml_new = tern.formats.spdx_new.spdxyaml.generator:SpdxYAML
spdxxml_new = tern.formats.spdx_new.spdxxml.generator:SpdxXML
spdxrdf_new = tern.formats.spdx_new.spdxrdf.generator:SpdxRDF
spdxtagvalue_new = tern.formats.spdx_new.spdxtagvalue.generator:SpdxTagValue
tern.extensions =
cve_bin_tool = tern.extensions.cve_bin_tool.executor:CveBinTool
Expand Down
Empty file.
57 changes: 57 additions & 0 deletions tern/formats/spdx_new/spdxrdf/generator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2021 VMware, Inc. All Rights Reserved.
# SPDX-License-Identifier: BSD-2-Clause

"""
SPDX RDF-XML document generator
"""
import io
import logging
from typing import List

from spdx_tools.spdx.model import Document
from spdx_tools.spdx.writer.rdf.rdf_writer import write_document_to_stream

from tern.classes.image import Image
from tern.classes.image_layer import ImageLayer
from tern.formats import generator
from tern.formats.spdx.spdx import SPDX
from tern.formats.spdx_new.make_spdx_model import make_spdx_model, make_spdx_model_snapshot
from tern.utils import constants

# global logger
logger = logging.getLogger(constants.logger_name)


class SpdxRDF(generator.Generate):
def generate(self, image_obj_list: List[Image], print_inclusive=False) -> str:
"""Generate an SPDX document
WARNING: This assumes that the list consists of one image or the base
image and a stub image, in which case, the information in the stub
image is not applicable in the SPDX case as it is an empty image
object with no metadata as nothing got built.
For the sake of SPDX, an image is a 'Package' which 'CONTAINS' each
layer which is also a 'Package' which 'CONTAINS' the real Packages"""
logger.debug("Generating SPDX RDF-XML document...")

spdx_document: Document = make_spdx_model(image_obj_list)

return get_serialized_rdf_document_string(spdx_document)


def generate_layer(self, layer: ImageLayer) -> str:
"""Generate an SPDX document containing package and file information
at container build time"""
logger.debug("Generating SPDX RDF-XML snapshot document...")
template = SPDX()
spdx_document: Document = make_spdx_model_snapshot(layer, template)

return get_serialized_rdf_document_string(spdx_document)


def get_serialized_rdf_document_string(spdx_document):
with io.BytesIO() as stream:
write_document_to_stream(spdx_document, stream, validate=False)
return stream.getvalue().decode("UTF-8")
Empty file.
50 changes: 50 additions & 0 deletions tern/formats/spdx_new/spdxxml/generator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2021 VMware, Inc. All Rights Reserved.
# SPDX-License-Identifier: BSD-2-Clause

"""
SPDX XML document generator
"""
import logging
from typing import List

from spdx_tools.spdx.model import Document
from spdx_tools.spdx.writer.xml.xml_writer import write_document_to_stream

from tern.classes.image import Image
from tern.classes.image_layer import ImageLayer
from tern.formats import generator
from tern.formats.spdx.spdx import SPDX
from tern.formats.spdx_new.general_helpers import get_serialized_document_string
from tern.formats.spdx_new.make_spdx_model import make_spdx_model, make_spdx_model_snapshot
from tern.utils import constants

# global logger
logger = logging.getLogger(constants.logger_name)


class SpdxXML(generator.Generate):
def generate(self, image_obj_list: List[Image], print_inclusive=False) -> str:
"""Generate an SPDX document
WARNING: This assumes that the list consists of one image or the base
image and a stub image, in which case, the information in the stub
image is not applicable in the SPDX case as it is an empty image
object with no metadata as nothing got built.
For the sake of SPDX, an image is a 'Package' which 'CONTAINS' each
layer which is also a 'Package' which 'CONTAINS' the real Packages"""
logger.debug("Generating SPDX XML document...")

spdx_document: Document = make_spdx_model(image_obj_list)

return get_serialized_document_string(spdx_document, write_document_to_stream)

def generate_layer(self, layer: ImageLayer) -> str:
"""Generate an SPDX document containing package and file information
at container build time"""
logger.debug("Generating SPDX XML snapshot document...")
template = SPDX()
spdx_document: Document = make_spdx_model_snapshot(layer, template)

return get_serialized_document_string(spdx_document, write_document_to_stream)
Empty file.
50 changes: 50 additions & 0 deletions tern/formats/spdx_new/spdxyaml/generator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2021 VMware, Inc. All Rights Reserved.
# SPDX-License-Identifier: BSD-2-Clause

"""
SPDX YAML document generator
"""
import logging
from typing import List

from spdx_tools.spdx.model import Document
from spdx_tools.spdx.writer.yaml.yaml_writer import write_document_to_stream

from tern.classes.image import Image
from tern.classes.image_layer import ImageLayer
from tern.formats import generator
from tern.formats.spdx.spdx import SPDX
from tern.formats.spdx_new.general_helpers import get_serialized_document_string
from tern.formats.spdx_new.make_spdx_model import make_spdx_model, make_spdx_model_snapshot
from tern.utils import constants

# global logger
logger = logging.getLogger(constants.logger_name)


class SpdxYAML(generator.Generate):
def generate(self, image_obj_list: List[Image], print_inclusive=False) -> str:
"""Generate an SPDX document
WARNING: This assumes that the list consists of one image or the base
image and a stub image, in which case, the information in the stub
image is not applicable in the SPDX case as it is an empty image
object with no metadata as nothing got built.
For the sake of SPDX, an image is a 'Package' which 'CONTAINS' each
layer which is also a 'Package' which 'CONTAINS' the real Packages"""
logger.debug("Generating SPDX YAML document...")

spdx_document: Document = make_spdx_model(image_obj_list)

return get_serialized_document_string(spdx_document, write_document_to_stream)

def generate_layer(self, layer: ImageLayer) -> str:
"""Generate an SPDX document containing package and file information
at container build time"""
logger.debug("Generating SPDX YAML snapshot document...")
template = SPDX()
spdx_document: Document = make_spdx_model_snapshot(layer, template)

return get_serialized_document_string(spdx_document, write_document_to_stream)

0 comments on commit 9f80484

Please sign in to comment.