aboutsummaryrefslogtreecommitdiff
path: root/json_module_graph/distanceFromLeaves.jq
blob: d48fa67445493e7078eddc202af5cde28c3a3a8f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# CMD: Returns the maximum distance from a leaf for each module

include "library";

def onlyDeps:
  { Name: .Name, Deps: .Deps | map(.Name) }
;

def mergeDepsForSameModule:
  group_by(.Name) | map({Name: .[0].Name, Deps: map(.Deps) | flatten | unique | sort})
;

def toMergeMap:
  map({key: .Name, value: .Deps}) | from_entries
;

def moduleGraphNoVariants:
  map(onlyDeps) | mergeDepsForSameModule | toMergeMap
;

def removeSelfEdges:
  to_entries |
  map(.key as $key | {key: .key, value: .value | [.[] | select(. != $key)]}) |
  from_entries
;

def nextDepths($m):
  . as $old |
  to_entries |
  map({
      key: .key,
      value: (
          .key as $key |
          $m[.key] // [] |
          map($old[.]) |
          if any(. == -1) then -1 else (max // -1) + 1 end
      )
  }) |
  from_entries
;

def maxDepths($m):
  map({key: ., value: -1}) | from_entries |
  {Prev: [], Next: .} |
  until (.Prev == .Next; {Prev: .Next, Next: .Next | nextDepths($m)}) |
  .Next
;

def variantlessDistancesFromLeaves($root):
  (moduleGraphNoVariants | removeSelfEdges) as $m |
  [$root] |
  transitiveDeps($m) |
  maxDepths($m)
;

variantlessDistancesFromLeaves($arg)