MCPcopy Create free account
hub / github.com/NVIDIA/OpenShell / render_report

Function render_report

crates/openshell-prover/src/report.rs:133–231  ·  view source on GitHub ↗

Render a full terminal report with finding panels. Returns exit code: 0 = pass, 1 = any findings present.

(findings: &[Finding], policy_path: &str, credentials_path: &str)

Source from the content-addressed store, hash-verified

131/// Render a full terminal report with finding panels.
132/// Returns exit code: 0 = pass, 1 = any findings present.
133pub fn render_report(findings: &[Finding], policy_path: &str, credentials_path: &str) -> i32 {
134 let policy_name = Path::new(policy_path)
135 .file_name()
136 .map_or("policy.yaml", |n| n.to_str().unwrap_or("policy.yaml"));
137 let creds_name = Path::new(credentials_path)
138 .file_name()
139 .map_or("credentials.yaml", |n| {
140 n.to_str().unwrap_or("credentials.yaml")
141 });
142
143 println!();
144 println!(
145 "{}",
146 "\u{250c}\u{2500}\u{2500} OpenShell Policy Prover \u{2500}\u{2500}\u{2510}".blue()
147 );
148 println!(" Policy: {policy_name}");
149 println!(" Credentials: {creds_name}");
150 println!();
151
152 let active: Vec<&Finding> = findings.iter().filter(|f| !f.accepted).collect();
153 let accepted: Vec<&Finding> = findings.iter().filter(|f| f.accepted).collect();
154
155 // Per-category summary
156 let mut counts: BTreeMap<&str, usize> = BTreeMap::new();
157 for f in &active {
158 *counts.entry(f.query.as_str()).or_default() += f.paths.len();
159 }
160
161 if active.is_empty() && accepted.is_empty() {
162 println!("{}", "No findings. Policy posture is clean.".green().bold());
163 return 0;
164 }
165
166 println!("{}", "Finding Summary".bold().underline());
167 for (query, count) in &counts {
168 println!(" {:>40} {count} path(s)", category_label(query).yellow());
169 }
170 if !accepted.is_empty() {
171 println!(" {:>40} {}", "ACCEPTED".dimmed(), accepted.len());
172 }
173 println!();
174
175 for (i, finding) in active.iter().enumerate() {
176 println!(
177 "--- Finding #{} [{}] ---",
178 i + 1,
179 category_label(&finding.query)
180 );
181 println!(" {}", finding.title.bold());
182 println!(" {}", finding.description);
183 println!();
184 render_paths(&finding.paths);
185 if !finding.remediation.is_empty() {
186 println!(" {}", "Remediation:".bold());
187 for r in &finding.remediation {
188 println!(" - {r}");
189 }
190 println!();

Callers 1

proveFunction · 0.85

Calls 4

render_pathsFunction · 0.85
lenMethod · 0.80
as_strMethod · 0.45
is_emptyMethod · 0.45

Tested by

no test coverage detected