visualize_packs 0.5.5 → 0.5.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/bin/visualize_packs +2 -2
- data/lib/graph.dot.erb +15 -15
- data/lib/options.rb +1 -1
- data/lib/visualize_packs.rb +27 -28
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd8d9c383e056e9ca083b753f77d14ff951d2f0245d3cccb8570eb4a6ac5cf72
|
4
|
+
data.tar.gz: 98edaf0dd58faabbfc57e3d42b24ca43c5f5ea65227627f519815811a03970a6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 541e54ff0460769bccc2d7e8788a57a86c1fbb5929af3cc7b01bbcac36daf0f26bf7378745e89bf189c51fa63b3484c3b34d6493e85e1603cf976f1b6780945e
|
7
|
+
data.tar.gz: d0622a5d36ee4816b497f6fb2488be4ee1a86679729432f8304b27ce1120ff16e28fd1baefc790a1372b227932d9cd54ca5c13e7221f91271d33e717ff01f682
|
data/README.md
CHANGED
@@ -16,7 +16,7 @@ This will generate a local dependency diagram for every pack in your app
|
|
16
16
|
find . -iname 'package.yml' | sed 's/\/package.yml//g' | sed 's/\.\///' | xargs -I % sh -c "bundle exec visualize_packs --only=% > %/packs.dot && dot %/packs.dot -Tpng -o %/packs.png"
|
17
17
|
```
|
18
18
|
|
19
|
-
If your app is large and has many packages and
|
19
|
+
If your app is large and has many packages and todos, the above graphs will likely be too big. Try this version to get only the edges to and from the focus package for each diagram:
|
20
20
|
|
21
21
|
```
|
22
22
|
find . -iname 'package.yml' | sed 's/\/package.yml//g' | sed 's/\.\///' | xargs -I % sh -c "bundle exec visualize_packs --only=% --only-edges-to-focus > %/packs.dot && dot %/packs.dot -Tpng -o %/packs.png"
|
data/bin/visualize_packs
CHANGED
@@ -35,9 +35,9 @@ OptionParser.new do |opt|
|
|
35
35
|
opt.on('--focus-on=PACKAGE', "Focus on a specific package") { |o| options.focus_package = o }
|
36
36
|
opt.on('--only-edges-to-focus', "If focus is set, this shows only the edges to/from the focus node instead of all edges in the focussed graph. This only has effect when --focus-on is set.") { |o| options.show_only_edges_to_focus_package = true }
|
37
37
|
|
38
|
-
opt.on('--
|
38
|
+
opt.on('--roll-nested-into-parent-packs', "Don't show nested packages (not counting root). Connect edges to top-level package instead") { |o| options.roll_nested_into_parent_packs = true }
|
39
39
|
opt.on('--focus_folder=FOLDER', "Draw package diagram only for packages in FOLDER") { |o| options.focus_folder = o }
|
40
|
-
opt.on('--no_nested_relationships', "Don't draw nested
|
40
|
+
opt.on('--no_nested_relationships', "Don't draw relationships between parents and nested packs") { |o| options.show_nested_relationships = false }
|
41
41
|
|
42
42
|
opt.on('--exclude-packs=pack1,pack2,etc', "Exclude these packs from diagram") { |o| options.exclude_packs = o.to_s.split(",") }
|
43
43
|
|
data/lib/graph.dot.erb
CHANGED
@@ -81,30 +81,30 @@ digraph package_diagram {
|
|
81
81
|
<%- end -%>
|
82
82
|
<%- if options.show_todos -%>
|
83
83
|
<%- all_packages.each do |package| -%>
|
84
|
-
<%-
|
84
|
+
<%- filtered_todos = package.violations -%>
|
85
85
|
<%- if options.only_todo_types.any? -%>
|
86
|
-
<%-
|
86
|
+
<%- filtered_todos = filtered_todos.select { options.only_todo_types.include?(_1.type) } -%>
|
87
87
|
<%- end -%>
|
88
|
-
<%-
|
89
|
-
<%-
|
90
|
-
<%- todo_types =
|
91
|
-
<%- todo_types.keys.each do |
|
92
|
-
<%- if show_edge.call(package.name,
|
93
|
-
"<%= package.name -%>" -> "<%=
|
88
|
+
<%- todos_by_package = filtered_todos.group_by(&:to_package_name) -%>
|
89
|
+
<%- todos_by_package.keys.each do |todos_to_package| -%>
|
90
|
+
<%- todo_types = todos_by_package[todos_to_package].group_by(&:type) -%>
|
91
|
+
<%- todo_types.keys.each do |todo_type| -%>
|
92
|
+
<%- if show_edge.call(package.name, todos_to_package) -%>
|
93
|
+
"<%= package.name -%>" -> "<%= todos_to_package -%>"<%= todo_type == 'privacy' ? ':private' : '' -%> [ color=darkred style=dashed
|
94
94
|
constraint=false
|
95
|
-
# headlabel="<%=
|
96
|
-
<%- if
|
95
|
+
# headlabel="<%= todo_type -%>"
|
96
|
+
<%- if todo_type == 'privacy' -%>
|
97
97
|
arrowhead=crow
|
98
|
-
<%- elsif
|
98
|
+
<%- elsif todo_type == 'architecture' -%>
|
99
99
|
arrowhead=invodot
|
100
|
-
<%- elsif
|
100
|
+
<%- elsif todo_type == 'visibility' -%>
|
101
101
|
arrowhead=obox
|
102
|
-
<%- elsif
|
102
|
+
<%- elsif todo_type == 'dependency' -%>
|
103
103
|
arrowhead=odot
|
104
104
|
<%- end -%>
|
105
105
|
<%-
|
106
106
|
max_edge_width = 10
|
107
|
-
edge_width = (todo_types[
|
107
|
+
edge_width = (todo_types[todo_type].count / max_todo_count.to_f * max_edge_width).to_i
|
108
108
|
-%>
|
109
109
|
penwidth=<%= edge_width -%>
|
110
110
|
]
|
@@ -139,7 +139,7 @@ digraph package_diagram {
|
|
139
139
|
K [ fontsize=12 shape=box label="package"]
|
140
140
|
L [ fontsize=12 shape=box label="package"]
|
141
141
|
A -> B [label="accepted dependency" color=darkgreen]
|
142
|
-
C -> D [label="
|
142
|
+
C -> D [label="privacy todo" color=darkred style=dashed arrowhead=crow]
|
143
143
|
E -> F [label="architecture todo" color=darkred style=dashed arrowhead=invodot]
|
144
144
|
G -> H [label="visibility todo" color=darkred style=dashed arrowhead=obox]
|
145
145
|
I -> J [label="dependency todo" color=darkred style=dashed arrowhead=odot]
|
data/lib/options.rb
CHANGED
@@ -15,7 +15,7 @@ class Options < T::Struct
|
|
15
15
|
prop :focus_package, T.nilable(String)
|
16
16
|
prop :show_only_edges_to_focus_package, T::Boolean, default: false
|
17
17
|
|
18
|
-
prop :
|
18
|
+
prop :roll_nested_into_parent_packs, T::Boolean, default: false
|
19
19
|
prop :focus_folder, T.nilable(String)
|
20
20
|
prop :show_nested_relationships, T::Boolean, default: true
|
21
21
|
|
data/lib/visualize_packs.rb
CHANGED
@@ -14,13 +14,13 @@ module VisualizePacks
|
|
14
14
|
all_packages = filtered(packages, options.focus_package, options.focus_folder, options.exclude_packs).sort_by {|x| x.name }
|
15
15
|
all_package_names = all_packages.map &:name
|
16
16
|
|
17
|
-
all_packages = remove_nested_packs(all_packages) if options.
|
17
|
+
all_packages = remove_nested_packs(all_packages) if options.roll_nested_into_parent_packs
|
18
18
|
|
19
19
|
show_edge = show_edge_builder(options, all_package_names)
|
20
20
|
node_color = node_color_builder()
|
21
|
-
|
21
|
+
max_todo_count = max_todo_count(all_packages, show_edge)
|
22
22
|
|
23
|
-
title = diagram_title(options,
|
23
|
+
title = diagram_title(options, max_todo_count)
|
24
24
|
|
25
25
|
architecture_layers = (raw_config['architecture_layers'] || []) + ["NotInLayer"]
|
26
26
|
grouped_packages = architecture_layers.inject({}) do |result, key|
|
@@ -52,7 +52,7 @@ module VisualizePacks
|
|
52
52
|
package.config.dig("metadata", "owner") || package.config["owner"]
|
53
53
|
end
|
54
54
|
|
55
|
-
def self.diagram_title(options,
|
55
|
+
def self.diagram_title(options, max_todo_count)
|
56
56
|
app_name = File.basename(Dir.pwd)
|
57
57
|
focus_edge_info = options.focus_package && options.show_only_edges_to_focus_package ? "showing only edges to/from focus pack" : "showing all edges between visible packs"
|
58
58
|
focus_info = options.focus_package || options.focus_folder ? "Focus on #{[options.focus_package, options.focus_folder].compact.join(' and ')} (#{focus_edge_info})" : "All packs"
|
@@ -65,14 +65,14 @@ module VisualizePacks
|
|
65
65
|
options.only_todo_types.empty? ? nil : "only #{limited_sentence(options.only_todo_types)} todos",
|
66
66
|
options.show_privacy ? nil : "hiding privacy",
|
67
67
|
options.show_teams ? nil : "hiding teams",
|
68
|
-
options.
|
68
|
+
options.roll_nested_into_parent_packs ? "hiding nested packs" : nil,
|
69
69
|
options.show_nested_relationships ? nil : "hiding nested relationships",
|
70
70
|
options.exclude_packs.empty? ? nil : "excluding pack#{options.exclude_packs.size > 1 ? 's' : ''}: #{limited_sentence(options.exclude_packs)}",
|
71
71
|
].compact.join(', ').strip
|
72
72
|
main_title = "#{app_name}: #{focus_info}#{skipped_info != '' ? ' - ' + skipped_info : ''}"
|
73
73
|
sub_title = ""
|
74
|
-
if options.show_todos &&
|
75
|
-
sub_title = "<br/><font point-size='12'>Widest todo edge is #{
|
74
|
+
if options.show_todos && max_todo_count
|
75
|
+
sub_title = "<br/><font point-size='12'>Widest todo edge is #{max_todo_count} todo#{max_todo_count > 1 ? 's' : ''}</font>"
|
76
76
|
end
|
77
77
|
"<<b>#{main_title}</b>#{sub_title}>"
|
78
78
|
end
|
@@ -113,22 +113,22 @@ module VisualizePacks
|
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
116
|
-
def self.
|
117
|
-
|
116
|
+
def self.max_todo_count(all_packages, show_edge)
|
117
|
+
todo_counts = {}
|
118
118
|
all_packages.each do |package|
|
119
|
-
|
120
|
-
|
121
|
-
todo_types =
|
122
|
-
todo_types.keys.each do |
|
123
|
-
if show_edge.call(package.name,
|
124
|
-
key = "#{package.name}->#{
|
125
|
-
|
126
|
-
#
|
119
|
+
todos_by_package = package.violations.group_by(&:to_package_name)
|
120
|
+
todos_by_package.keys.each do |todos_to_package|
|
121
|
+
todo_types = todos_by_package[todos_to_package].group_by(&:type)
|
122
|
+
todo_types.keys.each do |todo_type|
|
123
|
+
if show_edge.call(package.name, todos_to_package)
|
124
|
+
key = "#{package.name}->#{todos_to_package}:#{todo_type}"
|
125
|
+
todo_counts[key] = todo_types[todo_type].count
|
126
|
+
# todo_counts[key] += 1
|
127
127
|
end
|
128
128
|
end
|
129
129
|
end
|
130
130
|
end
|
131
|
-
|
131
|
+
todo_counts.values.max
|
132
132
|
end
|
133
133
|
|
134
134
|
def self.filtered(packages, filter_package, filter_folder, exclude_packs)
|
@@ -159,13 +159,12 @@ module VisualizePacks
|
|
159
159
|
def self.all_nested_packages(all_package_names)
|
160
160
|
all_package_names.reject { |p| p == '.' }.inject({}) do |result, package|
|
161
161
|
package_map_tally = all_package_names.map { |other_package| Pathname.new(package).parent.to_s.include?(other_package) }
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
end
|
162
|
+
|
163
|
+
acc = []
|
164
|
+
all_package_names.each_with_index { |pack, idx| acc << pack if package_map_tally[idx] }
|
165
|
+
acc.sort_by(&:length)
|
166
|
+
result[package] = acc.first unless acc.empty?
|
167
|
+
|
169
168
|
result
|
170
169
|
end
|
171
170
|
end
|
@@ -201,7 +200,7 @@ module VisualizePacks
|
|
201
200
|
nested_packages[d] || d
|
202
201
|
end.uniq.reject { |p| p == package.name }
|
203
202
|
|
204
|
-
|
203
|
+
morphed_todos = package.violations.map do |v|
|
205
204
|
ParsePackwerk::Violation.new(
|
206
205
|
type: v.type,
|
207
206
|
to_package_name: nested_packages[v.to_package_name] || v.to_package_name,
|
@@ -219,10 +218,10 @@ module VisualizePacks
|
|
219
218
|
metadata: package.metadata,
|
220
219
|
dependencies: morphed_dependencies,
|
221
220
|
config: package.config,
|
222
|
-
violations:
|
221
|
+
violations: morphed_todos
|
223
222
|
)
|
224
223
|
# add dependencies TO nested packages to top-level package
|
225
|
-
# add
|
224
|
+
# add todos TO nested packages to top-level package
|
226
225
|
end
|
227
226
|
end
|
228
227
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: visualize_packs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gusto Engineers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-08-
|
11
|
+
date: 2023-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|