diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ba0430d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__/ \ No newline at end of file diff --git a/ament_cobra/ament_cobra/main.py b/ament_cobra/ament_cobra/main.py index 2586c01..98f300b 100755 --- a/ament_cobra/ament_cobra/main.py +++ b/ament_cobra/ament_cobra/main.py @@ -160,8 +160,30 @@ def main(argv=sys.argv[1:]): error_count = 0 + # Unfortunately, the CWE ruleset is not outputting a JSON file + # Issue submitted here: https://github.com/nimble-code/Cobra/issues/50 + ruleset_to_filename = { + 'basic': '_Basic_.txt', + 'cwe': None, # No output JSON to work with (need #50 fixed) + 'p10': '_P10_.txt', + 'jpl': '_JPL_.txt', + 'misra2012': '_Misra2012_.txt', + 'C++/autosar': '_Autosar_.txt', + } + + input_filename = ruleset_to_filename[args.ruleset] + + # Remove old input_filename, if it exists. + try: + os.remove(input_filename) + except OSError: + pass + + # Temporary file to aggregate results from intermediate `input_filename` files + combined_output_filename = "combined_output.txt" + # For each group of files - for group_name in sorted(groups.keys()): + for i,group_name in enumerate(sorted(groups.keys())): files_in_group = groups[group_name] # If a compile_commands.json is provided, process each source file @@ -173,14 +195,23 @@ def main(argv=sys.argv[1:]): else: arguments = cmd + [filename] + # Invoke cobra, and aggregate its output error_count += invoke_cobra(arguments, args.verbose) + combine_output(input_filename, combined_output_filename, first=(i==0), verbose=args.verbose) + # Otherwise, run Cobra on this group of files else: arguments = cmd for include_dir in (args.include_dirs or []): cmd.extend(['-I' + include_dir]) arguments.extend(files_in_group) + + # Invoke cobra, and aggregate its output error_count += invoke_cobra(arguments, args.verbose) + combine_output(input_filename, combined_output_filename, first=(i==0), verbose=args.verbose) + + # Move the temporary combined output into the expected final location + os.rename(combined_output_filename, input_filename) # Output a summary if not error_count: @@ -190,19 +221,6 @@ def main(argv=sys.argv[1:]): print('%d errors' % error_count, file=sys.stderr) rc = 1 - # Unfortunately, the CWE ruleset is not outputting a JSON file - # Issue submitted here: https://github.com/nimble-code/Cobra/issues/50 - ruleset_to_filename = { - 'basic': '_Basic_.txt', - 'cwe': None, # No output JSON to work with (need #50 fixed) - 'p10': '_P10_.txt', - 'jpl': '_JPL_.txt', - 'misra2012': '_Misra2012_.txt', - 'C++/autosar': '_Autosar_.txt', - } - - input_filename = ruleset_to_filename[args.ruleset] - if (args.xunit_file or args.sarif_file) and input_filename is None: # When using the CWE ruleset, Cobra doesn't generate an output file print( @@ -223,14 +241,26 @@ def main(argv=sys.argv[1:]): else: # Generate the xunit output file if args.xunit_file: - write_output_file(input_filename, '-junit', args.xunit_file) + write_output_file(input_filename, ['-junit'], args.xunit_file) # Generate the SARIF output file if args.sarif_file: - write_output_file(input_filename, '-sarif', args.sarif_file) + write_output_file(input_filename, ['-sarif','-a'], args.sarif_file) return rc +def combine_output(input_filename, output_filename, first=False, verbose=False): + ''' + Appends the contents of `input_filename` into `output_filename`. Used to aggregate Cobra output. + ''' + if verbose: + print(f"Appending {input_filename} to {output_filename}") + with open(output_filename, "a") as out: + with open(input_filename, "r") as in_f: + # If this isn't the first file, we need to prepend a `,` to form valid json + if not first: out.write(",") + + out.write(in_f.read()) def find_executable(file_name, additional_paths=None): path = None @@ -372,10 +402,10 @@ def get_input_filenames(groups): return filenames -def write_output_file(input_filename, conversion_flag, output_filename): - folder_name = os.path.basename(os.path.dirname(output_filename)) +def write_output_file(input_filename, flags, output_filename): + try: - cmd = ['json_convert', conversion_flag, '-f', input_filename] + cmd = ['json_convert', '-f', input_filename] + flags p = subprocess.Popen(cmd, stdout=subprocess.PIPE) cmd_output = p.communicate()[0] with open(output_filename, 'w') as f: diff --git a/cobra_vendor/CMakeLists.txt b/cobra_vendor/CMakeLists.txt index 7399af0..b9725db 100644 --- a/cobra_vendor/CMakeLists.txt +++ b/cobra_vendor/CMakeLists.txt @@ -11,7 +11,7 @@ endif() # The Cobra source code version/revision numbers set(VER "4.1") -set(REV "09a5e421bfa7b84d5fca651d3ae3a93e7c30389f") +set(REV "81fba6ac6b734b0dd74f464e8501581040e5f02f") include(ExternalProject) ExternalProject_Add(cobra-${VER}