Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Capture all Cobra results #14

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Binary file not shown.
68 changes: 49 additions & 19 deletions ament_cobra/ament_cobra/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like this, but it's needed in Cobra's current implementation. Cobra dumps a _Autosar_.txt file in spaceros_ws/src/<pkg>/ directory. Is it worth asking Cobra maintainers to update this to optionally take an extra command-line parameter, so this file can instead be put in a better location (say, somewhere in spaceros_ws/build/<pkg>/test_results/)?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think that's a good idea. They've been pretty responsive so far. We could also just add the option to Cobra and submit a PR to their repo.

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
Expand All @@ -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:
Expand All @@ -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(
Expand All @@ -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
Expand Down Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion cobra_vendor/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down