Let the project name and the manufacturer be supplied on the command line

Neither is recorded in the artifacts: the metadata's repository_name is
empty and nothing names a manufacturer. --project wins over the metadata.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
alexanderandClaude Opus 5.5 committed 2026-09-24 20:41:56 +02:00
1 parent 5959d9364b
commit dc8ed38d8c
4 files changed
+69 -15

No files matched your search

+20 -8
View File
@@ -53,13 +53,21 @@ SEVERITY_OF_LEVEL = {
SEVERITY_ORDER = ("Critical", "High", "Medium", "Low")
def build_context(sources: ReportSources, documents: dict[str, Any]) -> dict[str, Any]:
def build_context(
sources: ReportSources,
documents: dict[str, Any],
*,
project: str | None = None,
manufacturer: str | None = None,
) -> dict[str, Any]:
"""Build the report context from a scan's parsed artifacts.
Args:
sources: The scan and its stored files.
documents: The parsed artifacts by role -- ``metadata``, ``findings``,
``vulnerabilities`` -- each absent where the scan stored none.
project: The project name the caller supplied. Wins over the one in the metadata.
manufacturer: The manufacturer the caller supplied. The artifacts never name one.
Returns:
The context :func:`layout.render_pdf`
@@ -67,11 +75,12 @@ def build_context(sources: ReportSources, documents: dict[str, Any]) -> dict[str
the template renders as a shorter report.
"""
metadata = documents.get("metadata") or {}
project = project or (metadata.get("configuration") or {}).get("repository_name")
tools = _tools(documents.get("findings"))
sca = summarize_vdr(documents["vulnerabilities"]) if documents.get("vulnerabilities") else None
context: dict[str, Any] = {
"cover": _cover(sources, metadata, tools, sca),
"cover": _cover(sources, metadata, tools, sca, project=project, manufacturer=manufacturer),
"summary": _summary(tools, sca, documents.get("metrics")),
"sections": [_tool_section(name, report) for name, report in tools],
}
@@ -79,7 +88,7 @@ def build_context(sources: ReportSources, documents: dict[str, Any]) -> dict[str
# Without the pipeline's metadata these two pages would be nothing but gaps.
if metadata:
context["scan"] = _scan(sources, metadata)
context["project"] = _project(metadata)
context["project"] = _project(metadata, project)
critical = _critical(tools, sca)
@@ -153,6 +162,9 @@ def _cover(
metadata: dict[str, Any],
tools: list[tuple[str, SarifReport]],
sca: VdrReport | None,
*,
project: str | None,
manufacturer: str | None,
) -> dict[str, Any]:
"""The first page."""
configuration = metadata.get("configuration") or {}
@@ -160,17 +172,17 @@ def _cover(
return {
"scan_id": str(sources.scan_id),
"subject": _stated(configuration.get("repository_name")),
"subject": _stated(project),
"footer_date": datetime.now(UTC).strftime("%d %B %Y"),
"logo": "cc_logo.png",
"title": TITLE,
"identity": [
_fact("Scan Identifier", sources.scan_id, kind="mono"),
_fact("Technology", ", ".join(technologies) or None),
_fact("Project", configuration.get("repository_name"), gap=True),
_fact("Project", project, gap=True),
_fact("Version", configuration.get("repository_version")),
_fact("Report Created", datetime.now(UTC).strftime("%A, %B %d, %Y")),
_fact("Manufacturer", None),
_fact("Manufacturer", manufacturer),
],
"severity_ledger": _severity_ledger(tools, sca),
}
@@ -238,7 +250,7 @@ def _stage(stage: dict[str, Any], sources: ReportSources) -> dict[str, Any]:
}
def _project(metadata: dict[str, Any]) -> dict[str, Any]:
def _project(metadata: dict[str, Any], project: str | None) -> dict[str, Any]:
"""What was scanned."""
configuration = metadata.get("configuration") or {}
@@ -246,7 +258,7 @@ def _project(metadata: dict[str, Any]) -> dict[str, Any]:
"id": "project",
"title": "Project Information",
"overview": [
_fact("Project", configuration.get("repository_name")),
_fact("Project", project),
_fact("Version", configuration.get("repository_version")),
# Nothing in the pipeline counts lines, so nothing here can report them.
_fact("Analysed lines of code", None),