From f8a98b044e6dbb7d1c2b4fed9c13bd47d06374a7 Mon Sep 17 00:00:00 2001 From: Pierre Tardy Date: Fri, 25 Jun 2021 15:51:23 +0200 Subject: [PATCH 01/10] factorize the parsing format detection a lot of the examples are actually the same code and the cli is using it We factorize it so that it is easier to make some more converters Signed-off-by: Pierre Tardy --- examples/parse_json.py | 96 -------------------- examples/parse_rdf.py | 102 --------------------- examples/parse_tv.py | 35 ------- examples/parse_xml.py | 94 ------------------- examples/parse_yaml.py | 96 -------------------- spdx/cli_tools/parser.py | 161 ++++++++++++++++++--------------- spdx/parsers/parse_anything.py | 54 +++++++++++ tests/test_parse_anything.py | 34 +++++++ 8 files changed, 177 insertions(+), 495 deletions(-) delete mode 100644 examples/parse_json.py delete mode 100755 examples/parse_rdf.py delete mode 100755 examples/parse_tv.py delete mode 100644 examples/parse_xml.py delete mode 100644 examples/parse_yaml.py create mode 100644 spdx/parsers/parse_anything.py create mode 100644 tests/test_parse_anything.py diff --git a/examples/parse_json.py b/examples/parse_json.py deleted file mode 100644 index 408b88362..000000000 --- a/examples/parse_json.py +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env python - -# Parses an JSON file and prints out some basic information. -# Usage: parse_json.py - - -def parse_JSON(file): - import spdx.file as spdxfile - from spdx.parsers.jsonparser import Parser - from spdx.parsers.loggers import StandardLogger - from spdx.parsers.jsonyamlxmlbuilders import Builder - - p = Parser(Builder(), StandardLogger()) - with open(file) as f: - doc, error = p.parse(f) - if not error: - print("doc comment: {0}".format(doc.comment)) - print("Creators:") - for c in doc.creation_info.creators: - print("\t{0}".format(c)) - print("Document review information:") - for review in doc.reviews: - print("\tReviewer: {0}".format(review.reviewer)) - print("\tDate: {0}".format(review.review_date)) - print("\tComment: {0}".format(review.comment)) - print("Creation comment: {0}".format(doc.creation_info.comment)) - print("Package Name: {0}".format(doc.package.name)) - print("Package Version: {0}".format(doc.package.version)) - print( - "Package Download Location: {0}".format(doc.package.download_location) - ) - print("Package Homepage: {0}".format(doc.package.homepage)) - print("Package Checksum: {0}".format(doc.package.check_sum.value)) - print("Package verification code: {0}".format(doc.package.verif_code)) - print( - "Package excluded from verif: {0}".format( - ",".join(doc.package.verif_exc_files) - ) - ) - print("Package license concluded: {0}".format(doc.package.conc_lics)) - print("Package license declared: {0}".format(doc.package.license_declared)) - print("Package licenses from files:") - for lics in doc.package.licenses_from_files: - print("\t{0}".format(lics)) - print("Package Copyright text: {0}".format(doc.package.cr_text)) - print("Package summary: {0}".format(doc.package.summary)) - print("Package description: {0}".format(doc.package.description)) - print("Package Files:") - VALUES = { - spdxfile.FileType.SOURCE: "SOURCE", - spdxfile.FileType.OTHER: "OTHER", - spdxfile.FileType.BINARY: "BINARY", - spdxfile.FileType.ARCHIVE: "ARCHIVE", - } - for f in doc.files: - print("\tFile name: {0}".format(f.name)) - print("\tFile type: {0}".format(VALUES[f.type])) - print("\tFile Checksum: {0}".format(f.chk_sum.value)) - print("\tFile license concluded: {0}".format(f.conc_lics)) - print( - "\tFile license info in file: {0}".format( - ",".join(map(lambda l: l.identifier, f.licenses_in_file)) - ) - ) - print( - "\tFile artifact of project name: {0}".format( - ",".join(f.artifact_of_project_name) - ) - ) - - print("Document Extracted licenses:") - for lics in doc.extracted_licenses: - print("\tIdentifier: {0}".format(lics.identifier)) - print("\tName: {0}".format(lics.full_name)) - print("Annotations:") - for an in doc.annotations: - print("\tAnnotator: {0}".format(an.annotator)) - print("\tAnnotation Date: {0}".format(an.annotation_date)) - print("\tAnnotation Comment: {0}".format(an.comment)) - print("\tAnnotation Type: {0}".format(an.annotation_type)) - print("\tAnnotation SPDX Identifier: {0}".format(an.spdx_id)) - - print("Relationships: ") - for rel in doc.relationships: - print("\tRelationship: {0}".format(rel.relationship)) - print("\tRelationship Comment: {0}".format(rel.relationship_comment)) - - else: - print("Errors while parsing") - - -if __name__ == "__main__": - import sys - - file = sys.argv[1] - parse_JSON(file) diff --git a/examples/parse_rdf.py b/examples/parse_rdf.py deleted file mode 100755 index 0b6f8b181..000000000 --- a/examples/parse_rdf.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/env python - -# Parses an RDF file and prints out some basic information. -# Usage: parse_rdf.py - -def parse_RDF(file): - import spdx.file as spdxfile - from spdx.parsers.rdf import Parser - from spdx.parsers.loggers import StandardLogger - from spdx.parsers.rdfbuilders import Builder - - p = Parser(Builder(), StandardLogger()) - with open(file) as f: - doc, error = p.parse(f) - if not error: - print("doc comment: {0}".format(doc.comment)) - print("Creators:") - for c in doc.creation_info.creators: - print("\t{0}".format(c)) - print("Document review information:") - for review in doc.reviews: - print("\tReviewer: {0}".format(review.reviewer)) - print("\tDate: {0}".format(review.review_date)) - print("\tComment: {0}".format(review.comment)) - print("Creation comment: {0}".format(doc.creation_info.comment)) - print("Package Name: {0}".format(doc.package.name)) - print("Package Version: {0}".format(doc.package.version)) - print( - "Package Download Location: {0}".format(doc.package.download_location) - ) - print("Package Homepage: {0}".format(doc.package.homepage)) - print("Package Checksum: {0}".format(doc.package.check_sum.value)) - print("Package Attribution Text: {0}".format(doc.package.attribution_text)) - print("Package verification code: {0}".format(doc.package.verif_code)) - print( - "Package excluded from verif: {0}".format( - ",".join(doc.package.verif_exc_files) - ) - ) - print("Package license concluded: {0}".format(doc.package.conc_lics)) - print("Package license declared: {0}".format(doc.package.license_declared)) - print("Package licenses from files:") - for lics in doc.package.licenses_from_files: - print("\t{0}".format(lics)) - print("Package Copyright text: {0}".format(doc.package.cr_text)) - print("Package summary: {0}".format(doc.package.summary)) - print("Package description: {0}".format(doc.package.description)) - print("Package Files:") - VALUES = { - spdxfile.FileType.SOURCE: "SOURCE", - spdxfile.FileType.OTHER: "OTHER", - spdxfile.FileType.BINARY: "BINARY", - spdxfile.FileType.ARCHIVE: "ARCHIVE", - } - for f in doc.files: - print("\tFile name: {0}".format(f.name)) - print("\tFile type: {0}".format(VALUES[f.type])) - print("\tFile Checksum: {0}".format(f.chk_sum.value)) - print("\tFile license concluded: {0}".format(f.conc_lics)) - print( - "\tFile license info in file: {0}".format( - ",".join(map(lambda l: l.identifier, f.licenses_in_file)) - ) - ) - print( - "\tFile artifact of project name: {0}".format( - ",".join(f.artifact_of_project_name) - ) - ) - - print("Document Extracted licenses:") - for lics in doc.extracted_licenses: - print("\tIdentifier: {0}".format(lics.identifier)) - print("\tName: {0}".format(lics.full_name)) - - print("Annotations:") - for an in doc.annotations: - print("\tAnnotator: {0}".format(an.annotator)) - print("\tAnnotation Date: {0}".format(an.annotation_date)) - print("\tAnnotation Comment: {0}".format(an.comment)) - print("\tAnnotation Type: {0}".format(an.annotation_type)) - print("\tAnnotation SPDX Identifier: {0}".format(an.spdx_id)) - - # print(doc.__dict__) - - print("Relationships: ") - for relation in doc.relationships: - print("\tRelationship: {0}".format(relation.relationship)) - try: - print("\tRelationship: {0}".format(relation.comment)) - except: - continue - - else: - print("Errors while parsing") - - -if __name__ == "__main__": - import sys - - file = sys.argv[1] - parse_RDF(file) diff --git a/examples/parse_tv.py b/examples/parse_tv.py deleted file mode 100755 index 0db66a27c..000000000 --- a/examples/parse_tv.py +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env python - -# Parses a tag/value file and prints out some basic information. -# Usage: parse_tv.py - -def parse_TAG(file): - from spdx.parsers.tagvalue import Parser - from spdx.parsers.loggers import StandardLogger - from spdx.parsers.tagvaluebuilders import Builder - - p = Parser(Builder(), StandardLogger()) - p.build() - with open(file) as f: - data = f.read() - document, error = p.parse(data) - if not error: - print("Parsing Successful") - print( - "Document Version {0}.{1}".format( - document.version.major, document.version.minor - ) - ) - print("Package name : {0}".format(document.package.name)) - print("Creators : ") - for creator in document.creation_info.creators: - print(creator.name) - else: - print("Errors encountered while parsing") - - -if __name__ == "__main__": - import sys - - file = sys.argv[1] - parse_TAG(file) diff --git a/examples/parse_xml.py b/examples/parse_xml.py deleted file mode 100644 index ce2e6959b..000000000 --- a/examples/parse_xml.py +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/env python - -# Parses an XML file and prints out some basic information. -# Usage: parse_xml.py -def parse_XML(file): - import spdx.file as spdxfile - from spdx.parsers.xmlparser import Parser - from spdx.parsers.loggers import StandardLogger - from spdx.parsers.jsonyamlxmlbuilders import Builder - - p = Parser(Builder(), StandardLogger()) - with open(file) as f: - doc, error = p.parse(f) - if not error: - print("doc comment: {0}".format(doc.comment)) - print("Creators:") - for c in doc.creation_info.creators: - print("\t{0}".format(c)) - print("Document review information:") - for review in doc.reviews: - print("\tReviewer: {0}".format(review.reviewer)) - print("\tDate: {0}".format(review.review_date)) - print("\tComment: {0}".format(review.comment)) - print("Creation comment: {0}".format(doc.creation_info.comment)) - print("Package Name: {0}".format(doc.package.name)) - print("Package Version: {0}".format(doc.package.version)) - print( - "Package Download Location: {0}".format(doc.package.download_location) - ) - print("Package Homepage: {0}".format(doc.package.homepage)) - print("Package Checksum: {0}".format(doc.package.check_sum.value)) - print("Package Attribution Text: {0}".format(doc.package.attribution_text)) - print("Package verification code: {0}".format(doc.package.verif_code)) - print( - "Package excluded from verif: {0}".format( - ",".join(doc.package.verif_exc_files) - ) - ) - print("Package license concluded: {0}".format(doc.package.conc_lics)) - print("Package license declared: {0}".format(doc.package.license_declared)) - print("Package licenses from files:") - for lics in doc.package.licenses_from_files: - print("\t{0}".format(lics)) - print("Package Copyright text: {0}".format(doc.package.cr_text)) - print("Package summary: {0}".format(doc.package.summary)) - print("Package description: {0}".format(doc.package.description)) - print("Package Files:") - VALUES = { - spdxfile.FileType.SOURCE: "SOURCE", - spdxfile.FileType.OTHER: "OTHER", - spdxfile.FileType.BINARY: "BINARY", - spdxfile.FileType.ARCHIVE: "ARCHIVE", - } - for f in doc.files: - print("\tFile name: {0}".format(f.name)) - print("\tFile type: {0}".format(VALUES[f.type])) - print("\tFile Checksum: {0}".format(f.chk_sum.value)) - print("\tFile license concluded: {0}".format(f.conc_lics)) - print( - "\tFile license info in file: {0}".format( - ",".join(map(lambda l: l.identifier, f.licenses_in_file)) - ) - ) - print( - "\tFile artifact of project name: {0}".format( - ",".join(f.artifact_of_project_name) - ) - ) - - print("Document Extracted licenses:") - for lics in doc.extracted_licenses: - print("\tIdentifier: {0}".format(lics.identifier)) - print("\tName: {0}".format(lics.full_name)) - print("Annotations:") - for an in doc.annotations: - print("\tAnnotator: {0}".format(an.annotator)) - print("\tAnnotation Date: {0}".format(an.annotation_date)) - print("\tAnnotation Comment: {0}".format(an.comment)) - print("\tAnnotation Type: {0}".format(an.annotation_type)) - print("\tAnnotation SPDX Identifier: {0}".format(an.spdx_id)) - print("Relationships: ") - for rel in doc.relationships: - print("\tRelationship: {0}".format(rel.relationship)) - print("\tRelationship Comment: {0}".format(rel.relationship_comment)) - - else: - print("Errors while parsing") - - -if __name__ == "__main__": - import sys - - file = sys.argv[1] - parse_XML(file) diff --git a/examples/parse_yaml.py b/examples/parse_yaml.py deleted file mode 100644 index 31fbecbef..000000000 --- a/examples/parse_yaml.py +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env python - -# Parses an YAML file and prints out some basic information. -# Usage: parse_yaml.py - - -def parse_YAML(file): - import spdx.file as spdxfile - from spdx.parsers.yamlparser import Parser - from spdx.parsers.loggers import StandardLogger - from spdx.parsers.jsonyamlxmlbuilders import Builder - - p = Parser(Builder(), StandardLogger()) - with open(file) as f: - doc, error = p.parse(f) - if not error: - print("doc comment: {0}".format(doc.comment)) - print("Creators:") - for c in doc.creation_info.creators: - print("\t{0}".format(c)) - print("Document review information:") - for review in doc.reviews: - print("\tReviewer: {0}".format(review.reviewer)) - print("\tDate: {0}".format(review.review_date)) - print("\tComment: {0}".format(review.comment)) - print("Creation comment: {0}".format(doc.creation_info.comment)) - print("Package Name: {0}".format(doc.package.name)) - print("Package Version: {0}".format(doc.package.version)) - print( - "Package Download Location: {0}".format(doc.package.download_location) - ) - print("Package Homepage: {0}".format(doc.package.homepage)) - print("Package Checksum: {0}".format(doc.package.check_sum.value)) - print("Package Attribution Text: {0}".format(doc.package.attribution_text)) - print("Package verification code: {0}".format(doc.package.verif_code)) - print( - "Package excluded from verif: {0}".format( - ",".join(doc.package.verif_exc_files) - ) - ) - print("Package license concluded: {0}".format(doc.package.conc_lics)) - print("Package license declared: {0}".format(doc.package.license_declared)) - print("Package licenses from files:") - for lics in doc.package.licenses_from_files: - print("\t{0}".format(lics)) - print("Package Copyright text: {0}".format(doc.package.cr_text)) - print("Package summary: {0}".format(doc.package.summary)) - print("Package description: {0}".format(doc.package.description)) - print("Package Files:") - VALUES = { - spdxfile.FileType.SOURCE: "SOURCE", - spdxfile.FileType.OTHER: "OTHER", - spdxfile.FileType.BINARY: "BINARY", - spdxfile.FileType.ARCHIVE: "ARCHIVE", - } - for f in doc.files: - print("\tFile name: {0}".format(f.name)) - print("\tFile type: {0}".format(VALUES[f.type])) - print("\tFile Checksum: {0}".format(f.chk_sum.value)) - print("\tFile license concluded: {0}".format(f.conc_lics)) - print( - "\tFile license info in file: {0}".format( - ",".join(map(lambda l: l.identifier, f.licenses_in_file)) - ) - ) - print( - "\tFile artifact of project name: {0}".format( - ",".join(f.artifact_of_project_name) - ) - ) - - print("Document Extracted licenses:") - for lics in doc.extracted_licenses: - print("\tIdentifier: {0}".format(lics.identifier)) - print("\tName: {0}".format(lics.full_name)) - print("Annotations:") - for an in doc.annotations: - print("\tAnnotator: {0}".format(an.annotator)) - print("\tAnnotation Date: {0}".format(an.annotation_date)) - print("\tAnnotation Comment: {0}".format(an.comment)) - print("\tAnnotation Type: {0}".format(an.annotation_type)) - print("\tAnnotation SPDX Identifier: {0}".format(an.spdx_id)) - print("Relationships: ") - for rel in doc.relationships: - print("\tRelationship: {0}".format(rel.relationship)) - print("\tRelationship Comment: {0}".format(rel.relationship_comment)) - - else: - print("Errors while parsing") - - -if __name__ == "__main__": - import sys - - file = sys.argv[1] - parse_YAML(file) diff --git a/spdx/cli_tools/parser.py b/spdx/cli_tools/parser.py index c203b50ea..b3fb007bd 100755 --- a/spdx/cli_tools/parser.py +++ b/spdx/cli_tools/parser.py @@ -12,90 +12,107 @@ # limitations under the License. import os -from examples.parse_json import parse_JSON -from examples.parse_rdf import parse_RDF -from examples.parse_tv import parse_TAG -from examples.parse_yaml import parse_YAML -from examples.parse_xml import parse_XML -from spdx.parsers.builderexceptions import FileTypeError +from spdx.parsers.parse_anything import parse_file +import spdx.file as spdxfile import click @click.command() -# @click.argument('file') @click.option("--file", prompt="File name", help="The file to be parsed") -def main(file): +@click.option("--force", action="store_true", help="print information even if there are some parsing errors") +def main(file, force): """ COMMAND-LINE TOOL for parsing file of RDF, XML, JSON, YAML and XML format. To use : run `parser` using terminal or run `parser --file ` """ - if file.endswith(".rdf"): - parsed_result = parse_rdf(file) - click.echo(parsed_result) - elif file.endswith(".rdf.xml"): - parsed_result = parse_rdf(file) - click.echo(parsed_result) - elif file.endswith(".spdx"): - parsed_result = parse_tag(file) - click.echo(parsed_result) - elif file.endswith(".tag"): - parsed_result = parse_tag(file) - click.echo(parsed_result) - elif file.endswith(".json"): - parsed_result = parse_json(file) - click.echo(parsed_result) - elif file.endswith(".xml"): - parsed_result = parse_xml(file) - click.echo(parsed_result) - elif file.endswith(".yaml"): - parsed_result = parse_yaml(file) - click.echo(parsed_result) - else: - raise FileTypeError("FileType Not Supported") - - -def parse_json(file): - file = str(file) - try: - return parse_JSON(os.path.join(file)) - except EnvironmentError as e: - print(os.strerror(e.errno)) - - -def parse_rdf(file): - file = str(file) - try: - return parse_RDF(os.path.join(file)) - except EnvironmentError as e: - print(os.strerror(e.errno)) - - -def parse_tag(file): - file = str(file) - try: - return parse_TAG(os.path.join(file)) - except EnvironmentError as e: - print(os.strerror(e.errno)) - - -def parse_yaml(file): - file = str(file) - try: - return parse_YAML(os.path.join(file)) - except EnvironmentError as e: - print(os.strerror(e.errno)) - - -def parse_xml(file): - file = str(file) - try: - return parse_XML(os.path.join(file)) - except EnvironmentError as e: - print(os.strerror(e.errno)) - + doc, errors = parse_file(file) + if errors: + print("Errors while parsing: ", errors) + if not force: + return 1 + + print("doc comment: {0}".format(doc.comment)) + print("Creators:") + for c in doc.creation_info.creators: + print("\t{0}".format(c)) + print("Document review information:") + for review in doc.reviews: + print("\tReviewer: {0}".format(review.reviewer)) + print("\tDate: {0}".format(review.review_date)) + print("\tComment: {0}".format(review.comment)) + print("Creation comment: {0}".format(doc.creation_info.comment)) + print("Package Name: {0}".format(doc.package.name)) + print("Package Version: {0}".format(doc.package.version)) + print( + "Package Download Location: {0}".format(doc.package.download_location) + ) + print("Package Homepage: {0}".format(doc.package.homepage)) + if doc.package.check_sum: + print("Package Checksum: {0}".format(doc.package.check_sum.value)) + print("Package Attribution Text: {0}".format(doc.package.attribution_text)) + print("Package verification code: {0}".format(doc.package.verif_code)) + print( + "Package excluded from verif: {0}".format( + ",".join(doc.package.verif_exc_files) + ) + ) + print("Package license concluded: {0}".format(doc.package.conc_lics)) + print("Package license declared: {0}".format(doc.package.license_declared)) + print("Package licenses from files:") + for lics in doc.package.licenses_from_files: + print("\t{0}".format(lics)) + print("Package Copyright text: {0}".format(doc.package.cr_text)) + print("Package summary: {0}".format(doc.package.summary)) + print("Package description: {0}".format(doc.package.description)) + print("Package Files:") + VALUES = { + spdxfile.FileType.SOURCE: "SOURCE", + spdxfile.FileType.OTHER: "OTHER", + spdxfile.FileType.BINARY: "BINARY", + spdxfile.FileType.ARCHIVE: "ARCHIVE", + } + for f in doc.files: + print("\tFile name: {0}".format(f.name)) + print("\tFile type: {0}".format(VALUES[f.type])) + print("\tFile Checksum: {0}".format(f.chk_sum.value)) + print("\tFile license concluded: {0}".format(f.conc_lics)) + print( + "\tFile license info in file: {0}".format( + ",".join(map(lambda l: l.identifier, f.licenses_in_file)) + ) + ) + print( + "\tFile artifact of project name: {0}".format( + ",".join(f.artifact_of_project_name) + ) + ) + + print("Document Extracted licenses:") + for lics in doc.extracted_licenses: + print("\tIdentifier: {0}".format(lics.identifier)) + print("\tName: {0}".format(lics.full_name)) + print("\License Text: {0}".format(lics.text)) + + print("Annotations:") + for an in doc.annotations: + print("\tAnnotator: {0}".format(an.annotator)) + print("\tAnnotation Date: {0}".format(an.annotation_date)) + print("\tAnnotation Comment: {0}".format(an.comment)) + print("\tAnnotation Type: {0}".format(an.annotation_type)) + print("\tAnnotation SPDX Identifier: {0}".format(an.spdx_id)) + + # print(doc.__dict__) + + print("Relationships: ") + for relation in doc.relationships: + print("\tRelationship: {0}".format(relation.relationship)) + try: + print("\tRelationship: {0}".format(relation.comment)) + except: + continue if __name__ == "__main__": main() diff --git a/spdx/parsers/parse_anything.py b/spdx/parsers/parse_anything.py new file mode 100644 index 000000000..94363b106 --- /dev/null +++ b/spdx/parsers/parse_anything.py @@ -0,0 +1,54 @@ +# Copyright (c) spdx contributors +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import spdx.file as spdxfile +from spdx.parsers import jsonparser +from spdx.parsers import yamlparser +from spdx.parsers import rdf +from spdx.parsers import xmlparser +from spdx.parsers import tagvalue +from spdx.parsers.loggers import StandardLogger +from spdx.parsers import jsonyamlxmlbuilders, tagvaluebuilders, rdfbuilders +from spdx.parsers.builderexceptions import FileTypeError + + +def parse_file(fn): + buildermodule = jsonyamlxmlbuilders + read_data = False + if fn.endswith(".rdf") or fn.endswith(".rdf.xml"): + parsing_module = rdf + buildermodule = rdfbuilders + elif fn.endswith(".spdx"): + parsing_module = rdf + buildermodule = rdfbuilders + elif fn.endswith(".tag"): + parsing_module = tagvalue + buildermodule = tagvaluebuilders + read_data = True + elif fn.endswith(".json"): + parsing_module = jsonparser + elif fn.endswith(".xml"): + parsing_module = xmlparser + elif fn.endswith(".yaml"): + parsing_module = yamlparser + else: + raise FileTypeError("FileType Not Supported") + + p = parsing_module.Parser(buildermodule.Builder(), StandardLogger()) + if hasattr(p, "build"): + p.build() + with open(fn) as f: + if read_data: + data = f.read() + return p.parse(data) + else: + return p.parse(f) diff --git a/tests/test_parse_anything.py b/tests/test_parse_anything.py new file mode 100644 index 000000000..2942d9c99 --- /dev/null +++ b/tests/test_parse_anything.py @@ -0,0 +1,34 @@ +# Copyright (c) 2021 spdx tool contributors +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import, print_function, unicode_literals + +import io +import json +import os + +import pytest +from spdx.parsers import parse_anything + + +dirname = os.path.join(os.path.dirname(__file__), "data", "formats") +test_files = [os.path.join(dirname, fn) for fn in os.listdir(dirname)] + + +@pytest.mark.parametrize("test_file", test_files) +def test_parse_anything(test_file): + doc, error = parse_anything.parse_file(test_file) + + assert not error + + # test a few fields, the core of the tests are per parser + assert doc.name == 'Sample_Document-V2.1' + assert doc.comment in ('This is a sample spreadsheet', 'Sample Comment') \ No newline at end of file From 56d16164d084c58382c102818dd119e941cc5bd7 Mon Sep 17 00:00:00 2001 From: Pierre Tardy Date: Fri, 25 Jun 2021 16:38:51 +0200 Subject: [PATCH 02/10] factorize convertor instead of having the same boilerplate in all the convertors, we just factorize in a single function that can output any format according to the file extension The tests show that the conversion is not fully stable. fixing that is out of scope of this commit, and requires more investigation Signed-off-by: Pierre Tardy --- examples/rdf_to_json.py | 30 -------- examples/rdf_to_tv.py | 41 ----------- examples/rdf_to_xml.py | 29 -------- examples/rdf_to_yaml.py | 29 -------- examples/tv_to_json.py | 30 -------- examples/tv_to_rdf.py | 36 ---------- examples/tv_to_xml.py | 30 -------- examples/tv_to_yaml.py | 30 -------- spdx/cli_tools/convertor.py | 123 +++------------------------------ spdx/writers/write_anything.py | 38 ++++++++++ tests/test_write_anything.py | 69 ++++++++++++++++++ 11 files changed, 117 insertions(+), 368 deletions(-) delete mode 100644 examples/rdf_to_json.py delete mode 100755 examples/rdf_to_tv.py delete mode 100644 examples/rdf_to_xml.py delete mode 100644 examples/rdf_to_yaml.py delete mode 100644 examples/tv_to_json.py delete mode 100644 examples/tv_to_rdf.py delete mode 100644 examples/tv_to_xml.py delete mode 100644 examples/tv_to_yaml.py create mode 100644 spdx/writers/write_anything.py create mode 100644 tests/test_write_anything.py diff --git a/examples/rdf_to_json.py b/examples/rdf_to_json.py deleted file mode 100644 index 379530a1c..000000000 --- a/examples/rdf_to_json.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python - - -def RDF_to_JSON(input_file, out_file): - # if __name__ == "__main__": - import sys - from spdx.parsers.rdf import Parser - from spdx.parsers.loggers import StandardLogger - from spdx.parsers.rdfbuilders import Builder - from spdx.writers.json import write_document - - # input_file = sys.argv[1] - # out_file = sys.argv[2] - p = Parser(Builder(), StandardLogger()) - with open(input_file) as f: - document, error = p.parse(f) - - if not error: - with open(out_file, "w") as out: - write_document(document, out) - else: - print("Errors encountered while parsing") - - -if __name__ == "__main__": - import sys - - in_file = sys.argv[1] - out_file = sys.argv[2] - RDF_to_JSON(in_file, out_file) diff --git a/examples/rdf_to_tv.py b/examples/rdf_to_tv.py deleted file mode 100755 index 0c2009737..000000000 --- a/examples/rdf_to_tv.py +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env python - -# Converts an RDF file to tag/value format. -# Usage: rdf_to_tv - -def RDF_to_TAG(infile_name, outfile_name): - # if __name__ == "__main__": - # import sys - import codecs - from spdx.parsers.rdf import Parser - from spdx.parsers.loggers import StandardLogger - from spdx.parsers.rdfbuilders import Builder - from spdx.writers.tagvalue import write_document, InvalidDocumentError - - # infile_name = sys.argv[1] - # outfile_name = sys.argv[2] - rdfparser = Parser(Builder(), StandardLogger()) - with open(infile_name) as infile: - document, error = rdfparser.parse(infile) - if not error: - # print(map(lambda c: c.name, document.creation_info.creators)) - print("Parsing Successful") - with codecs.open(outfile_name, mode="w", encoding="utf-8") as outfile: - try: - write_document(document, outfile) - except InvalidDocumentError: - # Note document is valid if error is False - print("Document is Invalid") - else: - print("Errors encountered while parsing RDF file.") - messages = [] - document.validate(messages) - print("\n".join(messages)) - - -if __name__ == "__main__": - import sys - - in_file = sys.argv[1] - out_file = sys.argv[2] - RDF_to_TAG(in_file, out_file) diff --git a/examples/rdf_to_xml.py b/examples/rdf_to_xml.py deleted file mode 100644 index 58a0d6bb0..000000000 --- a/examples/rdf_to_xml.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python - - -def RDF_to_XML(infile_name, outfile_name): - # if __name__ == "__main__": - # import sys - from spdx.parsers.rdf import Parser - from spdx.parsers.loggers import StandardLogger - from spdx.parsers.rdfbuilders import Builder - from spdx.writers.xml import write_document - - # file = sys.argv[1] - p = Parser(Builder(), StandardLogger()) - with open(infile_name) as f: - document, error = p.parse(f) - - if not error: - with open(outfile_name, "w") as out: - write_document(document, out) - else: - print("Errors encountered while parsing") - - -if __name__ == "__main__": - import sys - - in_file = sys.argv[1] - out_file = sys.argv[2] - RDF_to_XML(in_file, out_file) diff --git a/examples/rdf_to_yaml.py b/examples/rdf_to_yaml.py deleted file mode 100644 index f77ae73b0..000000000 --- a/examples/rdf_to_yaml.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python - - -def RDF_to_YAML(infile_name, outfile_name): - # if __name__ == "__main__": - # import sys - from spdx.parsers.rdf import Parser - from spdx.parsers.loggers import StandardLogger - from spdx.parsers.rdfbuilders import Builder - from spdx.writers.yaml import write_document - - # file = sys.argv[1] - p = Parser(Builder(), StandardLogger()) - with open(infile_name) as f: - document, error = p.parse(f) - - if not error: - with open(outfile_name, "w") as out: - write_document(document, out) - else: - print("Errors encountered while parsing") - - -if __name__ == "__main__": - import sys - - in_file = sys.argv[1] - out_file = sys.argv[2] - RDF_to_YAML(in_file, out_file) diff --git a/examples/tv_to_json.py b/examples/tv_to_json.py deleted file mode 100644 index f0f88be85..000000000 --- a/examples/tv_to_json.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python - - -def TAG_to_JSON(infile_name, outfile_name): - # if __name__ == "__main__": - # import sys - from spdx.parsers.tagvalue import Parser - from spdx.parsers.loggers import StandardLogger - from spdx.parsers.tagvaluebuilders import Builder - from spdx.writers.json import write_document - - # file = sys.argv[1] - p = Parser(Builder(), StandardLogger()) - p.build() - with open(infile_name) as f: - data = f.read() - document, error = p.parse(data) - if not error: - with open(outfile_name, "w") as out: - write_document(document, out) - else: - print("Errors encountered while parsing") - - -if __name__ == "__main__": - import sys - - in_file = sys.argv[1] - out_file = sys.argv[2] - TAG_to_JSON(in_file, out_file) diff --git a/examples/tv_to_rdf.py b/examples/tv_to_rdf.py deleted file mode 100644 index 0cd7c254c..000000000 --- a/examples/tv_to_rdf.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python - -""" -Converts an tag/value file to RDF format. -Usage: tv_to_rdf -""" -import sys -import codecs -from spdx.parsers.tagvalue import Parser -from spdx.parsers.loggers import StandardLogger -from spdx.parsers.tagvaluebuilders import Builder -from spdx.writers.rdf import write_document, InvalidDocumentError - - -def TAG_to_RDF(infile_name, outfile_name): - tagvalueparser = Parser(Builder(), StandardLogger()) - tagvalueparser.build() - with open(infile_name) as infile: - data = infile.read() - document, error = tagvalueparser.parse(data) - if not error: - # print(map(lambda c: c.name, document.creation_info.creators)) - print("Parsing Successful") - with open(outfile_name, mode="w") as out: - write_document(document, out, validate=True) - else: - print("Errors encountered while parsing tag value file.") - messages = [] - document.validate(messages) - print("\n".join(messages)) - - -if __name__ == "__main__": - infile_name = sys.argv[1] - outfile_name = sys.argv[2] - TAG_to_RDF(infile_name, outfile_name) diff --git a/examples/tv_to_xml.py b/examples/tv_to_xml.py deleted file mode 100644 index 53cb142de..000000000 --- a/examples/tv_to_xml.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python - - -def TAG_to_XML(infile_name, outfile_name): - # if __name__ == "__main__": - # import sys - from spdx.parsers.tagvalue import Parser - from spdx.parsers.loggers import StandardLogger - from spdx.parsers.tagvaluebuilders import Builder - from spdx.writers.xml import write_document - - # file = sys.argv[1] - p = Parser(Builder(), StandardLogger()) - p.build() - with open(infile_name) as f: - data = f.read() - document, error = p.parse(data) - if not error: - with open(outfile_name, "w") as out: - write_document(document, out) - else: - print("Errors encountered while parsing") - - -if __name__ == "__main__": - import sys - - in_file = sys.argv[1] - out_file = sys.argv[2] - TAG_to_XML(in_file, out_file) diff --git a/examples/tv_to_yaml.py b/examples/tv_to_yaml.py deleted file mode 100644 index 826d89cf7..000000000 --- a/examples/tv_to_yaml.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python - - -def TAG_to_YAML(infile_name, outfile_name): - # if __name__ == "__main__": - # import sys - from spdx.parsers.tagvalue import Parser - from spdx.parsers.loggers import StandardLogger - from spdx.parsers.tagvaluebuilders import Builder - from spdx.writers.yaml import write_document - - # file = sys.argv[1] - p = Parser(Builder(), StandardLogger()) - p.build() - with open(infile_name) as f: - data = f.read() - document, error = p.parse(data) - if not error: - with open(outfile_name, "w") as out: - write_document(document, out) - else: - print("Errors encountered while parsing") - - -if __name__ == "__main__": - import sys - - in_file = sys.argv[1] - out_file = sys.argv[2] - TAG_to_YAML(in_file, out_file) diff --git a/spdx/cli_tools/convertor.py b/spdx/cli_tools/convertor.py index f761f2673..901d8627e 100644 --- a/spdx/cli_tools/convertor.py +++ b/spdx/cli_tools/convertor.py @@ -12,15 +12,9 @@ # limitations under the License. import os -from examples.rdf_to_json import RDF_to_JSON -from examples.rdf_to_tv import RDF_to_TAG -from examples.rdf_to_xml import RDF_to_XML -from examples.rdf_to_yaml import RDF_to_YAML -from examples.tv_to_json import TAG_to_JSON -from examples.tv_to_rdf import TAG_to_RDF -from examples.tv_to_xml import TAG_to_XML -from examples.tv_to_yaml import TAG_to_YAML from spdx.parsers.builderexceptions import FileTypeError +from spdx.parsers.parse_anything import parse_file +from spdx.writers.write_anything import write_file import click @@ -42,7 +36,8 @@ type=click.Choice(["tag", "rdf"], case_sensitive=False), default="undefined", ) -def main(infile, outfile, src, from_, to): +@click.option("--force", action="store_true", help="convert even if there are some parsing errors or inconsistencies") +def main(infile, outfile, src, from_, to, force): """ CLI-TOOL for converting a RDF or TAG file to RDF, JSON, YAML, TAG or XML format. @@ -82,111 +77,13 @@ def main(infile, outfile, src, from_, to): outfile_path = os.path.splitext(outfile)[0] outfile = outfile_path + "." + to - if infile.endswith(".rdf"): - infile_format = "rdf" - elif infile.endswith(".tag"): - infile_format = "tag" - else: - raise FileTypeError( - "INPUT FILETYPE NOT SUPPORTED. (only RDF and TAG format supported)" - ) + doc, errors = parse_file(infile) + if errors: + print("Errors while parsing: ", errors) + if not force: + return 1 - if outfile.endswith(".rdf"): - outfile_format = "rdf" - elif outfile.endswith(".tag"): - outfile_format = "tag" - elif outfile.endswith(".json"): - outfile_format = "json" - elif outfile.endswith(".xml"): - outfile_format = "xml" - elif outfile.endswith(".yaml"): - outfile_format = "yaml" - elif outfile.endswith(".spdx"): - outfile_format = "tag" - elif outfile.endswith(".rdf.xml"): - outfile_format = "rdf" - else: - raise FileTypeError("OUTFILE FILETYPE NOT SUPPORTED") - - try: - func_to_call = infile_format + "_to_" + outfile_format - result = globals()[func_to_call](infile, outfile) - click.echo(result) - except EnvironmentError as e: - print(os.strerror(e.errno)) - - -def rdf_to_json(infile, outfile): - infile = str(infile) - outfile = str(outfile) - try: - return RDF_to_JSON(os.path.join(infile), os.path.join(outfile)) - except EnvironmentError as e: - print(os.strerror(e.errno)) - - -def rdf_to_tag(infile, outfile): - infile = str(infile) - outfile = str(outfile) - try: - return RDF_to_TAG(os.path.join(infile), os.path.join(outfile)) - except EnvironmentError as e: - print(os.strerror(e.errno)) - - -def rdf_to_yaml(infile, outfile): - infile = str(infile) - outfile = str(outfile) - try: - return RDF_to_YAML(os.path.join(infile), os.path.join(outfile)) - except EnvironmentError as e: - # OSError or IOError... - print(os.strerror(e.errno)) - - -def rdf_to_xml(infile, outfile): - infile = str(infile) - outfile = str(outfile) - try: - return RDF_to_XML(os.path.join(infile), os.path.join(outfile)) - except EnvironmentError as e: - print(os.strerror(e.errno)) - - -def tag_to_json(infile, outfile): - infile = str(infile) - outfile = str(outfile) - try: - return TAG_to_JSON(os.path.join(infile), os.path.join(outfile)) - except EnvironmentError as e: - print(os.strerror(e.errno)) - - -def tag_to_rdf(infile, outfile): - infile = str(infile) - outfile = str(outfile) - try: - return TAG_to_RDF(os.path.join(infile), os.path.join(outfile)) - except EnvironmentError as e: - print(os.strerror(e.errno)) - - -def tag_to_yaml(infile, outfile): - infile = str(infile) - outfile = str(outfile) - try: - return TAG_to_YAML(os.path.join(infile), os.path.join(outfile)) - except EnvironmentError as e: - print(os.strerror(e.errno)) - - -def tag_to_xml(infile, outfile): - infile = str(infile) - outfile = str(outfile) - try: - return TAG_to_XML(os.path.join(infile), os.path.join(outfile)) - except EnvironmentError as e: - print(os.strerror(e.errno)) + write_file(doc, outfile) if __name__ == "__main__": diff --git a/spdx/writers/write_anything.py b/spdx/writers/write_anything.py new file mode 100644 index 000000000..f75dd57a6 --- /dev/null +++ b/spdx/writers/write_anything.py @@ -0,0 +1,38 @@ +# Copyright (c) spdx contributors +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +from spdx.writers import json +from spdx.writers import yaml +from spdx.writers import rdf +from spdx.writers import xml +from spdx.writers import tagvalue +from spdx.parsers.builderexceptions import FileTypeError + + +def write_file(doc, fn): + out_mode = "w" + if fn.endswith(".rdf") or fn.endswith(".rdf.xml") or fn.endswith(".spdx"): + writer_module = rdf + out_mode = "wb" + elif fn.endswith(".tag"): + writer_module = tagvalue + elif fn.endswith(".json"): + writer_module = json + elif fn.endswith(".xml"): + writer_module = xml + elif fn.endswith(".yaml"): + writer_module = yaml + else: + raise FileTypeError("FileType Not Supported") + + with open(fn, out_mode) as out: + p = writer_module.write_document(doc, out) diff --git a/tests/test_write_anything.py b/tests/test_write_anything.py new file mode 100644 index 000000000..b07118af4 --- /dev/null +++ b/tests/test_write_anything.py @@ -0,0 +1,69 @@ +# Copyright (c) 2021 spdx tool contributors +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import, print_function, unicode_literals + +import os + +import pytest +from spdx.parsers import parse_anything +from spdx.writers import write_anything + +from tests import utils_test + +dirname = os.path.join(os.path.dirname(__file__), "data", "formats") +test_files = [os.path.join(dirname, fn) for fn in os.listdir(dirname)] +UNSTABLE_CONVERSIONS = [ + "rdf->rdf", + "yaml->rdf", + "xml->rdf", + "json->rdf", + "tag->rdf", + "rdf->yaml", + "tag->yaml", + "rdf->xml", + "tag->xml", + "rdf->json", + "tag->json", + "rdf->tag", + "yaml->tag", + "xml->tag", + "json->tag", + "tag->tag" +] + +@pytest.mark.parametrize("in_format", ['rdf', 'yaml', 'xml', 'json', 'tag']) +@pytest.mark.parametrize("out_format", ['rdf', 'yaml', 'xml', 'json', 'tag']) +def test_parse_anything(in_format, out_format, tmpdir): + + for in_file in test_files: + if in_file.endswith(in_format): + break + doc, error = parse_anything.parse_file(in_file) + + assert not error + result = utils_test.TestParserUtils.to_dict(doc) + + out_fn = os.path.join(tmpdir, "test." + out_format) + write_anything.write_file(doc, out_fn) + + doc2, error2 = parse_anything.parse_file(out_fn) + result2 = utils_test.TestParserUtils.to_dict(doc2) + assert not error2 + + test = in_format + "->" + out_format + if test not in UNSTABLE_CONVERSIONS: + assert result2 == result + else: + # if this test failed, this means we are more stable \o/ + # in that case, please remove the test from UNSTABLE_CONVERSIONS list + assert result2 != result, test + From 7586612a69c25f55d7852a4bd7fc7e83f24f860a Mon Sep 17 00:00:00 2001 From: Pierre Tardy Date: Wed, 21 Jul 2021 13:21:05 +0200 Subject: [PATCH 03/10] Fix comparison of UnKnown object leading to spurious difference in tests Signed-off-by: Pierre Tardy --- spdx/utils.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/spdx/utils.py b/spdx/utils.py index 55aa0aa99..ca8ab6fef 100644 --- a/spdx/utils.py +++ b/spdx/utils.py @@ -85,6 +85,11 @@ def to_value(self): def __str__(self): return self.to_value() + def __repr__(self): + return self.to_value() + + def __eq__(self, other): + return self.to_value() == other.to_value() class SPDXNone(object): """ From 3806abb56aa080cfa61dfa42976d48a7efcfdd3f Mon Sep 17 00:00:00 2001 From: Pierre Tardy Date: Wed, 21 Jul 2021 13:21:50 +0200 Subject: [PATCH 04/10] Fix uninitialized variable warning Signed-off-by: Pierre Tardy --- spdx/parsers/jsonyamlxml.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spdx/parsers/jsonyamlxml.py b/spdx/parsers/jsonyamlxml.py index ea71af012..2e2fb1d71 100644 --- a/spdx/parsers/jsonyamlxml.py +++ b/spdx/parsers/jsonyamlxml.py @@ -460,7 +460,7 @@ def parse_relationship(self, spdxelementid, relationshiptype, relatedspdxelement except SPDXValueError: self.value_error("RELATIONSHIP_VALUE", relate) else: - self.value_error("RELATIONSHIP_VALUE", relate) + self.value_error("RELATIONSHIP_VALUE", relationshiptype) def parse_relationship_comment(self, relationship_comment): """ From 11749fcf636cb551328bb55725c3e74704d44701 Mon Sep 17 00:00:00 2001 From: Pierre Tardy Date: Wed, 21 Jul 2021 13:22:52 +0200 Subject: [PATCH 05/10] add more coherency between parser to the default value for license full names Signed-off-by: Pierre Tardy --- spdx/document.py | 45 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/spdx/document.py b/spdx/document.py index cca777a70..b7dfdadce 100644 --- a/spdx/document.py +++ b/spdx/document.py @@ -89,8 +89,12 @@ def _add_parens(required, text): @total_ordering class License(object): def __init__(self, full_name, identifier): - self._full_name = full_name - self._identifier = identifier + """if one of the argument is None, we try to map as much as possible + """ + self._full_name = None + self._identifier = None + self.set_full_name(full_name) + self.set_identifier(identifier) @classmethod def from_identifier(cls, identifier): @@ -98,10 +102,7 @@ def from_identifier(cls, identifier): the full_name is retrieved from it. Otherwise the full_name is the same as the identifier. """ - if identifier in config.LICENSE_MAP.keys(): - return cls(config.LICENSE_MAP[identifier], identifier) - else: - return cls(identifier, identifier) + return cls(None, identifier) @classmethod def from_full_name(cls, full_name): @@ -110,10 +111,7 @@ def from_full_name(cls, full_name): config.LICENSE_MAP the identifier is retrieved from it. Otherwise the identifier is the same as the full_name. """ - if full_name in config.LICENSE_MAP.keys(): - return cls(full_name, config.LICENSE_MAP[full_name]) - else: - return cls(full_name, full_name) + return cls(full_name, None) @property def url(self): @@ -125,12 +123,39 @@ def full_name(self): @full_name.setter def full_name(self, value): + self.set_full_name(value) + + def set_full_name(self, value): + + if value is None: + return + if self._identifier is None: + if value in config.LICENSE_MAP: + self._identifier = config.LICENSE_MAP[value] + else: + self._identifier = value self._full_name = value @property def identifier(self): return self._identifier + @identifier.setter + def identifier(self, value): + self.set_identifier(value) + + def set_identifier(self, value): + if value is None: + return + if self._full_name is None: + if value in config.LICENSE_MAP: + self._full_name = config.LICENSE_MAP[value] + else: + self._full_name = value + + self._identifier = value + + def __eq__(self, other): return ( isinstance(other, License) From db7c42964321c907db6e54ca899396a5b09de893 Mon Sep 17 00:00:00 2001 From: Pierre Tardy Date: Wed, 21 Jul 2021 13:23:28 +0200 Subject: [PATCH 06/10] misc test improvements Signed-off-by: Pierre Tardy --- tests/test_write_anything.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_write_anything.py b/tests/test_write_anything.py index b07118af4..1f7e707dc 100644 --- a/tests/test_write_anything.py +++ b/tests/test_write_anything.py @@ -37,12 +37,11 @@ "yaml->tag", "xml->tag", "json->tag", - "tag->tag" ] @pytest.mark.parametrize("in_format", ['rdf', 'yaml', 'xml', 'json', 'tag']) @pytest.mark.parametrize("out_format", ['rdf', 'yaml', 'xml', 'json', 'tag']) -def test_parse_anything(in_format, out_format, tmpdir): +def test_write_anything(in_format, out_format, tmpdir): for in_file in test_files: if in_file.endswith(in_format): @@ -61,9 +60,10 @@ def test_parse_anything(in_format, out_format, tmpdir): test = in_format + "->" + out_format if test not in UNSTABLE_CONVERSIONS: - assert result2 == result + for k, v in result.items(): + assert v == result2[k], k + " differs" else: - # if this test failed, this means we are more stable \o/ + # if this test fails, this means we are more stable \o/ # in that case, please remove the test from UNSTABLE_CONVERSIONS list assert result2 != result, test From 49cab4bb6097f337737b3504606e50fcd0808dd8 Mon Sep 17 00:00:00 2001 From: Pierre Tardy Date: Thu, 22 Jul 2021 11:44:32 +0200 Subject: [PATCH 07/10] Use testfixture for better comparison error message Fix some test by regenerating the expected data Signed-off-by: Pierre Tardy --- .circleci/config.yml | 2 +- README.md | 9 +- appveyor.yml | 2 +- tests/data/doc_parse/expected.json | 384 +++++++++--------- tests/data/doc_parse/spdx-expected.json | 512 ++++++++++++------------ tests/test_jsonyamlxml_parser.py | 4 +- tests/test_rdf_parser.py | 27 +- tests/test_write_anything.py | 3 +- tests/utils_test.py | 6 + 9 files changed, 468 insertions(+), 481 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index bb31c5891..32a18c426 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -25,7 +25,7 @@ commands: steps: - run: | python setup.py install - python -m pip install pytest + python -m pip install pytest testfixtures - run: pytest jobs: diff --git a/README.md b/README.md index 816ff995e..1e6bc38cb 100644 --- a/README.md +++ b/README.md @@ -85,8 +85,13 @@ instead of `bin`. # How to run tests -From the project root directory run: `python setup.py test`. -You can use another test runner such as pytest or nose at your preference. +Tests framework is using pytest and testfixtures + +``` +pip install pytest testfixtures +pytest +``` + # Development process diff --git a/appveyor.yml b/appveyor.yml index 83fc722cc..cf9d6eb8b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,7 +11,7 @@ environment: install: - "%PYTHON_EXE% --version" - "%PYTHON_EXE% setup.py install" - - "%PYTHON_EXE% -m pip install pytest" + - "%PYTHON_EXE% -m pip install pytest testfixtures" build: off diff --git a/tests/data/doc_parse/expected.json b/tests/data/doc_parse/expected.json index 9abe2c9d3..f895e4fb1 100644 --- a/tests/data/doc_parse/expected.json +++ b/tests/data/doc_parse/expected.json @@ -1,311 +1,311 @@ { - "id": "SPDXRef-DOCUMENT", + "id": "SPDXRef-DOCUMENT", "specVersion": { - "major": 2, + "major": 2, "minor": 1 - }, - "documentNamespace": "https://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301", - "name": "Sample_Document-V2.1", - "comment": "This is a sample spreadsheet", + }, + "documentNamespace": "https://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301", + "name": "Sample_Document-V2.1", + "comment": "This is a sample spreadsheet", "dataLicense": { - "type": "Single", - "identifier": "CC0-1.0", + "type": "Single", + "identifier": "CC0-1.0", "name": "Creative Commons Zero v1.0 Universal" - }, + }, "licenseListVersion": { - "major": 3, + "major": 3, "minor": 6 - }, + }, "creators": [ { - "name": "Gary O'Neall", - "email": null, + "name": "Gary O'Neall", + "email": null, "type": "Person" - }, + }, { - "name": "Source Auditor Inc.", - "email": null, + "name": "Source Auditor Inc.", + "email": null, "type": "Organization" - }, + }, { - "name": "SourceAuditor-V1.2", + "name": "SourceAuditor-V1.2", "type": "Tool" } - ], - "created": "2010-02-03T00:00:00Z", - "creatorComment": "This is an example of an SPDX spreadsheet format", + ], + "created": "2010-02-03T00:00:00Z", + "creatorComment": "This is an example of an SPDX spreadsheet format", "package": { - "id": "SPDXRef-Package", - "name": "SPDX Translator", - "packageFileName": "spdxtranslator-1.0.zip", - "summary": "SPDX Translator utility", - "description": "This utility translates and SPDX RDF XML document to a spreadsheet, translates a spreadsheet to an SPDX RDF XML document and translates an SPDX RDFa document to an SPDX RDF XML document.", - "versionInfo": "Version 0.9.2", - "sourceInfo": "Version 1.0 of the SPDX Translator application", - "downloadLocation": "http://www.spdx.org/tools", - "homepage": null, + "id": "SPDXRef-Package", + "name": "SPDX Translator", + "packageFileName": "spdxtranslator-1.0.zip", + "summary": "SPDX Translator utility", + "description": "This utility translates and SPDX RDF XML document to a spreadsheet, translates a spreadsheet to an SPDX RDF XML document and translates an SPDX RDFa document to an SPDX RDF XML document.", + "versionInfo": "Version 0.9.2", + "sourceInfo": "Version 1.0 of the SPDX Translator application", + "downloadLocation": "http://www.spdx.org/tools", + "homepage": null, "originator": { - "name": "SPDX", - "email": null, + "name": "SPDX", + "email": null, "type": "Organization" - }, + }, "supplier": { - "name": "Linux Foundation", - "email": null, + "name": "Linux Foundation", + "email": null, "type": "Organization" - }, + }, "licenseConcluded": { - "type": "Conjunction", + "type": "Conjunction", "identifier": [ - "Apache-1.0", - "Apache-2.0", - "LicenseRef-1", - "LicenseRef-2", - "LicenseRef-3", - "LicenseRef-4", + "Apache-1.0", + "Apache-2.0", + "LicenseRef-1", + "LicenseRef-2", + "LicenseRef-3", + "LicenseRef-4", "MPL-1.1" - ], + ], "name": [ - "Apache License 1.0", - "Apache License 2.0", - "CyberNeko License", - "Mozilla Public License 1.1", - "None", - "None", - "None" + "Apache License 1.0", + "Apache License 2.0", + "CyberNeko License", + "LicenseRef-1", + "LicenseRef-2", + "LicenseRef-4", + "Mozilla Public License 1.1" ] - }, + }, "licenseDeclared": { - "type": "Conjunction", + "type": "Conjunction", "identifier": [ - "Apache-2.0", - "LicenseRef-1", - "LicenseRef-2", - "LicenseRef-3", - "LicenseRef-4", + "Apache-2.0", + "LicenseRef-1", + "LicenseRef-2", + "LicenseRef-3", + "LicenseRef-4", "MPL-1.1" - ], + ], "name": [ - "Apache License 2.0", - "CyberNeko License", - "Mozilla Public License 1.1", - "None", - "None", - "None" + "Apache License 2.0", + "CyberNeko License", + "LicenseRef-1", + "LicenseRef-2", + "LicenseRef-4", + "Mozilla Public License 1.1" ] - }, - "copyrightText": " Copyright 2010, 2011 Source Auditor Inc.", - "licenseComment": "The declared license information can be found in the NOTICE file at the root of the archive file", + }, + "copyrightText": " Copyright 2010, 2011 Source Auditor Inc.", + "licenseComment": "The declared license information can be found in the NOTICE file at the root of the archive file", "checksum": { - "identifier": "SHA1", + "identifier": "SHA1", "value": "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12" - }, + }, "files": [ { - "id": "SPDXRef-File1", - "name": "Jenna-2.6.3/jena-2.6.3-sources.jar", - "type": 3, - "comment": "This file belongs to Jena", + "id": "SPDXRef-File1", + "name": "Jenna-2.6.3/jena-2.6.3-sources.jar", + "type": 3, + "comment": "This file belongs to Jena", "licenseConcluded": { - "type": "Single", - "identifier": "LicenseRef-1", - "name": null - }, - "copyrightText": "(c) Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Hewlett-Packard Development Company, LP", - "licenseComment": "This license is used by Jena", - "notice": null, + "type": "Single", + "identifier": "LicenseRef-1", + "name": "LicenseRef-1" + }, + "copyrightText": "(c) Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Hewlett-Packard Development Company, LP", + "licenseComment": "This license is used by Jena", + "notice": null, "checksum": { - "identifier": "SHA1", + "identifier": "SHA1", "value": "3ab4e1c67a2d28fced849ee1bb76e7391b93f125" - }, + }, "licenseInfoFromFiles": [ { - "type": "Single", - "identifier": "LicenseRef-1", - "name": null + "type": "Single", + "identifier": "LicenseRef-1", + "name": "LicenseRef-1" } - ], - "contributors": [], - "dependencies": [], + ], + "contributors": [], + "dependencies": [], "artifactOfProjectName": [ "Jena" - ], + ], "artifactOfProjectHome": [ "http://www.openjena.org/" - ], + ], "artifactOfProjectURI": [ "http://subversion.apache.org/doap.rdf" ] - }, + }, { - "id": "SPDXRef-File2", - "name": "src/org/spdx/parser/DOAPProject.java", - "type": 1, - "comment": null, + "id": "SPDXRef-File2", + "name": "src/org/spdx/parser/DOAPProject.java", + "type": 1, + "comment": null, "licenseConcluded": { - "type": "Single", - "identifier": "Apache-2.0", + "type": "Single", + "identifier": "Apache-2.0", "name": "Apache License 2.0" - }, - "copyrightText": "Copyright 2010, 2011 Source Auditor Inc.", - "licenseComment": null, - "notice": null, + }, + "copyrightText": "Copyright 2010, 2011 Source Auditor Inc.", + "licenseComment": null, + "notice": null, "checksum": { - "identifier": "SHA1", + "identifier": "SHA1", "value": "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12" - }, + }, "licenseInfoFromFiles": [ { - "type": "Single", - "identifier": "Apache-2.0", + "type": "Single", + "identifier": "Apache-2.0", "name": "Apache License 2.0" } - ], - "contributors": [], - "dependencies": [], - "artifactOfProjectName": [], - "artifactOfProjectHome": [], + ], + "contributors": [], + "dependencies": [], + "artifactOfProjectName": [], + "artifactOfProjectHome": [], "artifactOfProjectURI": [] } - ], + ], "licenseInfoFromFiles": [ { - "type": "Single", - "identifier": "Apache-1.0", + "type": "Single", + "identifier": "Apache-1.0", "name": "Apache License 1.0" - }, + }, { - "type": "Single", - "identifier": "Apache-2.0", + "type": "Single", + "identifier": "Apache-2.0", "name": "Apache License 2.0" - }, + }, { - "type": "Single", - "identifier": "LicenseRef-1", - "name": null - }, + "type": "Single", + "identifier": "LicenseRef-1", + "name": "LicenseRef-1" + }, { - "type": "Single", - "identifier": "LicenseRef-2", - "name": null - }, + "type": "Single", + "identifier": "LicenseRef-2", + "name": "LicenseRef-2" + }, { - "type": "Single", - "identifier": "LicenseRef-3", + "type": "Single", + "identifier": "LicenseRef-3", "name": "CyberNeko License" - }, + }, { - "type": "Single", - "identifier": "LicenseRef-4", - "name": null - }, + "type": "Single", + "identifier": "LicenseRef-4", + "name": "LicenseRef-4" + }, { - "type": "Single", - "identifier": "MPL-1.1", + "type": "Single", + "identifier": "MPL-1.1", "name": "Mozilla Public License 1.1" } - ], + ], "verificationCode": { - "value": "4e3211c67a2d28fced849ee1bb76e7391b93feba", + "value": "4e3211c67a2d28fced849ee1bb76e7391b93feba", "excludedFilesNames": [ - "SpdxTranslatorSpdx.rdf", + "SpdxTranslatorSpdx.rdf", "SpdxTranslatorSpdx.txt" ] } - }, + }, "externalDocumentRefs": [ { - "externalDocumentId": "DocumentRef-spdx-tool-2.1", - "spdxDocument": "https://spdx.org/spdxdocs/spdx-tools-v2.1-3F2504E0-4F89-41D3-9A0C-0305E82C3301", + "externalDocumentId": "DocumentRef-spdx-tool-2.1", + "spdxDocument": "https://spdx.org/spdxdocs/spdx-tools-v2.1-3F2504E0-4F89-41D3-9A0C-0305E82C3301", "checksum": { - "identifier": "SHA1", + "identifier": "SHA1", "value": "d6a770ba38583ed4bb4525bd96e50461655d2759" } } - ], + ], "extractedLicenses": [ { - "name": null, - "identifier": "LicenseRef-1", - "text": "/*\n * (c) Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Hewlett-Packard Development Company, LP\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n * derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */", - "comment": null, + "name": "LicenseRef-1", + "identifier": "LicenseRef-1", + "text": "/*\n * (c) Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Hewlett-Packard Development Company, LP\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n * derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */", + "comment": null, "cross_refs": [] - }, + }, { - "name": null, - "identifier": "LicenseRef-2", - "text": "This package includes the GRDDL parser developed by Hewlett Packard under the following license:\n\u00a9 Copyright 2007 Hewlett-Packard Development Company, LP\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: \n\nRedistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. \nRedistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. \nThe name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. \nTHIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ", - "comment": null, + "name": "LicenseRef-2", + "identifier": "LicenseRef-2", + "text": "This package includes the GRDDL parser developed by Hewlett Packard under the following license:\n\u00a9 Copyright 2007 Hewlett-Packard Development Company, LP\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: \n\nRedistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. \nRedistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. \nThe name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. \nTHIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ", + "comment": null, "cross_refs": [] - }, + }, { - "name": "CyberNeko License", - "identifier": "LicenseRef-3", - "text": "The CyberNeko Software License, Version 1.0\n\n \n(C) Copyright 2002-2005, Andy Clark. All rights reserved.\n \nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n1. Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer. \n\n2. Redistributions in binary form must reproduce the above copyright\n notice, this list of conditions and the following disclaimer in\n the documentation and/or other materials provided with the\n distribution.\n\n3. The end-user documentation included with the redistribution,\n if any, must include the following acknowledgment: \n \"This product includes software developed by Andy Clark.\"\n Alternately, this acknowledgment may appear in the software itself,\n if and wherever such third-party acknowledgments normally appear.\n\n4. The names \"CyberNeko\" and \"NekoHTML\" must not be used to endorse\n or promote products derived from this software without prior \n written permission. For written permission, please contact \n andyc@cyberneko.net.\n\n5. Products derived from this software may not be called \"CyberNeko\",\n nor may \"CyberNeko\" appear in their name, without prior written\n permission of the author.\n\nTHIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED\nWARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\nOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS\nBE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, \nOR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \nOF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \nBUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \nWHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE \nOR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, \nEVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.", - "comment": "This is tye CyperNeko License", + "name": "CyberNeko License", + "identifier": "LicenseRef-3", + "text": "The CyberNeko Software License, Version 1.0\n\n \n(C) Copyright 2002-2005, Andy Clark. All rights reserved.\n \nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n1. Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer. \n\n2. Redistributions in binary form must reproduce the above copyright\n notice, this list of conditions and the following disclaimer in\n the documentation and/or other materials provided with the\n distribution.\n\n3. The end-user documentation included with the redistribution,\n if any, must include the following acknowledgment: \n \"This product includes software developed by Andy Clark.\"\n Alternately, this acknowledgment may appear in the software itself,\n if and wherever such third-party acknowledgments normally appear.\n\n4. The names \"CyberNeko\" and \"NekoHTML\" must not be used to endorse\n or promote products derived from this software without prior \n written permission. For written permission, please contact \n andyc@cyberneko.net.\n\n5. Products derived from this software may not be called \"CyberNeko\",\n nor may \"CyberNeko\" appear in their name, without prior written\n permission of the author.\n\nTHIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED\nWARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\nOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS\nBE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, \nOR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \nOF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \nBUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \nWHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE \nOR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, \nEVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.", + "comment": "This is tye CyperNeko License", "cross_refs": [ - "http://justasample.url.com", + "http://justasample.url.com", "http://people.apache.org/~andyc/neko/LICENSE" ] - }, + }, { - "name": null, - "identifier": "LicenseRef-4", - "text": "/*\n * (c) Copyright 2009 University of Bristol\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n * derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */ ", - "comment": null, + "name": "LicenseRef-4", + "identifier": "LicenseRef-4", + "text": "/*\n * (c) Copyright 2009 University of Bristol\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n * derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */ ", + "comment": null, "cross_refs": [] } - ], + ], "annotations": [ { - "id": "SPDXRef-45", - "comment": "This is just an example. Some of the non-standard licenses look like they are actually BSD 3 clause licenses", - "type": "REVIEW", + "id": "SPDXRef-45", + "comment": "This is just an example. Some of the non-standard licenses look like they are actually BSD 3 clause licenses", + "type": "REVIEW", "annotator": { - "name": "Jim Reviewer", - "email": null, + "name": "Jim Reviewer", + "email": null, "type": "Person" - }, + }, "date": "2012-06-13T00:00:00Z" } - ], + ], "reviews": [ { - "comment": "This is just an example. Some of the non-standard licenses look like they are actually BSD 3 clause licenses", + "comment": "This is just an example. Some of the non-standard licenses look like they are actually BSD 3 clause licenses", "reviewer": { - "name": "Joe Reviewer", - "email": null, + "name": "Joe Reviewer", + "email": null, "type": "Person" - }, + }, "date": "2010-02-10T00:00:00Z" - }, + }, { - "comment": "Another example reviewer.", + "comment": "Another example reviewer.", "reviewer": { - "name": "Suzanne Reviewer", - "email": null, + "name": "Suzanne Reviewer", + "email": null, "type": "Person" - }, + }, "date": "2011-03-13T00:00:00Z" } - ], + ], "snippets": [ { - "id": "SPDXRef-Snippet", - "name": "from linux kernel", - "comment": "This snippet was identified as significant and highlighted in this Apache-2.0 file, when a commercial scanner identified it as being derived from file foo.c in package xyz which is licensed under GPL-2.0-or-later.", - "copyrightText": "Copyright 2008-2010 John Smith", - "licenseComments": "The concluded license was taken from package xyz, from which the snippet was copied into the current file. The concluded license information was found in the COPYING.txt file in package xyz.", - "fileId": "SPDXRef-DoapSource", + "id": "SPDXRef-Snippet", + "name": "from linux kernel", + "comment": "This snippet was identified as significant and highlighted in this Apache-2.0 file, when a commercial scanner identified it as being derived from file foo.c in package xyz which is licensed under GPL-2.0-or-later.", + "copyrightText": "Copyright 2008-2010 John Smith", + "licenseComments": "The concluded license was taken from package xyz, from which the snippet was copied into the current file. The concluded license information was found in the COPYING.txt file in package xyz.", + "fileId": "SPDXRef-DoapSource", "licenseConcluded": { - "type": "Single", - "identifier": "Apache-2.0", + "type": "Single", + "identifier": "Apache-2.0", "name": "Apache License 2.0" - }, + }, "licenseInfoFromSnippet": [ { - "type": "Single", - "identifier": "Apache-2.0", + "type": "Single", + "identifier": "Apache-2.0", "name": "Apache License 2.0" } ] diff --git a/tests/data/doc_parse/spdx-expected.json b/tests/data/doc_parse/spdx-expected.json index f911be4bc..689721107 100644 --- a/tests/data/doc_parse/spdx-expected.json +++ b/tests/data/doc_parse/spdx-expected.json @@ -1,312 +1,312 @@ { - "comment": "This is a sample spreadsheet", - "externalDocumentRefs": [ - { - "checksum": { - "identifier": "SHA1", - "value": "d6a770ba38583ed4bb4525bd96e50461655d2759" - }, - "spdxDocument": "https://spdx.org/spdxdocs/spdx-tools-v2.1-3F2504E0-4F89-41D3-9A0C-0305E82C3301", - "externalDocumentId": "DocumentRef-spdx-tool-2.1" - } - ], - "licenseListVersion": { - "major": 3, - "minor": 6 - }, + "id": "https://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DOCUMENT", "specVersion": { - "major": 2, + "major": 2, "minor": 1 - }, - "id": "https://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-DOCUMENT", - "name": "Sample_Document-V2.1", - "created": "2010-02-03T00:00:00Z", - "creatorComment": "This is an example of an SPDX spreadsheet format", + }, + "documentNamespace": "https://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301", + "name": "Sample_Document-V2.1", + "comment": "This is a sample spreadsheet", + "dataLicense": { + "type": "Single", + "identifier": "CC0-1.0", + "name": "Creative Commons Zero v1.0 Universal" + }, + "licenseListVersion": { + "major": 3, + "minor": 6 + }, + "creators": [ + { + "name": "Gary O'Neall", + "email": null, + "type": "Person" + }, + { + "name": "Source Auditor Inc.", + "email": null, + "type": "Organization" + }, + { + "name": "SourceAuditor-V1.2", + "type": "Tool" + } + ], + "created": "2010-02-03T00:00:00Z", + "creatorComment": "This is an example of an SPDX spreadsheet format", "package": { - "id": "SPDXRef-Package", + "id": "SPDXRef-Package", + "name": "SPDX Translator", + "packageFileName": "spdxtranslator-1.0.zip", + "summary": "SPDX Translator utility", + "description": "This utility translates and SPDX RDF XML document to a spreadsheet, translates a spreadsheet to an SPDX RDF XML document and translates an SPDX RDFa document to an SPDX RDF XML document.", + "versionInfo": "Version 0.9.2", + "sourceInfo": "Version 1.0 of the SPDX Translator application", + "downloadLocation": "http://www.spdx.org/tools", + "homepage": null, "originator": { - "type": "Organization", - "name": "SPDX", - "email": null - }, + "name": "SPDX", + "email": null, + "type": "Organization" + }, + "supplier": { + "name": "Linux Foundation", + "email": null, + "type": "Organization" + }, + "licenseConcluded": { + "type": "Conjunction", + "identifier": [ + "Apache-1.0", + "Apache-2.0", + "LicenseRef-1", + "LicenseRef-2", + "LicenseRef-3", + "LicenseRef-4", + "MPL-1.1" + ], + "name": [ + "Apache License 1.0", + "Apache License 2.0", + "CyberNeko License", + "LicenseRef-1", + "LicenseRef-2", + "LicenseRef-4", + "Mozilla Public License 1.1" + ] + }, + "licenseDeclared": { + "type": "Conjunction", + "identifier": [ + "Apache-2.0", + "LicenseRef-1", + "LicenseRef-2", + "LicenseRef-3", + "LicenseRef-4", + "MPL-1.1" + ], + "name": [ + "Apache License 2.0", + "CyberNeko License", + "LicenseRef-1", + "LicenseRef-2", + "LicenseRef-4", + "Mozilla Public License 1.1" + ] + }, + "copyrightText": " Copyright 2010, 2011 Source Auditor Inc.", + "licenseComment": "The declared license information can be found in the NOTICE file at the root of the archive file", + "checksum": { + "identifier": "SHA1", + "value": "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12" + }, "files": [ { - "comment": "This file belongs to Jena", + "id": "https://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-File1", + "name": "Jenna-2.6.3/jena-2.6.3-sources.jar", + "type": 3, + "comment": "This file belongs to Jena", + "licenseConcluded": { + "type": "Single", + "identifier": "LicenseRef-1", + "name": "LicenseRef-1" + }, + "copyrightText": "(c) Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Hewlett-Packard Development Company, LP", + "licenseComment": "This license is used by Jena", + "notice": null, + "checksum": { + "identifier": "SHA1", + "value": "3ab4e1c67a2d28fced849ee1bb76e7391b93f125" + }, "licenseInfoFromFiles": [ { - "identifier": "LicenseRef-1", - "type": "Single", - "name": null + "type": "Single", + "identifier": "LicenseRef-1", + "name": "LicenseRef-1" } - ], - "contributors": [], - "notice": null, - "licenseConcluded": { - "identifier": "LicenseRef-1", - "type": "Single", - "name": null - }, - "dependencies": [], + ], + "contributors": [], + "dependencies": [], "artifactOfProjectName": [ "Jena" - ], - "artifactOfProjectURI": [], - "id": "https://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-File1", - "licenseComment": "This license is used by Jena", - "name": "Jenna-2.6.3/jena-2.6.3-sources.jar", + ], "artifactOfProjectHome": [ "http://www.openjena.org/" - ], - "checksum": { - "identifier": "SHA1", - "value": "3ab4e1c67a2d28fced849ee1bb76e7391b93f125" - }, - "copyrightText": "(c) Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Hewlett-Packard Development Company, LP", - "type": 3 - }, + ], + "artifactOfProjectURI": [] + }, { - "comment": null, - "licenseInfoFromFiles": [ - { - "identifier": "Apache-2.0", - "type": "Single", - "name": "Apache License 2.0" - } - ], - "contributors": [], - "notice": null, + "id": "https://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-File2", + "name": "src/org/spdx/parser/DOAPProject.java", + "type": 1, + "comment": null, "licenseConcluded": { - "identifier": "Apache-2.0", - "type": "Single", + "type": "Single", + "identifier": "Apache-2.0", "name": "Apache License 2.0" - }, - "dependencies": [], - "artifactOfProjectName": [], - "artifactOfProjectURI": [], - "id": "https://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-File2", - "licenseComment": null, - "name": "src/org/spdx/parser/DOAPProject.java", - "artifactOfProjectHome": [], + }, + "copyrightText": "Copyright 2010, 2011 Source Auditor Inc.", + "licenseComment": null, + "notice": null, "checksum": { - "identifier": "SHA1", + "identifier": "SHA1", "value": "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12" - }, - "copyrightText": "Copyright 2010, 2011 Source Auditor Inc.", - "type": 1 + }, + "licenseInfoFromFiles": [ + { + "type": "Single", + "identifier": "Apache-2.0", + "name": "Apache License 2.0" + } + ], + "contributors": [], + "dependencies": [], + "artifactOfProjectName": [], + "artifactOfProjectHome": [], + "artifactOfProjectURI": [] } - ], - "licenseComment": "The declared license information can be found in the NOTICE file at the root of the archive file", - "name": "SPDX Translator", - "packageFileName": "spdxtranslator-1.0.zip", - "licenseDeclared": { - "identifier": [ - "Apache-2.0", - "LicenseRef-1", - "LicenseRef-2", - "LicenseRef-3", - "LicenseRef-4", - "MPL-1.1" - ], - "type": "Conjunction", - "name": [ - "Apache License 2.0", - "CyberNeko License", - "Mozilla Public License 1.1", - "None", - "None", - "None" - ] - }, - "sourceInfo": "Version 1.0 of the SPDX Translator application", - "summary": "SPDX Translator utility", + ], "licenseInfoFromFiles": [ { - "identifier": "Apache-1.0", - "type": "Single", + "type": "Single", + "identifier": "Apache-1.0", "name": "Apache License 1.0" - }, + }, { - "identifier": "Apache-2.0", - "type": "Single", + "type": "Single", + "identifier": "Apache-2.0", "name": "Apache License 2.0" - }, + }, { - "identifier": "LicenseRef-1", - "type": "Single", - "name": null - }, + "type": "Single", + "identifier": "LicenseRef-1", + "name": "LicenseRef-1" + }, { - "identifier": "LicenseRef-2", - "type": "Single", - "name": null - }, + "type": "Single", + "identifier": "LicenseRef-2", + "name": "LicenseRef-2" + }, { - "identifier": "LicenseRef-3", - "type": "Single", + "type": "Single", + "identifier": "LicenseRef-3", "name": "CyberNeko License" - }, + }, { - "identifier": "LicenseRef-4", - "type": "Single", - "name": null - }, + "type": "Single", + "identifier": "LicenseRef-4", + "name": "LicenseRef-4" + }, { - "identifier": "MPL-1.1", - "type": "Single", + "type": "Single", + "identifier": "MPL-1.1", "name": "Mozilla Public License 1.1" } - ], - "licenseConcluded": { - "identifier": [ - "Apache-1.0", - "Apache-2.0", - "LicenseRef-1", - "LicenseRef-2", - "LicenseRef-3", - "LicenseRef-4", - "MPL-1.1" - ], - "type": "Conjunction", - "name": [ - "Apache License 1.0", - "Apache License 2.0", - "CyberNeko License", - "Mozilla Public License 1.1", - "None", - "None", - "None" - ] - }, - "copyrightText": " Copyright 2010, 2011 Source Auditor Inc.", + ], "verificationCode": { - "value": "4e3211c67a2d28fced849ee1bb76e7391b93feba", + "value": "4e3211c67a2d28fced849ee1bb76e7391b93feba", "excludedFilesNames": [ - "SpdxTranslatorSpdx.rdf", + "SpdxTranslatorSpdx.rdf", "SpdxTranslatorSpdx.txt" ] - }, - "checksum": { - "identifier": "SHA1", - "value": "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12" - }, - "supplier": { - "type": "Organization", - "name": "Linux Foundation", - "email": null - }, - "versionInfo": "Version 0.9.2", - "homepage": null, - "downloadLocation": "http://www.spdx.org/tools", - "description": "This utility translates and SPDX RDF XML document to a spreadsheet, translates a spreadsheet to an SPDX RDF XML document and translates an SPDX RDFa document to an SPDX RDF XML document." - }, - "documentNamespace": "https://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301", - "reviews": [ - { - "comment": "This is just an example. Some of the non-standard licenses look like they are actually BSD 3 clause licenses", - "reviewer": { - "type": "Person", - "name": "Joe Reviewer", - "email": null - }, - "date": "2010-02-10T00:00:00Z" - }, + } + }, + "externalDocumentRefs": [ { - "comment": "Another example reviewer.", - "reviewer": { - "type": "Person", - "name": "Suzanne Reviewer", - "email": null - }, - "date": "2011-03-13T00:00:00Z" + "externalDocumentId": "DocumentRef-spdx-tool-2.1", + "spdxDocument": "https://spdx.org/spdxdocs/spdx-tools-v2.1-3F2504E0-4F89-41D3-9A0C-0305E82C3301", + "checksum": { + "identifier": "SHA1", + "value": "d6a770ba38583ed4bb4525bd96e50461655d2759" + } } - ], - "dataLicense": { - "identifier": "CC0-1.0", - "type": "Single", - "name": "Creative Commons Zero v1.0 Universal" - }, + ], "extractedLicenses": [ { - "comment": null, - "text": "/*\n * (c) Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Hewlett-Packard Development Company, LP\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n * derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */", - "cross_refs": [], - "identifier": "LicenseRef-1", - "name": null - }, + "name": "LicenseRef-1", + "identifier": "LicenseRef-1", + "text": "/*\n * (c) Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Hewlett-Packard Development Company, LP\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n * derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */", + "comment": null, + "cross_refs": [] + }, { - "comment": null, - "text": "This package includes the GRDDL parser developed by Hewlett Packard under the following license:\n\u00a9 Copyright 2007 Hewlett-Packard Development Company, LP\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: \n\nRedistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. \nRedistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. \nThe name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. \nTHIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ", - "cross_refs": [], - "identifier": "LicenseRef-2", - "name": null - }, + "name": "LicenseRef-2", + "identifier": "LicenseRef-2", + "text": "This package includes the GRDDL parser developed by Hewlett Packard under the following license:\n\u00a9 Copyright 2007 Hewlett-Packard Development Company, LP\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: \n\nRedistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. \nRedistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. \nThe name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. \nTHIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ", + "comment": null, + "cross_refs": [] + }, { - "comment": "This is tye CyperNeko License", - "text": "The CyberNeko Software License, Version 1.0\n\n \n(C) Copyright 2002-2005, Andy Clark. All rights reserved.\n \nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n1. Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer. \n\n2. Redistributions in binary form must reproduce the above copyright\n notice, this list of conditions and the following disclaimer in\n the documentation and/or other materials provided with the\n distribution.\n\n3. The end-user documentation included with the redistribution,\n if any, must include the following acknowledgment: \n \"This product includes software developed by Andy Clark.\"\n Alternately, this acknowledgment may appear in the software itself,\n if and wherever such third-party acknowledgments normally appear.\n\n4. The names \"CyberNeko\" and \"NekoHTML\" must not be used to endorse\n or promote products derived from this software without prior \n written permission. For written permission, please contact \n andyc@cyberneko.net.\n\n5. Products derived from this software may not be called \"CyberNeko\",\n nor may \"CyberNeko\" appear in their name, without prior written\n permission of the author.\n\nTHIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED\nWARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\nOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS\nBE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, \nOR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \nOF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \nBUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \nWHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE \nOR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, \nEVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.", + "name": "CyberNeko License", + "identifier": "LicenseRef-3", + "text": "The CyberNeko Software License, Version 1.0\n\n \n(C) Copyright 2002-2005, Andy Clark. All rights reserved.\n \nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n1. Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer. \n\n2. Redistributions in binary form must reproduce the above copyright\n notice, this list of conditions and the following disclaimer in\n the documentation and/or other materials provided with the\n distribution.\n\n3. The end-user documentation included with the redistribution,\n if any, must include the following acknowledgment: \n \"This product includes software developed by Andy Clark.\"\n Alternately, this acknowledgment may appear in the software itself,\n if and wherever such third-party acknowledgments normally appear.\n\n4. The names \"CyberNeko\" and \"NekoHTML\" must not be used to endorse\n or promote products derived from this software without prior \n written permission. For written permission, please contact \n andyc@cyberneko.net.\n\n5. Products derived from this software may not be called \"CyberNeko\",\n nor may \"CyberNeko\" appear in their name, without prior written\n permission of the author.\n\nTHIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED\nWARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\nOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS\nBE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, \nOR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \nOF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \nBUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \nWHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE \nOR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, \nEVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.", + "comment": "This is tye CyperNeko License", "cross_refs": [ - "http://justasample.url.com", + "http://justasample.url.com", "http://people.apache.org/~andyc/neko/LICENSE" - ], - "identifier": "LicenseRef-3", - "name": "CyberNeko License" - }, - { - "comment": null, - "text": "/*\n * (c) Copyright 2009 University of Bristol\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n * derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */ ", - "cross_refs": [], - "identifier": "LicenseRef-4", - "name": null - } - ], - "creators": [ - { - "type": "Person", - "name": "Gary O'Neall", - "email": null - }, - { - "type": "Organization", - "name": "Source Auditor Inc.", - "email": null - }, + ] + }, { - "type": "Tool", - "name": "SourceAuditor-V1.2" + "name": "LicenseRef-4", + "identifier": "LicenseRef-4", + "text": "/*\n * (c) Copyright 2009 University of Bristol\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n * derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */ ", + "comment": null, + "cross_refs": [] } - ], + ], "annotations": [ { - "comment": "This is just an example. Some of the non-standard licenses look like they are actually BSD 3 clause licenses", - "date": "2012-06-13T00:00:00Z", - "type": "REVIEW", - "id": "https://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-45", + "id": "https://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-45", + "comment": "This is just an example. Some of the non-standard licenses look like they are actually BSD 3 clause licenses", + "type": "REVIEW", "annotator": { - "type": "Person", - "name": "Jim Reviewer", - "email": null - } + "name": "Jim Reviewer", + "email": null, + "type": "Person" + }, + "date": "2012-06-13T00:00:00Z" + } + ], + "reviews": [ + { + "comment": "This is just an example. Some of the non-standard licenses look like they are actually BSD 3 clause licenses", + "reviewer": { + "name": "Joe Reviewer", + "email": null, + "type": "Person" + }, + "date": "2010-02-10T00:00:00Z" + }, + { + "comment": "Another example reviewer.", + "reviewer": { + "name": "Suzanne Reviewer", + "email": null, + "type": "Person" + }, + "date": "2011-03-13T00:00:00Z" } - ], + ], "snippets": [ { - "id": "SPDXRef-Snippet", - "name": "from linux kernel", - "comment": "This snippet was identified as significant and highlighted in this Apache-2.0 file, when a commercial scanner identified it as being derived from file foo.c in package xyz which is licensed under GPL-2.0-or-later.", - "copyrightText": "Copyright 2008-2010 John Smith", - "licenseComments": "The concluded license was taken from package xyz, from which the snippet was copied into the current file. The concluded license information was found in the COPYING.txt file in package xyz.", - "fileId": "SPDXRef-DoapSource", - "licenseConcluded": { - "identifier": "Apache-2.0", - "name": "Apache License 2.0", - "type": "Single" - }, - "licenseInfoFromSnippet": [ - { - "identifier": "Apache-2.0", - "name": "Apache License 2.0", - "type": "Single" - } - ] + "id": "SPDXRef-Snippet", + "name": "from linux kernel", + "comment": "This snippet was identified as significant and highlighted in this Apache-2.0 file, when a commercial scanner identified it as being derived from file foo.c in package xyz which is licensed under GPL-2.0-or-later.", + "copyrightText": "Copyright 2008-2010 John Smith", + "licenseComments": "The concluded license was taken from package xyz, from which the snippet was copied into the current file. The concluded license information was found in the COPYING.txt file in package xyz.", + "fileId": "SPDXRef-DoapSource", + "licenseConcluded": { + "type": "Single", + "identifier": "Apache-2.0", + "name": "Apache License 2.0" + }, + "licenseInfoFromSnippet": [ + { + "type": "Single", + "identifier": "Apache-2.0", + "name": "Apache License 2.0" + } + ] } ] } \ No newline at end of file diff --git a/tests/test_jsonyamlxml_parser.py b/tests/test_jsonyamlxml_parser.py index f3070cec9..101d277ed 100644 --- a/tests/test_jsonyamlxml_parser.py +++ b/tests/test_jsonyamlxml_parser.py @@ -30,13 +30,13 @@ def check_document(self, document, expected_loc, regen=False): result = TestParserUtils.to_dict(document) if regen: - with open(expected_loc, 'wb') as o: + with open(expected_loc, 'w') as o: o.write(json.dumps(result, indent=2)) with io.open(expected_loc, encoding='utf-8') as ex: expected = json.load(ex, object_pairs_hook=OrderedDict) - self.assertEqual(expected, result) + utils_test.compare(expected, result) def test_json_parser(self): parser = jsonparser.Parser(Builder(), StandardLogger()) diff --git a/tests/test_rdf_parser.py b/tests/test_rdf_parser.py index 5b9cb82ad..3c0463d6d 100644 --- a/tests/test_rdf_parser.py +++ b/tests/test_rdf_parser.py @@ -25,7 +25,7 @@ class TestParser(unittest.TestCase): maxDiff = None - def test_rdf_parser(self): + def test_rdf_parser(self, regen=False): parser = rdf.Parser(RDFBuilder(), StandardLogger()) test_file = utils_test.get_test_loc('formats/SPDXRdfExample.rdf', test_data_dir=utils_test.test_data_dir) with io.open(test_file, 'rb') as f: @@ -44,27 +44,4 @@ def check_document(self, document, expected_loc, regen=False): with io.open(expected_loc, 'r', encoding='utf-8') as ex: expected = json.load(ex) - self.check_fields(result, expected) - assert expected == result - - def check_fields(self, result, expected): - """ - Test result and expected objects field by field - to provide more specific error messages when failing - """ - assert expected['id'] == result['id'] - assert expected['specVersion'] == result['specVersion'] - assert expected['documentNamespace'] == result['documentNamespace'] - assert expected['name'] == result['name'] - assert expected['comment'] == result['comment'] - assert expected['dataLicense'] == result['dataLicense'] - assert expected['licenseListVersion'] == result['licenseListVersion'] - assert expected['creators'] == result['creators'] - assert expected['created'] == result['created'] - assert expected['creatorComment'] == result['creatorComment'] - assert expected['package']['files'] == result['package']['files'] - assert expected['package'] == result['package'] - assert expected['externalDocumentRefs'] == result['externalDocumentRefs'] - assert expected['extractedLicenses'] == result['extractedLicenses'] - assert expected['annotations'] == result['annotations'] - assert expected['reviews'] == result['reviews'] + utils_test.compare(result, expected) diff --git a/tests/test_write_anything.py b/tests/test_write_anything.py index 1f7e707dc..17817b09a 100644 --- a/tests/test_write_anything.py +++ b/tests/test_write_anything.py @@ -60,8 +60,7 @@ def test_write_anything(in_format, out_format, tmpdir): test = in_format + "->" + out_format if test not in UNSTABLE_CONVERSIONS: - for k, v in result.items(): - assert v == result2[k], k + " differs" + utils_test.compare(result, result2) else: # if this test fails, this means we are more stable \o/ # in that case, please remove the test from UNSTABLE_CONVERSIONS list diff --git a/tests/utils_test.py b/tests/utils_test.py index aee818e33..099b331e0 100644 --- a/tests/utils_test.py +++ b/tests/utils_test.py @@ -29,6 +29,12 @@ import spdx from spdx import utils +try: + from testfixtures import compare +except ImportError: + def compare(a, b): + assert a == b, "for better comparaison results, please pip install testfixtures" + test_data_dir = os.path.join(os.path.dirname(__file__), 'data') From 03174b61eed9c449a9492ac8a7f71bd16eb982d9 Mon Sep 17 00:00:00 2001 From: Pierre Tardy Date: Thu, 22 Jul 2021 16:02:51 +0200 Subject: [PATCH 08/10] autogenerate ExtractedLicense is not found in the data Signed-off-by: Pierre Tardy --- spdx/writers/rdf.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/spdx/writers/rdf.py b/spdx/writers/rdf.py index 50bcc8105..2251181cb 100644 --- a/spdx/writers/rdf.py +++ b/spdx/writers/rdf.py @@ -24,6 +24,7 @@ from spdx import utils from spdx.writers.tagvalue import InvalidDocumentError +import warnings class BaseWriter(object): """ @@ -142,9 +143,11 @@ def create_license_helper(self, lic): if len(matches) != 0: return self.create_extracted_license(matches[0]) else: - raise InvalidDocumentError( + lic = document.ExtractedLicense(lic.identifier) + warnings.warn( "Missing extracted license: {0}".format(lic.identifier) ) + return self.create_extracted_license(lic) def create_extracted_license(self, lic): """ From 3eda4f9d1e6fa8a94de6a0eb8d388ad1e68d58f6 Mon Sep 17 00:00:00 2001 From: Pierre Tardy Date: Thu, 22 Jul 2021 16:04:32 +0200 Subject: [PATCH 09/10] test with all data in the data dir previous version of the test was unstable to directory order the first file found was used, and some more simple files have good conversion while more complex are failing Signed-off-by: Pierre Tardy --- tests/test_write_anything.py | 46 +++++++++++++++++------------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/tests/test_write_anything.py b/tests/test_write_anything.py index 17817b09a..fd6b191ab 100644 --- a/tests/test_write_anything.py +++ b/tests/test_write_anything.py @@ -21,31 +21,29 @@ dirname = os.path.join(os.path.dirname(__file__), "data", "formats") test_files = [os.path.join(dirname, fn) for fn in os.listdir(dirname)] -UNSTABLE_CONVERSIONS = [ - "rdf->rdf", - "yaml->rdf", - "xml->rdf", - "json->rdf", - "tag->rdf", - "rdf->yaml", - "tag->yaml", - "rdf->xml", - "tag->xml", - "rdf->json", - "tag->json", - "rdf->tag", - "yaml->tag", - "xml->tag", - "json->tag", -] +UNSTABLE_CONVERSIONS = { + "SPDXTagExample.tag-rdf", + "SPDXTagExample.tag-yaml", + "SPDXTagExample.tag-xml", + "SPDXTagExample.tag-json", + "SPDXSimpleTag.tag-rdf", + "SPDXXmlExample.xml-rdf", + "SPDXXmlExample.xml-tag", + "SPDXJsonExample.json-rdf", + "SPDXJsonExample.json-tag", + "SPDXYamlExample.yaml-rdf", + "SPDXYamlExample.yaml-tag", + "SPDXRdfExample.rdf-rdf", + "SPDXRdfExample.rdf-yaml", + "SPDXRdfExample.rdf-xml", + "SPDXRdfExample.rdf-json", + "SPDXRdfExample.rdf-tag", +} -@pytest.mark.parametrize("in_format", ['rdf', 'yaml', 'xml', 'json', 'tag']) @pytest.mark.parametrize("out_format", ['rdf', 'yaml', 'xml', 'json', 'tag']) -def test_write_anything(in_format, out_format, tmpdir): - - for in_file in test_files: - if in_file.endswith(in_format): - break +@pytest.mark.parametrize("in_file", test_files, ids=lambda x: os.path.basename(x)) +def test_write_anything(in_file, out_format, tmpdir): + in_basename = os.path.basename(in_file) doc, error = parse_anything.parse_file(in_file) assert not error @@ -58,7 +56,7 @@ def test_write_anything(in_format, out_format, tmpdir): result2 = utils_test.TestParserUtils.to_dict(doc2) assert not error2 - test = in_format + "->" + out_format + test = in_basename + "-" + out_format if test not in UNSTABLE_CONVERSIONS: utils_test.compare(result, result2) else: From 3efab86fd735cb527032c959417668bc9a2d3de1 Mon Sep 17 00:00:00 2001 From: Pierre Tardy Date: Mon, 26 Jul 2021 17:25:08 +0200 Subject: [PATCH 10/10] fix commandline usage Signed-off-by: Pierre Tardy --- setup.py | 1 - spdx/cli_tools/convertor.py | 22 ++++++++++++---------- spdx/cli_tools/parser.py | 2 +- spdx/parsers/parse_anything.py | 2 +- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/setup.py b/setup.py index 6029053aa..24c79b793 100755 --- a/setup.py +++ b/setup.py @@ -43,7 +43,6 @@ def test_suite(): 'console_scripts': [ 'convertor = spdx.cli_tools.convertor:main', 'parser = spdx.cli_tools.parser:main', - 'generate_notice_file = spdx.cli_tools.generate_notice_file:main', ], }, diff --git a/spdx/cli_tools/convertor.py b/spdx/cli_tools/convertor.py index 901d8627e..07c27752f 100644 --- a/spdx/cli_tools/convertor.py +++ b/spdx/cli_tools/convertor.py @@ -18,25 +18,25 @@ import click +def print_help_msg(command): + with click.Context(command) as ctx: + click.echo(command.get_help(ctx)) @click.command() @click.argument("src", nargs=-1) -@click.option("--infile", "-i", help="The file to be converted ", default="undefined") -@click.option("--outfile", "-o", help="The file after converting", default="undefined") +@click.option("--infile", "-i", help="The file to be converted ") +@click.option("--outfile", "-o", help="The file after converting") @click.option( "--to", "-t", - type=click.Choice(["json", "rdf", "yaml", "xml", "tag"], case_sensitive=False), - default="undefined", + type=click.Choice(["json", "rdf", "yaml", "xml", "tag"], case_sensitive=False) ) @click.option( "--from", "-f", "from_", - type=click.Choice(["tag", "rdf"], case_sensitive=False), - default="undefined", -) -@click.option("--force", action="store_true", help="convert even if there are some parsing errors or inconsistencies") + type=click.Choice(["tag", "rdf"], case_sensitive=False)) +@click.option("--force", is_flag=True, help="convert even if there are some parsing errors or inconsistencies") def main(infile, outfile, src, from_, to, force): """ CLI-TOOL for converting a RDF or TAG file to RDF, JSON, YAML, TAG or XML format. @@ -44,7 +44,7 @@ def main(infile, outfile, src, from_, to, force): To use : run 'convertor -f -t ' command on terminal or use ' convertor --infile --outfile ' """ - if infile is None and outfile is None: + if infile is None and outfile is None and len(src) == 2: """ when the CLI is of given format: ' convertor -f/--from -t/--to . @@ -76,7 +76,9 @@ def main(infile, outfile, src, from_, to, force): if to is not None: outfile_path = os.path.splitext(outfile)[0] outfile = outfile_path + "." + to - + else: + print_help_msg(main) + return doc, errors = parse_file(infile) if errors: print("Errors while parsing: ", errors) diff --git a/spdx/cli_tools/parser.py b/spdx/cli_tools/parser.py index b3fb007bd..182ca2db0 100755 --- a/spdx/cli_tools/parser.py +++ b/spdx/cli_tools/parser.py @@ -20,7 +20,7 @@ @click.command() @click.option("--file", prompt="File name", help="The file to be parsed") -@click.option("--force", action="store_true", help="print information even if there are some parsing errors") +@click.option("--force", is_flag=True, help="print information even if there are some parsing errors") def main(file, force): """ COMMAND-LINE TOOL for parsing file of RDF, XML, JSON, YAML and XML format. diff --git a/spdx/parsers/parse_anything.py b/spdx/parsers/parse_anything.py index 94363b106..8d1d6139f 100644 --- a/spdx/parsers/parse_anything.py +++ b/spdx/parsers/parse_anything.py @@ -41,7 +41,7 @@ def parse_file(fn): elif fn.endswith(".yaml"): parsing_module = yamlparser else: - raise FileTypeError("FileType Not Supported") + raise FileTypeError("FileType Not Supported" + str(fn)) p = parsing_module.Parser(buildermodule.Builder(), StandardLogger()) if hasattr(p, "build"):