spdx_tools.spdx.clitools.pyspdxtools
1#!/usr/bin/env python3 2 3# Copyright (c) 2020 Yash Varshney 4# Copyright (c) 2023 spdx contributors 5# SPDX-License-Identifier: Apache-2.0 6# Licensed under the Apache License, Version 2.0 (the "License"); 7# you may not use this file except in compliance with the License. 8# You may obtain a copy of the License at 9# http://www.apache.org/licenses/LICENSE-2.0 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15import logging 16import sys 17from json import JSONDecodeError 18from xml.parsers.expat import ExpatError 19from xml.sax import SAXParseException 20 21import click 22from beartype.typing import List 23from yaml.scanner import ScannerError 24 25from spdx_tools.spdx.graph_generation import export_graph_from_document 26from spdx_tools.spdx.model import Document 27from spdx_tools.spdx.parser.error import SPDXParsingError 28from spdx_tools.spdx.parser.parse_anything import parse_file 29from spdx_tools.spdx.validation.document_validator import validate_full_spdx_document 30from spdx_tools.spdx.validation.validation_message import ValidationMessage 31from spdx_tools.spdx.writer.tagvalue import tagvalue_writer 32from spdx_tools.spdx.writer.write_anything import write_file 33 34 35@click.command() 36@click.option("--infile", "-i", required=True, help="The file containing the document to be validated or converted.") 37@click.option( 38 "--outfile", 39 "-o", 40 help="The file to write the converted document to (write a dash for output to stdout or omit for no conversion). " 41 "If you add the option --graph to the command the generated graph will be written to this file.", 42) 43@click.option( 44 "--version", 45 help='The SPDX version to be used during parsing and validation ("SPDX-2.2" or "SPDX-2.3"). ' 46 "Will be read from the document if not provided.", 47 default=None, 48) 49@click.option("--novalidation", is_flag=True, help="Don't validate the provided document.") 50@click.option( 51 "--graph", 52 is_flag=True, 53 default=False, 54 help="Generate a relationship graph from the input file. " 55 "The generated graph is saved to the file specified with --outfile. " 56 "Note: You need to install the optional dependencies 'networkx' and 'pygraphviz' for this feature.", 57) 58def main(infile: str, outfile: str, version: str, novalidation: bool, graph: bool): 59 """ 60 CLI-tool for validating SPDX documents and converting between RDF, TAG-VALUE, JSON, YAML and XML formats. 61 Formats are determined by the file endings. 62 To use, run: 'pyspdxtools --infile <input file name> --outfile <output file name>' 63 """ 64 try: 65 document: Document = parse_file(infile) 66 67 if not novalidation: 68 if not version: 69 version = document.creation_info.spdx_version 70 71 if version not in ["SPDX-2.2", "SPDX-2.3"]: 72 logging.error(f"This tool only supports SPDX versions SPDX-2.2 and SPDX-2.3, but got: {version}") 73 sys.exit(1) 74 75 validation_messages: List[ValidationMessage] = validate_full_spdx_document(document, version) 76 if validation_messages: 77 log_string = "\n".join( 78 ["The document is invalid. The following issues have been found:"] 79 + [message.validation_message for message in validation_messages] 80 ) 81 logging.error(log_string) 82 sys.exit(1) 83 else: 84 logging.info("The document is valid.") 85 86 if outfile == "-": 87 tagvalue_writer.write_document(document, sys.stdout) 88 89 elif graph: 90 try: 91 export_graph_from_document(document, outfile) 92 except ImportError: 93 logging.error( 94 "To be able to draw a relationship graph of the parsed document " 95 "you need to install 'networkx' and 'pygraphviz'. Run 'pip install \".[graph_generation]\"'." 96 ) 97 sys.exit(1) 98 99 elif outfile: 100 write_file(document, outfile, validate=False) 101 102 except NotImplementedError as err: 103 logging.error( 104 err.args[0] 105 + "\nPlease note that this project is currently undergoing a major refactoring and therefore missing " 106 "a few features which will be added in time (refer to https://github.com/spdx/tools-python/issues " 107 "for insights into the current status).\n" 108 "In the meantime, please use the current PyPI release version." 109 ) 110 sys.exit(1) 111 112 except SPDXParsingError as err: 113 log_string = "\n".join( 114 ["There have been issues while parsing the provided document:"] 115 + [message for message in err.get_messages()] 116 ) 117 logging.error(log_string) 118 sys.exit(1) 119 120 except JSONDecodeError as err: 121 logging.error(f"Invalid JSON provided: {err.args[0]}") 122 sys.exit(1) 123 124 except ScannerError as err: 125 logging.error("Invalid YAML provided: " + "\n".join([str(arg) for arg in err.args])) 126 sys.exit(1) 127 128 except ExpatError as err: 129 logging.error(f"Invalid XML provided: {err.args[0]}") 130 sys.exit(1) 131 132 except SAXParseException as err: 133 logging.error(f"Invalid RDF-XML provided: {str(err)}") 134 sys.exit(1) 135 136 except FileNotFoundError as err: 137 logging.error(f"{err.strerror}: {err.filename}") 138 sys.exit(1) 139 140 141if __name__ == "__main__": 142 main()
main =
<Command main>
CLI-tool for validating SPDX documents and converting between RDF, TAG-VALUE, JSON, YAML and XML formats. Formats are determined by the file endings. To use, run: 'pyspdxtools --infile --outfile