1# Applies "f" to all variation maps in modules and deps
2
3def transformModule(f):
4  .Variations = (.Variations | f) |
5  .DependencyVariations = (.DependencyVariations | f)
6;
7
8def transformModuleReferences(f):
9  transformModule(f) |
10  .Deps = [.Deps | .[] | transformModule(f)]
11;
12
13
14
15# Utility functions for transforming modules
16
17def deleteDependencyVariations:
18  if .DependencyVariations == .Variations then del(.DependencyVariations) else . end
19;
20
21
22# Utility functions for transforming variation maps
23
24def emptyIfNull: if . == null then {} else . end
25;
26
27def flattenVariations:
28  [. as $m | . | keys | sort | .[] | . + "=" + ($m[.] | tostring)] | join(", ")
29;
30
31def removeLinkVariation:
32  del(.link)
33;
34
35def removeEmptyVariations:
36  del(.[] | select(. == ""))
37;
38
39# Computes the difference of two maps, returns it as a single string
40def mapDelta($outer; $inner):
41  $outer | keys as $outerKeys |
42  $inner | keys as $innerKeys |
43  ($outerKeys - $innerKeys) as $removed |
44  ($innerKeys - $outerKeys) as $added |
45  [($removed | .[] | "-" + . + "=" + $outer[.]), ($added | .[] | "+" + . + "=" + $inner[.])] |
46  join(", ")
47;
48
49# Transforms the variation map of dependencies (as specified by f) to a delta
50# from the variation map of the module that depends on them
51def depDelta(f):
52  f as $outer |
53  (.Deps | .[] | f) |= (. | mapDelta($outer; .))
54;
55
56# "filterMatchingDeps"  filters deps that have different variations
57
58def differentDep($od; $ov):
59  (.DependencyVariations != $od or .Variations != $ov) and
60  (.DependencyVariations != {} or .Variations != {})
61;
62
63def filterMatchingDeps: .Variations as $ov |
64  .DependencyVariations as $od |
65  .Deps = [.Deps[] | select(differentDep($ov; $od))]
66;
67
68
69def groupDeps:
70  group_by({Variations, DependencyVariations, Tag}) |
71  map({
72    DependencyVariations: .[0].DependencyVariations,
73    Variations: .[0].Variations,
74    Tag: .[0].Tag | sub(" {BaseDependencyTag:{}(?<g>.*)}"; "\(.g)"),
75    Modules: map(.Name)
76  } | del(if has("DependencyVariations") then .DependencyVariations else empty end))
77
78;
79
80# Utilities for filtering out interesting modules (deps remain untouched)
81
82def onlyDeps:
83  { Name: .Name, Deps: .Deps | map(.Name) }
84;
85
86def mergeDepsForSameModule:
87  group_by(.Name) | map({Name: .[0].Name, Deps: map(.Deps) | flatten | unique | sort})
88;
89
90def toMergeMap:
91  map({key: .Name, value: .Deps}) | from_entries
92;
93
94def moduleGraphNoVariants:
95  map(onlyDeps) | mergeDepsForSameModule | toMergeMap
96;
97
98def removeSelfEdges:
99  to_entries |
100  map(.key as $key | {key: .key, value: .value | [.[] | select(. != $key)]}) |
101  from_entries
102;
103
104def directDeps($m):
105  map($m[.] // []) + [.] | flatten | unique
106;
107
108def transitiveDeps($m):
109  {Prev: [], Next: .} |
110  until (.Prev == .Next; {Prev: .Next, Next: .Next | directDeps($m)}) |
111  .Next
112;
113
114def findEdge($from;$to):
115  .[] | select(.Name == $from) |
116  .Deps |= [.[] | select(.Name == $to)] |
117  select((.Deps | length) > 0)
118;
119