Warning, file /sdk/kde-dev-scripts/pim-build-deps-graphs.py was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 #!/usr/bin/python 0002 # -*- coding: utf-8 -*- 0003 0004 # Copyright (C) 2017 Sandro Knauß <sknauss@kde.org> 0005 # 0006 # This program is free software: you can redistribute it and/or modify 0007 # it under the terms of the GNU General Public License as published by 0008 # the Free Software Foundation, either version 3 of the License, or 0009 # (at your option) any later version. 0010 0011 """Graph the dependencies of all pim packages. 0012 0013 The dependencies are minimized, so that only direct dependencies are shown. 0014 The green dots are packages without depdencies inside the set. 0015 The lightblue dots are one end of the build chain. 0016 0017 If you have something like this: 0018 0019 a -> b -> c 0020 a -> c 0021 the second depdency is not shown. 0022 0023 You can enable the full dependency if you replace sgraph -> graph in the last for loop. 0024 0025 The tier graph shows you a tier based view to pim packages. 0026 One tier is defined as a maximum set of packages, that do not depend on each other and only 0027 depend on lower tiers. Only dependecies from one tier to the next one are shown. Ellipsed shape 0028 packages without arrows are indicating, that they could be built in a higher tier. Diamond shape 0029 indicate that nothing depends on this anymore. 0030 0031 usage: 0032 git clone kde:kde-build-metadata 0033 <pathto>/pim-build-deps-graphs.py > pim-graphs.dot 0034 dot -T png -o kde-build-metadata-17.12-deps.png pim-graphs.dot > kde-build-metadata-17.12-tier.png 0035 """ 0036 0037 from __future__ import print_function 0038 0039 import re 0040 import copy 0041 0042 __fresh_id = 0 0043 0044 def main(): 0045 def get_id(): 0046 global __fresh_id 0047 __fresh_id += 1 0048 return ("NODE_%d" % __fresh_id) 0049 0050 def emit_arc(node1, node2): 0051 print(' "%s" -> "%s" ;' % (node1, node2)) 0052 def emit_node(node, dsc=None): 0053 if dsc is None: 0054 print(' "%s";' % (node)) 0055 else: 0056 print(' "%s" [label="%s"];' % (node, dsc)) 0057 def emit_nodecolor(node, color): 0058 print(' "%s" [fillcolor="%s", style="filled"] ;' % (node, color)) 0059 0060 0061 line = re.compile(r"^([^#^:]+):\s*([^#]+)\s*(#.*)?$") 0062 graph = {} 0063 for i in open('kde-build-metadata/dependency-data-kf5-qt5').readlines(): 0064 if not i.strip(): 0065 continue 0066 m = line.match(i) 0067 if not m: 0068 continue 0069 pkg = m.group(1).strip() 0070 dep = m.group(2).strip() 0071 if not pkg.startswith("kde/pim/"): 0072 continue 0073 else: 0074 pkg = pkg[len("kde/pim/"):] 0075 0076 if not pkg in graph: 0077 graph[pkg] = set() 0078 0079 if not dep.startswith("kde/pim/"): 0080 continue 0081 else: 0082 dep = dep[len("kde/pim/"):] 0083 0084 if not dep in graph: 0085 graph[dep] = set() 0086 0087 graph[pkg].add(dep) 0088 0089 sgraph = {} # minimized graph 0090 fgraph = graph # full dependency graph 0091 0092 for i in range(10): 0093 changed = False 0094 ograph = fgraph 0095 for pkg in ograph: 0096 deps = copy.copy(ograph[pkg]) 0097 for dep in ograph[pkg]: 0098 deps |= ograph[dep] 0099 if deps != ograph[pkg]: 0100 changed = True 0101 fgraph[pkg] = deps 0102 0103 if not changed: 0104 break 0105 0106 for pkg in fgraph: 0107 deps = copy.copy(graph[pkg]) 0108 for dep in graph[pkg]: 0109 deps -= fgraph[dep] 0110 sgraph[pkg] = deps 0111 0112 pkgs = set(graph.keys()) # packages to order into tiers 0113 tiers = [] # each tier will be one entry 0114 deps = set() # All deps from lower tiers 0115 0116 while pkgs: 0117 tD = set() 0118 if tiers: 0119 deps |= tiers[-1] 0120 tiers.append(set()) 0121 for pkg in pkgs: 0122 if not (sgraph[pkg] - deps): 0123 tiers[-1].add(pkg) 0124 tD.add(pkg) 0125 pkgs -= tD 0126 0127 ends = set() 0128 0129 for pkg in graph: 0130 name = pkg 0131 sDeps = sgraph[pkg] 0132 if sDeps: 0133 for p in sgraph: 0134 if p == pkg: 0135 continue 0136 if pkg in sgraph[p]: 0137 break 0138 else: 0139 ends.add(name) 0140 0141 print("digraph pim {") 0142 for pkg in graph: 0143 name = pkg 0144 sDeps = sgraph[pkg] 0145 if sDeps == set(): 0146 emit_nodecolor(name, 'darkgreen') 0147 else: 0148 for p in sgraph: 0149 if p == pkg: 0150 continue 0151 if pkg in sgraph[p]: 0152 break 0153 else: 0154 emit_nodecolor(name, 'lightblue') 0155 0156 for pkg in graph: 0157 name = pkg 0158 sDeps = sgraph[pkg] 0159 for dep in sDeps: 0160 emit_arc(dep, name) 0161 print("}") 0162 0163 print("digraph pimTier {") 0164 print(" node [shape=diamond,fillcolor=lightblue,style=filled];") 0165 for pkg in ends: # all end notes 0166 emit_node(pkg) 0167 print(" node [shape=ellipse,fillcolor=darkgreen];") 0168 for pkg in tiers[0]: # all dependency free packages - aka tier 0 0169 emit_node(pkg) 0170 print(" node [shape=ellipse,fillcolor=white];") 0171 for index, tier in enumerate(tiers): 0172 print(" subgraph cluster_{} {{".format(index)) 0173 print(" style=filled;") 0174 print(" color=lightgrey;") 0175 print(' label = "Tier {}";'.format(index)) 0176 for pkg in tier: 0177 emit_node(pkg) 0178 print(" }") 0179 if index > 0: 0180 subTier = tiers[index-1] 0181 for pkg in tier: 0182 for dep in (sgraph[pkg] & subTier): 0183 emit_arc(dep, pkg) 0184 print("}") 0185 0186 0187 0188 if __name__ == '__main__': 0189 main() 0190