diff --git a/py/CMakeLists.txt b/py/CMakeLists.txt index ea31c03..bbeade0 100644 --- a/py/CMakeLists.txt +++ b/py/CMakeLists.txt @@ -27,6 +27,7 @@ install(FILES ${src_dir}/__init__.py DESTINATION ${dst_dir}) install(FILES ${src_dir}/common/__init__.py DESTINATION ${dst_dir}/common) install(FILES ${src_dir}/common/cflags.py DESTINATION ${dst_dir}/common) install(FILES ${src_dir}/common/results.py DESTINATION ${dst_dir}/common) +install(FILES ${src_dir}/common/snyk.py DESTINATION ${dst_dir}/common) install(FILES ${src_dir}/common/util.py DESTINATION ${dst_dir}/common) macro(install_executable FILE_NAME) diff --git a/py/common/snyk.py b/py/common/snyk.py new file mode 100644 index 0000000..98df173 --- /dev/null +++ b/py/common/snyk.py @@ -0,0 +1,52 @@ +# Copyright (C) 2024 Red Hat, Inc. +# +# This file is part of csmock. +# +# csmock is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# any later version. +# +# csmock is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with csmock. If not, see . + +import json + + +def snyk_write_analysis_meta(results, raw_results_file): + """write snyk stats on metadata file. At the time, we write the total number of files, + the number of supported files and the coverage ratio.""" + + try: + with open(raw_results_file) as snyk_results_file: + data = json.load(snyk_results_file) + coverage_stats = data["runs"][0]["properties"]["coverage"] + total_files = 0 + supported_files = 0 + for lang in coverage_stats: + total_files += lang["files"] + if lang["type"] == "SUPPORTED": + supported_files += lang["files"] + + coverage_ratio = 0 + if total_files > 0: + coverage_ratio = int(supported_files * 100 / total_files) + + results.ini_writer.append("snyk-scanned-files-coverage", coverage_ratio) + results.ini_writer.append("snyk-scanned-files-success", supported_files) + results.ini_writer.append("snyk-scanned-files-total", total_files) + + return 0 + + except OSError as e: + results.error(f"snyk-scan: failed to read {raw_results_file}: {e}") + return 1 + + except KeyError as e: + results.error(f"snyk-scan: error parsing results from snyk-results.sarif file: {e}") + return 1 diff --git a/py/plugins/snyk.py b/py/plugins/snyk.py index c22f006..54ca728 100644 --- a/py/plugins/snyk.py +++ b/py/plugins/snyk.py @@ -17,6 +17,8 @@ import os +from csmock.common.snyk import snyk_write_analysis_meta + # default URL to download snyk binary executable SNYK_BIN_URL = "https://static.snyk.io/cli/latest/snyk-linux" @@ -204,4 +206,8 @@ def filter_hook(results): cmd = FILTER_CMD % (src, dst) return results.exec_cmd(cmd, shell=True) - props.post_process_hooks += [filter_hook] + def write_snyk_stats_metadata(results): + raw_results_file = results.dbgdir_raw + SNYK_OUTPUT + return snyk_write_analysis_meta(results, raw_results_file) + + props.post_process_hooks += [write_snyk_stats_metadata, filter_hook]