My aggregated monorepo of OCaml code, automaintained
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Show sole-blocker count in results output

For each root failure, shows both total blocks and how many packages
it's the only blocker for. E.g. "blocks 418, 73 sole" means fixing
this would unblock at least 73 packages immediately.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+20 -10
+20 -10
day11/bin/cmd_results.ml
··· 100 100 Hashtbl.replace failed_set m.package () 101 101 ) failed; 102 102 (* For each solved package, find which failed packages it 103 - transitively depends on. Count how many packages each 104 - failure blocks. *) 103 + transitively depends on. Track total blocks and sole-blocker count. *) 105 104 let blocked_count : (string, int) Hashtbl.t = Hashtbl.create 64 in 105 + let sole_blocker_count : (string, int) Hashtbl.t = Hashtbl.create 64 in 106 106 Hashtbl.iter (fun pkg_str solution -> 107 - (* Walk the solution's deps to find any failed package *) 107 + (* Walk the solution's deps to collect all failed deps *) 108 108 let visited : (string, unit) Hashtbl.t = Hashtbl.create 16 in 109 + let failed_deps = ref [] in 109 110 let rec walk pkg = 110 111 let key = OpamPackage.to_string pkg in 111 112 if Hashtbl.mem visited key then () 112 113 else begin 113 114 Hashtbl.replace visited key (); 114 - if Hashtbl.mem failed_set key && key <> pkg_str then begin 115 - let n = try Hashtbl.find blocked_count key 116 - with Not_found -> 0 in 117 - Hashtbl.replace blocked_count key (n + 1) 118 - end; 115 + if Hashtbl.mem failed_set key && key <> pkg_str then 116 + failed_deps := key :: !failed_deps; 119 117 match OpamPackage.Map.find_opt pkg solution with 120 118 | Some deps -> 121 119 OpamPackage.Set.iter walk deps ··· 123 121 end 124 122 in 125 123 let pkg = OpamPackage.of_string pkg_str in 126 - walk pkg 124 + walk pkg; 125 + let unique_failed = List.sort_uniq String.compare !failed_deps in 126 + List.iter (fun dep -> 127 + let n = try Hashtbl.find blocked_count dep with Not_found -> 0 in 128 + Hashtbl.replace blocked_count dep (n + 1); 129 + if List.length unique_failed = 1 then begin 130 + let n = try Hashtbl.find sole_blocker_count dep with Not_found -> 0 in 131 + Hashtbl.replace sole_blocker_count dep (n + 1) 132 + end 133 + ) unique_failed 127 134 ) all_solutions; 128 135 (* Separate root cause failures from cascaded failures using failed_dep *) 129 136 let root_failures = List.filter (fun (_, (m : Day11_layer.Layer_meta.build_meta)) -> ··· 155 162 let patched = if m.patches <> [] then 156 163 Printf.sprintf " [patched: %s]" (String.concat ", " m.patches) 157 164 else "" in 165 + let sole = try Hashtbl.find sole_blocker_count m.package 166 + with Not_found -> 0 in 158 167 if blocks > 0 then 159 - Printf.printf " %-45s (blocks %d)%s\n" m.package blocks patched 168 + Printf.printf " %-45s (blocks %d, %d sole)%s\n" 169 + m.package blocks sole patched 160 170 else 161 171 Printf.printf " %-45s%s\n" m.package patched 162 172 ) root_failures