From 7bf19b82fc9fcd19de2de162d773a5517cfb3347 Mon Sep 17 00:00:00 2001 From: Diogo Gaspar Date: Sun, 1 Jun 2025 18:20:41 +0200 Subject: [PATCH 1/2] feat: granular check-related information in reports Relates to Report feedback #166 --- tool/main.py | 1 + tool/report_static.py | 87 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 81 insertions(+), 7 deletions(-) diff --git a/tool/main.py b/tool/main.py index 077468fa..19275892 100644 --- a/tool/main.py +++ b/tool/main.py @@ -520,6 +520,7 @@ def generate_static_report(analysis_results, project_info, is_old_version): project_info["enabled_checks"], project_info["gradual_report"], summary_filename=summary_file, + config=project_info["config"] ) diff --git a/tool/report_static.py b/tool/report_static.py index dee4cf52..8c21f8e4 100644 --- a/tool/report_static.py +++ b/tool/report_static.py @@ -328,7 +328,7 @@ def aliased_package(aliased_package_df, md_file, amount, package_manager): def write_summary( - df, project_name, release_version, package_manager, filename, enabled_checks, gradual_report, mode="w" + df, project_name, release_version, package_manager, filename, enabled_checks, gradual_report, mode="w", config={} ): """ Write a summary of the static analysis results to a markdown file. @@ -485,18 +485,78 @@ def write_summary( preamble += "\n" md_file.write(preamble) + md_file.write(""" +## šŸ“š Table of Contents + +- [Enabled Checks](#enabled-checks) +- [Ignore Configuration Summary](#ignore-configuration-summary) +- [Summary of Findings](#summary-of-findings) +- [Fine Grained Information](#fine-grained-information) +- [Call to Action](#call-to-action) +- [Notes](#notes) +- [Glossary](#glossary) +""") + # Section showing which checks were performed any_specific = any(enabled_checks.values()) if any_specific and not gradual_report: - md_file.write("## Enabled Checks\n") - md_file.write("The following checks were specifically requested:\n\n") + md_file.write("## Enabled Checks\n\n") + md_file.write("The following checks were requested project-wide:\n\n") + md_file.write("| Check | Status |\n") + md_file.write("|-------|--------|\n") for check, enabled in enabled_checks.items(): - if enabled: - md_file.write(f"- {check.replace('_', ' ').title()}: `{check}`\n") + status = "āœ…" if enabled else "āŒ" + md_file.write(f"| {check.replace('_', ' ').title()}: `{check}` | {status} |\n") md_file.write("\n---\n\n") else: md_file.write("All available checks were performed.\n\n---\n\n") + if config: + md_file.write("## Ignore Configuration Summary\n\n") + + if "ignore" in config and config["ignore"]: + md_file.write( + "
\n" + "Ignored Checks Per Dependency šŸ”§\n\n" + "These dependencies had specific checks excluded based on the configuration file. \n" + "**Note**: If `all` is listed, every check is ignored for that dependency.\n\n" + ) + md_file.write("| Dependency Pattern | Ignored Checks |\n") + md_file.write("|--------------------|----------------|\n") + + for dep_pattern in sorted(config["ignore"]): + ignored = config["ignore"][dep_pattern] + if ignored == "all": + checks_str = "`all`" + else: + checks_str = ", ".join(f"`{chk}`" for chk in ignored) + md_file.write(f"| `{dep_pattern}` | {checks_str} |\n") + + md_file.write("\n
\n\n") + + if "ignore-if-parent" in config and config["ignore-if-parent"]: + md_file.write( + "
\n" + "Ignored Checks If Dependency is a Parent šŸ“¦āž”ļøšŸ‘¶\n\n" + "Checks will be ignored **if the listed dependency is a parent of another package**. \n" + ) + md_file.write("| Parent Dependency Pattern | Ignored Checks |\n") + md_file.write("|---------------------------|----------------|\n") + + for parent_pattern in sorted(config["ignore-if-parent"]): + ignored = config["ignore-if-parent"][parent_pattern] + if ignored == "all": + checks_str = "`all`" + else: + checks_str = ", ".join(f"`{chk}`" for chk in ignored) + md_file.write(f"| `{parent_pattern}` | {checks_str} |\n") + + md_file.write("\n
\n\n") + + md_file.write("---\n\n") + + md_file.write("## Summary of Findings\n\n") + md_file.write( """
@@ -522,7 +582,7 @@ def write_summary( md_file.write("\n### Fine grained information\n") md_file.write( - "\n:dolphin: For further information about software supply chain smells in your project, take a look at the following tables.\n" + "\n🐬 For further information about software supply chain smells in your project, take a look at the following tables.\n" ) reports = { "no_source_code": { @@ -662,6 +722,18 @@ def write_summary( md_file.write(markdown_text) md_file.write("\n
\n\n\n") + md_file.write("\n## Glossary\n\n") + md_file.write(""" +- `source_code`: Whether a repo URL is present and valid + - `source_code_sha`: Whether a commit SHA is available and valid + - `forks`: Whether the repo is a fork +- `deprecated`: Whether the package is marked deprecated +- `provenance`: Whether build provenance/attestation is provided +- `code_signature`: Whether a code signature is present and valid +- `aliased_packages`: Whether a package is aliased under a different name +""") + + md_file.write("---\n") md_file.write("\nReport created by [dirty-waters](https://github.com/chains-project/dirty-waters/).\n") md_file.write(f"\nReport created on {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n") @@ -676,7 +748,7 @@ def write_summary( def get_s_summary( - data, deps_list, project_name, release_version, package_manager, enabled_checks, gradual_report, summary_filename + data, deps_list, project_name, release_version, package_manager, enabled_checks, gradual_report, summary_filename, config={} ): """ Get a summary of the static analysis results. @@ -692,4 +764,5 @@ def get_s_summary( enabled_checks=enabled_checks, gradual_report=gradual_report, mode="w", + config=config, ) From 8eab1cd1a6def4153bb181fba2cf775bf68f83f8 Mon Sep 17 00:00:00 2001 From: randomicecube <74926943+randomicecube@users.noreply.github.com> Date: Sun, 1 Jun 2025 16:21:51 +0000 Subject: [PATCH 2/2] style: format Python code with Black --- tool/main.py | 2 +- tool/report_static.py | 25 ++++++++++++++++++------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/tool/main.py b/tool/main.py index 19275892..43db635c 100644 --- a/tool/main.py +++ b/tool/main.py @@ -520,7 +520,7 @@ def generate_static_report(analysis_results, project_info, is_old_version): project_info["enabled_checks"], project_info["gradual_report"], summary_filename=summary_file, - config=project_info["config"] + config=project_info["config"], ) diff --git a/tool/report_static.py b/tool/report_static.py index 8c21f8e4..636a69f2 100644 --- a/tool/report_static.py +++ b/tool/report_static.py @@ -485,7 +485,8 @@ def write_summary( preamble += "\n" md_file.write(preamble) - md_file.write(""" + md_file.write( + """ ## šŸ“š Table of Contents - [Enabled Checks](#enabled-checks) @@ -495,7 +496,8 @@ def write_summary( - [Call to Action](#call-to-action) - [Notes](#notes) - [Glossary](#glossary) -""") +""" + ) # Section showing which checks were performed any_specific = any(enabled_checks.values()) @@ -554,7 +556,7 @@ def write_summary( md_file.write("\n\n\n") md_file.write("---\n\n") - + md_file.write("## Summary of Findings\n\n") md_file.write( @@ -723,7 +725,8 @@ def write_summary( md_file.write("\n\n\n\n") md_file.write("\n## Glossary\n\n") - md_file.write(""" + md_file.write( + """ - `source_code`: Whether a repo URL is present and valid - `source_code_sha`: Whether a commit SHA is available and valid - `forks`: Whether the repo is a fork @@ -731,8 +734,8 @@ def write_summary( - `provenance`: Whether build provenance/attestation is provided - `code_signature`: Whether a code signature is present and valid - `aliased_packages`: Whether a package is aliased under a different name -""") - +""" + ) md_file.write("---\n") md_file.write("\nReport created by [dirty-waters](https://github.com/chains-project/dirty-waters/).\n") @@ -748,7 +751,15 @@ def write_summary( def get_s_summary( - data, deps_list, project_name, release_version, package_manager, enabled_checks, gradual_report, summary_filename, config={} + data, + deps_list, + project_name, + release_version, + package_manager, + enabled_checks, + gradual_report, + summary_filename, + config={}, ): """ Get a summary of the static analysis results.