1include "library"; 2 3def onlyDeps: 4 { Name: .Name, Deps: .Deps | map(.Name) } 5; 6 7def mergeDepsForSameModule: 8 group_by(.Name) | map({Name: .[0].Name, Deps: map(.Deps) | flatten | unique | sort}) 9; 10 11def toMergeMap: 12 map({key: .Name, value: .Deps}) | from_entries 13; 14 15def moduleGraphNoVariants: 16 map(onlyDeps) | mergeDepsForSameModule | toMergeMap 17; 18 19def removeSelfEdges: 20 to_entries | 21 map(.key as $key | {key: .key, value: .value | [.[] | select(. != $key)]}) | 22 from_entries 23; 24 25def nextDepths($m): 26 . as $old | 27 to_entries | 28 map({ 29 key: .key, 30 value: ( 31 .key as $key | 32 $m[.key] // [] | 33 map($old[.]) | 34 if any(. == -1) then -1 else (max // -1) + 1 end 35 ) 36 }) | 37 from_entries 38; 39 40def maxDepths($m): 41 map({key: ., value: -1}) | from_entries | 42 {Prev: [], Next: .} | 43 until (.Prev == .Next; {Prev: .Next, Next: .Next | nextDepths($m)}) | 44 .Next 45; 46 47def variantlessDistancesFromLeaves($root): 48 (moduleGraphNoVariants | removeSelfEdges) as $m | 49 [$root] | 50 transitiveDeps($m) | 51 maxDepths($m) 52; 53 54variantlessDistancesFromLeaves($arg)