2020
2121import argparse
2222import os
23- import sys
2423from datetime import datetime
2524
2625from cyclonedx .model .bom import Bom
2726from cyclonedx .output import BaseOutput , get_instance , OutputFormat , SchemaVersion
2827from cyclonedx .parser import BaseParser
2928from cyclonedx .parser .environment import EnvironmentParser
30- from cyclonedx .parser .requirements import RequirementsParser , RequirementsFileParser
29+ from cyclonedx .parser .requirements import RequirementsFileParser
3130
3231
3332class CycloneDxCmd :
3433 # Whether debug output is enabled
3534 _DEBUG_ENABLED : bool = False
3635
37- # Argument Parser
38- _arg_parser : argparse .ArgumentParser
39-
4036 # Parsed Arguments
4137 _arguments : argparse .Namespace
4238
43- def __init__ (self ):
44- # Build and parse command arguments
45- self ._build_arg_parser ()
46- self ._parse_arguments ()
39+ def __init__ (self , args : argparse .Namespace ):
40+ self ._arguments = args
4741
4842 if self ._arguments .debug_enabled :
4943 self ._DEBUG_ENABLED = True
@@ -71,10 +65,11 @@ def execute(self):
7165 self ._debug_message ('Will be outputting SBOM to file at: {}' .format (output_filename ))
7266 output .output_to_file (filename = output_filename , allow_overwrite = self ._arguments .output_file_overwrite )
7367
74- def _build_arg_parser (self ):
75- self ._arg_parser = argparse .ArgumentParser (description = 'CycloneDX SBOM Generator' )
68+ @staticmethod
69+ def get_arg_parser () -> argparse .ArgumentParser :
70+ arg_parser = argparse .ArgumentParser (description = 'CycloneDX SBOM Generator' )
7671
77- input_group = self . _arg_parser .add_mutually_exclusive_group (required = True )
72+ input_group = arg_parser .add_mutually_exclusive_group (required = True )
7873 input_group .add_argument (
7974 '-e' , '--e' , '--environment' , action = 'store_true' ,
8075 help = 'Build a SBOM based on the packages installed in your current Python environment (default)' ,
@@ -86,16 +81,16 @@ def _build_arg_parser(self):
8681 dest = 'input_from_requirements'
8782 )
8883
89- req_input_group = self . _arg_parser .add_argument_group (
84+ req_input_group = arg_parser .add_argument_group (
9085 title = 'Requirements' ,
9186 description = 'Additional optional arguments if you are setting the input type to `requirements`.'
9287 )
9388 req_input_group .add_argument (
94- '-rf' , '--rf' , '--requirements-file' , action = 'store' , metavar = 'FILE_PATH' ,
89+ '-rf' , '--rf' , '--requirements-file' , action = 'store' , metavar = 'FILE_PATH' , default = 'requirements.txt' ,
9590 help = 'Path to a the requirements.txt file you wish to parse' , dest = 'input_requirements_file' , required = False
9691 )
9792
98- output_group = self . _arg_parser .add_argument_group (
93+ output_group = arg_parser .add_argument_group (
9994 title = 'SBOM Output Configuration' ,
10095 description = 'Choose the output format and schema version'
10196 )
@@ -118,7 +113,9 @@ def _build_arg_parser(self):
118113 help = 'If outputting to a file and the stated file already exists, it will be overwritten.'
119114 )
120115
121- self ._arg_parser .add_argument ('-X' , action = 'store_true' , help = 'Enable debug output' , dest = 'debug_enabled' )
116+ arg_parser .add_argument ('-X' , action = 'store_true' , help = 'Enable debug output' , dest = 'debug_enabled' )
117+
118+ return arg_parser
122119
123120 def _debug_message (self , message : str ):
124121 if self ._DEBUG_ENABLED :
@@ -133,23 +130,28 @@ def _get_input_parser(self) -> BaseParser:
133130 if self ._arguments .input_from_environment :
134131 return EnvironmentParser ()
135132 elif self ._arguments .input_from_requirements :
136- if self ._arguments .input_requirements_file :
137- if os .path .exists (self ._arguments .input_requirements_file ):
138- # A requirements.txt path was provided
139- return RequirementsFileParser (requirements_file = self ._arguments .input_requirements_file )
140- else :
141- self ._error_and_exit ('The requirements.txt file path provided does not exist ({})' .format (
142- self ._arguments .input_requirements_file
143- ))
133+ # if self._arguments.input_requirements_file:
134+ requirements_file = os .path .realpath (self ._arguments .input_requirements_file )
135+ # requirements_file = self._arguments.input_requirements_file
136+ if CycloneDxCmd ._validate_requirements_file (self ._arguments .input_requirements_file ):
137+ # A requirements.txt path was provided
138+ return RequirementsFileParser (requirements_file = requirements_file )
144139 else :
145- return RequirementsParser (requirements_content = sys .stdin .readlines ())
140+ self ._error_and_exit ('The requirements.txt file path provided does not exist ({})' .format (
141+ requirements_file
142+ ))
143+ else :
144+ raise ValueError ('Parser type could not be determined.' )
146145
147- def _parse_arguments (self ):
148- self ._arguments = self ._arg_parser .parse_args ()
146+ @staticmethod
147+ def _validate_requirements_file (requirements_file_path : str ) -> bool :
148+ return os .path .exists (requirements_file_path )
149149
150150
151151def main ():
152- CycloneDxCmd ().execute ()
152+ parser = CycloneDxCmd .get_arg_parser ()
153+ args = parser .parse_args ()
154+ CycloneDxCmd (args ).execute ()
153155
154156
155157if __name__ == "__main__" :
0 commit comments