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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
# File 'lib/archruby/presenters/graph.rb', line 8
def render architecture
modules = architecture.modules
g = GraphViz.new(:G)
g.edge[:color] = "black"
g.edge[:style] = "filled"
g.edge[:label] = ""
internal = g.subgraph("internal", "label" => "Internal", "color" => "black")
external = g.subgraph("external", "label" => "External", "color" => "black", "rank" => "same")
nodes = {}
internal_nodes = []
external_nodes = []
modules.each do |module_definiton|
next if module_definiton.name == Archruby::Ruby::STD_LIB_NAME || module_definiton.name == Archruby::Ruby::CORE_LIB_NAME
if module_definiton.is_external?
nodes[module_definiton.name] = external.add_nodes(module_definiton.name, "shape" => "parallelogram", "color" => "gray60", "style" => "filled")
external_nodes << nodes[module_definiton.name]
else
if module_definiton.is_empty?
nodes[module_definiton.name] = internal.add_nodes("#{module_definiton.name}\n [empty]", "color" => "gray74", "shape" => "rectangle")
else
nodes[module_definiton.name] = internal.add_nodes(module_definiton.name, "color" => "gray92", "style" => "filled", "shape" => "rectangle")
end
internal_nodes << nodes[module_definiton.name]
end
end
edges = {}
edges_objs = []
modules.each do |module_definiton|
module_name = module_definiton.name
node_origin = nodes[module_name]
edges[module_name] ||= {}
edges[module_name][:edges] ||= []
module_definiton.dependencies.each do |class_name|
module_dest = architecture.module_name class_name
next if module_dest == Archruby::Ruby::STD_LIB_NAME || module_dest == Archruby::Ruby::CORE_LIB_NAME
how_many_access = architecture.how_many_access_to module_name, module_dest
if !edges[module_name][:edges].include?(module_dest) && module_dest != module_name
edges[module_name][:edges] << module_dest
node_dest = nodes[module_dest]
edges_objs << internal.add_edges(node_origin, node_dest, :headlabel => how_many_access, :minlen => 2)
end
end
end
constraints_breaks = architecture.constraints_breaks
constraints_breaks.each_with_index do |constraint_break, index|
module_origin = constraint_break.module_origin
module_target = constraint_break.module_target
contraint_type = constraint_break.type
node_origin = nodes[module_origin]
node_dest = nodes[module_target]
node_found = false
edges_objs.each do |edge|
if edge.node_one == module_origin && edge.node_two == module_target
if contraint_type == Archruby::Architecture::ConstraintBreak::ABSENSE
edge.set do |e|
e.headlabel = "X (##{architecture.how_many_break(module_origin, module_target, Archruby::Architecture::ConstraintBreak::ABSENSE)})"
e.color = "red"
e.style = "bold"
e.minlen = 2
end
else
edge.set do |e|
e.headlabel = "! (##{architecture.how_many_break(module_origin, module_target, Archruby::Architecture::ConstraintBreak::DIVERGENCE)})"
e.color = "orange"
e.style = "bold"
e.minlen = 2
end
end
node_found = true
break
end
end
if !node_found
if contraint_type == Archruby::Architecture::ConstraintBreak::ABSENSE
break_count = architecture.how_many_break(module_origin, module_target, Archruby::Architecture::ConstraintBreak::ABSENSE)
edges_objs << g.add_edges(node_origin, node_dest, :color => 'red', :headlabel => "X (##{break_count})", 'style' => 'bold', :minlen => 2)
else
break_count = architecture.how_many_break(module_origin, module_target, Archruby::Architecture::ConstraintBreak::DIVERGENCE)
edges_objs << g.add_edges(node_origin, node_dest, :color => 'red', :headlabel => "! (##{break_count})", 'style' => 'bold', :minlen => 2)
end
end
end
modules.each do |module_definiton|
next if module_definiton.name == Archruby::Ruby::STD_LIB_NAME || module_definiton.name == Archruby::Ruby::CORE_LIB_NAME
module_origin = module_definiton.is_empty? ? "#{module_definiton.name}\n [empty]" : module_definiton.name
node_origin = nodes[module_origin]
module_definiton.allowed_modules.each do |allowed_module_name|
module_target = allowed_module_name
node_dest = nodes[allowed_module_name]
edge_found = false
edges_objs.each do |edge|
if edge.node_one == module_origin && edge.node_two == module_target
edge_found = true
break
end
end
if !edge_found
internal.add_edges(node_origin, node_dest, :color => 'gray74', :label => "[none]", :minlen => 2)
end
end
end
g.output( :png => "architecture.png" )
end
|