Skip to content

Commit 6b113c0

Browse files
committed
Fix report links in Console and JSON
Assisted-by: Codex:gpt-6-luna
1 parent a0819f8 commit 6b113c0

6 files changed

Lines changed: 417 additions & 80 deletions

File tree

‎pyproject.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
66

77
[project]
88
name = "socketsecurity"
9-
version = "2.10.11"
9+
version = "2.10.12"
1010
requires-python = ">= 3.11"
1111
license = {"file" = "LICENSE"}
1212
dependencies = [

‎socketsecurity/__init__.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
__author__ = 'socket.dev'
2-
__version__ = '2.10.11'
2+
__version__ = '2.10.12'
33
USER_AGENT = f'SocketPythonCLI/{__version__}'
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
from dataclasses import dataclass
2+
from typing import Optional
3+
4+
from socketsecurity.config import CliConfig
5+
from socketsecurity.core.alert_selection import (
6+
clone_diff_with_selected_alerts,
7+
select_diff_alerts,
8+
)
9+
from socketsecurity.core.classes import Diff
10+
from socketsecurity.core.messages import Messages
11+
12+
13+
@dataclass(frozen=True)
14+
class ReportReferences:
15+
full_scan_id: str
16+
report_url: Optional[str]
17+
diff_url: Optional[str]
18+
is_full_scan: bool
19+
20+
def console_link(self) -> Optional[tuple[str, str]]:
21+
if self.is_full_scan:
22+
if self.report_url:
23+
return "Report Url", self.report_url
24+
if self.diff_url:
25+
return "Report Url", self.diff_url
26+
else:
27+
if self.diff_url:
28+
return "Diff Url", self.diff_url
29+
if self.report_url:
30+
return "Report Url", self.report_url
31+
return None
32+
33+
34+
def build_report_references(diff_report: Diff) -> ReportReferences:
35+
return ReportReferences(
36+
full_scan_id=getattr(diff_report, "id", ""),
37+
report_url=getattr(diff_report, "report_url", None),
38+
diff_url=getattr(diff_report, "diff_url", ""),
39+
is_full_scan=getattr(diff_report, "is_full_scan", False),
40+
)
41+
42+
43+
def build_console_summary(diff_report: Diff, config: CliConfig) -> str:
44+
references = build_report_references(diff_report)
45+
is_full_scan = references.is_full_scan
46+
link = references.console_link()
47+
48+
if is_full_scan and not getattr(diff_report, "alerts_fetched", False):
49+
lines = ["Full scan completed. Findings were not fetched for console output."]
50+
if link:
51+
lines.append(f"{link[0]}: {link[1]}")
52+
return "\n".join(lines)
53+
54+
selected_alerts = select_diff_alerts(
55+
diff_report,
56+
strict_blocking=config.strict_blocking,
57+
)
58+
has_new_alerts = len(selected_alerts) > 0
59+
has_unchanged_alerts = (
60+
config.strict_blocking
61+
and hasattr(diff_report, "unchanged_alerts")
62+
and len(diff_report.unchanged_alerts) > 0
63+
)
64+
65+
if not has_new_alerts and not has_unchanged_alerts:
66+
if link:
67+
return f"No issues found\n{link[0]}: {link[1]}"
68+
return "No issues found"
69+
70+
new_blocking = sum(1 for issue in diff_report.new_alerts if issue.error)
71+
new_warning = sum(1 for issue in diff_report.new_alerts if issue.warn)
72+
73+
unchanged_blocking = 0
74+
unchanged_warning = 0
75+
if has_unchanged_alerts:
76+
unchanged_blocking = sum(
77+
1 for issue in diff_report.unchanged_alerts if issue.error
78+
)
79+
unchanged_warning = sum(
80+
1 for issue in diff_report.unchanged_alerts if issue.warn
81+
)
82+
83+
selected_diff = clone_diff_with_selected_alerts(diff_report, selected_alerts)
84+
console_security_comment = Messages.create_console_security_alert_table(
85+
selected_diff
86+
)
87+
88+
blocking_label = "Blocking issues" if is_full_scan else "NEW blocking issues"
89+
warning_label = "Warning issues" if is_full_scan else "NEW warning issues"
90+
91+
lines = ["Security issues detected by Socket Security:"]
92+
if new_blocking > 0:
93+
lines.append(f" - {blocking_label}: {new_blocking}")
94+
if new_warning > 0:
95+
lines.append(f" - {warning_label}: {new_warning}")
96+
if unchanged_blocking > 0:
97+
lines.append(
98+
f" - EXISTING blocking issues: {unchanged_blocking} "
99+
"(causing failure due to --strict-blocking)"
100+
)
101+
if unchanged_warning > 0:
102+
lines.append(f" - EXISTING warning issues: {unchanged_warning}")
103+
if is_full_scan:
104+
lines.append(
105+
" Reported against the whole repository, with no baseline to compare "
106+
"against, so these do not affect the exit code."
107+
)
108+
109+
if link:
110+
lines.append(f"{link[0]}: {link[1]}")
111+
lines.append("")
112+
lines.append(str(console_security_comment))
113+
return "\n".join(lines)
114+
115+
116+
def build_socket_json_report(
117+
diff_report: Diff,
118+
config: CliConfig,
119+
) -> dict[str, object]:
120+
references = build_report_references(diff_report)
121+
selected_alerts = select_diff_alerts(
122+
diff_report,
123+
strict_blocking=config.strict_blocking,
124+
)
125+
selected_diff = clone_diff_with_selected_alerts(diff_report, selected_alerts)
126+
report = Messages.create_security_comment_json(selected_diff)
127+
legal_flag = getattr(config, "legal", False)
128+
repo = getattr(config, "repo", None)
129+
branch = getattr(config, "branch", None)
130+
commit_sha = getattr(config, "commit_sha", None)
131+
report["full_scan_id"] = references.full_scan_id
132+
report["diff_url"] = references.diff_url
133+
report["report_url"] = references.report_url
134+
report["repo"] = repo if isinstance(repo, str) or repo is None else None
135+
report["branch"] = branch if isinstance(branch, str) or branch is None else None
136+
report["commit_sha"] = (
137+
commit_sha if isinstance(commit_sha, str) or commit_sha is None else None
138+
)
139+
report["legal_mode"] = legal_flag if isinstance(legal_flag, bool) else False
140+
return report

‎socketsecurity/output.py‎

Lines changed: 3 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from .config import CliConfig
1717
from .core.classes import Diff, Issue
1818
from .core.messages import Messages
19+
from .core.report_output import build_console_summary, build_socket_json_report
1920
from .fossa_compat import build_fossa_report_payload
2021

2122

@@ -229,88 +230,13 @@ def save_sbom_file(self, diff_report: Diff, sbom_file_name: Optional[str] = None
229230

230231
def build_summary_text(self, diff_report: Diff) -> str:
231232
"""Render the console summary text for stdout and file output."""
232-
is_full_scan = getattr(diff_report, "is_full_scan", False)
233-
if is_full_scan and not getattr(diff_report, "alerts_fetched", False):
234-
lines = ["Full scan completed. Findings were not fetched for console output."]
235-
report_link = getattr(diff_report, "report_url", "") or getattr(
236-
diff_report, "diff_url", ""
237-
)
238-
if report_link:
239-
lines.append(f"Report Url: {report_link}")
240-
return "\n".join(lines)
241-
242-
selected_alerts = select_diff_alerts(diff_report, strict_blocking=self.config.strict_blocking)
243-
has_new_alerts = len(selected_alerts) > 0
244-
has_unchanged_alerts = (
245-
self.config.strict_blocking and
246-
hasattr(diff_report, 'unchanged_alerts') and
247-
len(diff_report.unchanged_alerts) > 0
248-
)
249-
250-
if not has_new_alerts and not has_unchanged_alerts:
251-
return "No issues found"
252-
253-
new_blocking = sum(1 for issue in diff_report.new_alerts if issue.error)
254-
new_warning = sum(1 for issue in diff_report.new_alerts if issue.warn)
255-
256-
unchanged_blocking = 0
257-
unchanged_warning = 0
258-
if has_unchanged_alerts:
259-
unchanged_blocking = sum(1 for issue in diff_report.unchanged_alerts if issue.error)
260-
unchanged_warning = sum(1 for issue in diff_report.unchanged_alerts if issue.warn)
261-
262-
selected_diff = clone_diff_with_selected_alerts(diff_report, selected_alerts)
263-
console_security_comment = Messages.create_console_security_alert_table(selected_diff)
264-
265-
# A full scan has no baseline, so everything it carries is a finding in the
266-
# repository rather than one the change introduced. Calling those NEW would
267-
# also contradict the exit code, which stays 0 because no finding can be
268-
# attributed to the change.
269-
blocking_label = "Blocking issues" if is_full_scan else "NEW blocking issues"
270-
warning_label = "Warning issues" if is_full_scan else "NEW warning issues"
271-
link_label = "Report Url" if is_full_scan else "Diff Url"
272-
273-
lines = ["Security issues detected by Socket Security:"]
274-
if new_blocking > 0:
275-
lines.append(f" - {blocking_label}: {new_blocking}")
276-
if new_warning > 0:
277-
lines.append(f" - {warning_label}: {new_warning}")
278-
if unchanged_blocking > 0:
279-
lines.append(
280-
f" - EXISTING blocking issues: {unchanged_blocking} (causing failure due to --strict-blocking)"
281-
)
282-
if unchanged_warning > 0:
283-
lines.append(f" - EXISTING warning issues: {unchanged_warning}")
284-
if is_full_scan:
285-
lines.append(
286-
" Reported against the whole repository, with no baseline to compare "
287-
"against, so these do not affect the exit code."
288-
)
289-
290-
report_link = getattr(diff_report, "report_url", "") or getattr(diff_report, "diff_url", "")
291-
lines.append(f"{link_label}: {report_link}")
292-
lines.append("")
293-
lines.append(str(console_security_comment))
294-
return "\n".join(lines)
233+
return build_console_summary(diff_report, self.config)
295234

296235
def build_json_report(self, diff_report: Diff) -> dict:
297236
"""Build the JSON report payload for stdout and file output."""
298237
if getattr(self.config, "legal_format", "socket") == "fossa":
299238
return build_fossa_report_payload(diff_report, self.config)
300-
301-
selected_alerts = select_diff_alerts(diff_report, strict_blocking=self.config.strict_blocking)
302-
selected_diff = clone_diff_with_selected_alerts(diff_report, selected_alerts)
303-
report = Messages.create_security_comment_json(selected_diff)
304-
legal_flag = getattr(self.config, "legal", False)
305-
repo = getattr(self.config, "repo", None)
306-
branch = getattr(self.config, "branch", None)
307-
commit_sha = getattr(self.config, "commit_sha", None)
308-
report["report_url"] = getattr(diff_report, "report_url", None)
309-
report["repo"] = repo if isinstance(repo, str) or repo is None else None
310-
report["branch"] = branch if isinstance(branch, str) or branch is None else None
311-
report["commit_sha"] = commit_sha if isinstance(commit_sha, str) or commit_sha is None else None
312-
report["legal_mode"] = legal_flag if isinstance(legal_flag, bool) else False
313-
return report
239+
return build_socket_json_report(diff_report, self.config)
314240

315241
def save_json_file(self, diff_report: Diff, json_file_name: Optional[str] = None) -> None:
316242
if not json_file_name:

0 commit comments

Comments
 (0)