visualize_packs 0.5.15 → 0.5.16
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 +14 -26
- data/lib/graph.dot.erb +1 -4
- data/lib/visualize_packs/options.rb +13 -4
- data/lib/visualize_packs.rb +24 -41
- 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: a3844051eddac8142057acc5912277e386450da923f96714d7ab2f4b664d75ee
|
4
|
+
data.tar.gz: 646315741ca5d8706de1a8397948e231b04295b6513bd4a0cf69d943a546c41b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d8a1125327c319356a386ef1dfa5efe5fadb94a848d36e465d0a3bebd356f4597bc3db2e67ae35c2c54c7668f968e793dcb11457a1e1fd8f4b7b50bc12d39a8
|
7
|
+
data.tar.gz: 0f066a5bf9897d8a5a495ee6f9f6bcc1aacb1ea0e6c00e5422cc8470c6308c5fe9d0b665847c67b0a1d1d8b453362777917cded5395173b812e34638de7526db
|
data/README.md
CHANGED
@@ -19,7 +19,7 @@ find . -iname 'package.yml' | sed 's/\/package.yml//g' | sed 's/\.\///' | xargs
|
|
19
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
|
-
find . -iname 'package.yml' | sed 's/\/package.yml//g' | sed 's/\.\///' | xargs -I % sh -c "bundle exec visualize_packs --only=% --
|
22
|
+
find . -iname 'package.yml' | sed 's/\/package.yml//g' | sed 's/\.\///' | xargs -I % sh -c "bundle exec visualize_packs --only=% --focus-pack-edge-mode=inout > %/packs.dot && dot %/packs.dot -Tpng -o %/packs.png"
|
23
23
|
```
|
24
24
|
|
25
25
|
|
data/bin/visualize_packs
CHANGED
@@ -9,39 +9,27 @@ require_relative '../lib/visualize_packs'
|
|
9
9
|
|
10
10
|
options = Options.new
|
11
11
|
|
12
|
-
supported_todo_types = %w[
|
13
|
-
privacy
|
14
|
-
architecture
|
15
|
-
visibility
|
16
|
-
dependency
|
17
|
-
].sort.freeze
|
18
|
-
|
19
|
-
def validated_list(o, valid_arguments)
|
20
|
-
list = o.to_s.split(",").uniq
|
21
|
-
raise OptionParser::InvalidArgument, o unless (list - valid_arguments).empty?
|
22
|
-
list
|
23
|
-
end
|
24
|
-
|
25
12
|
OptionParser.new do |opt|
|
26
13
|
opt.on('--no-legend', "Don't show legend") { |o| options.show_legend = false }
|
14
|
+
|
27
15
|
opt.on('--no-layers', "Don't show architectural layers") { |o| options.show_layers = false }
|
28
|
-
|
29
|
-
opt.on('--no-todos', "Don't show package todos") { |o| options.show_todos = false }
|
30
|
-
opt.on('--only-todo-types=privacy,architecture,etc', "Show only these types of todos (supported types: #{supported_todo_types.join(', ')})") { |o| options.only_todo_types = validated_list(o, supported_todo_types) }
|
31
|
-
opt.on('--no-privacy', "Don't show privacy enforcement") { |o| options.show_privacy = false }
|
16
|
+
|
32
17
|
opt.on('--no-teams', "Don't show team colors") { |o| options.show_teams = false }
|
18
|
+
|
19
|
+
opt.on('--no-dependency-arrows', "Don't show accepted dependencies") { |o| options.show_dependencies = false }
|
33
20
|
|
34
|
-
opt.on('--
|
35
|
-
opt.on(
|
36
|
-
opt.on('--
|
21
|
+
opt.on('--no-todo-arrows', "Don't show pack todos") { |o| options.show_todos = false }
|
22
|
+
opt.on("--only-todo-types=", "Show only the selected types of todos. Comma-separated list of #{EdgeTodoTypes.values.map &:serialize}") { |o| options.only_todo_types = o.to_s.split(",").uniq.map { EdgeTodoTypes.deserialize(_1) } }
|
23
|
+
opt.on('--no-privacy-boxes', "Don't show privacy enforcement box on a pack") { |o| options.show_privacy = false }
|
37
24
|
|
38
|
-
opt.on('--
|
39
|
-
opt.on('--
|
25
|
+
opt.on('--no-nesting-arrows', "Don't draw relationships between parents and nested packs") { |o| options.show_nested_relationships = false }
|
26
|
+
opt.on('--roll-nested-into-parent-packs', "Don't show nested packs (not counting root). Connect edges to top-level pack instead") { |o| options.roll_nested_into_parent_packs = true }
|
40
27
|
|
41
|
-
opt.on('--
|
42
|
-
opt.on('--
|
28
|
+
opt.on('--focus-pack=', "Focus on a specific pack(s). Comma-separated list of packs. Wildcards supported: 'packs/*'") { |o| options.focus_pack = o.to_s.split(",") }
|
29
|
+
opt.on('--focus-pack-edge-mode=', "If focus-pack is set, this shows only between focussed packs (when set to none) or the edges into / out of / in and out of the focus packs to non-focus packs (which will be re-added to the graph). One of #{FocusPackEdgeDirection.values.map &:serialize}") { |o| options.show_only_edges_to_focus_pack = FocusPackEdgeDirection.deserialize(o) }
|
30
|
+
opt.on('--exclude-packs=', "Exclude listed packs from diagram. If used with include you will get all included that are not excluded. Wildcards support: 'packs/ignores/*'") { |o| options.exclude_packs = o.to_s.split(",") }
|
43
31
|
|
44
|
-
opt.on('--remote-base-url=
|
32
|
+
opt.on('--remote-base-url=', "Link pack packs to a URL (affects graphviz SVG generation)") { |o| options.remote_base_url = o }
|
45
33
|
|
46
34
|
opt.on_tail("-h", "--help", "Show this message") do
|
47
35
|
puts opt
|
@@ -52,5 +40,5 @@ end.parse!
|
|
52
40
|
puts VisualizePacks.package_graph!(
|
53
41
|
options,
|
54
42
|
ParsePackwerk::Configuration.fetch.raw,
|
55
|
-
Packs.all.map {
|
43
|
+
Packs.all.map { ParsePackwerk.find(_1.name) }
|
56
44
|
)
|
data/lib/graph.dot.erb
CHANGED
@@ -81,10 +81,7 @@ digraph package_diagram {
|
|
81
81
|
<%- end -%>
|
82
82
|
<%- if options.show_todos -%>
|
83
83
|
<%- all_packages.each do |package| -%>
|
84
|
-
<%- filtered_todos = package.violations -%>
|
85
|
-
<%- if options.only_todo_types.any? -%>
|
86
|
-
<%- filtered_todos = filtered_todos.select { options.only_todo_types.include?(_1.type) } -%>
|
87
|
-
<%- end -%>
|
84
|
+
<%- filtered_todos = package.violations.select { options.only_todo_types.include?(EdgeTodoTypes.deserialize(_1.type)) } -%>
|
88
85
|
<%- todos_by_package = filtered_todos.group_by(&:to_package_name) -%>
|
89
86
|
<%- todos_by_package.keys.each do |todos_to_package| -%>
|
90
87
|
<%- todo_types = todos_by_package[todos_to_package].group_by(&:type) -%>
|
@@ -1,8 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
# typed: strict
|
3
3
|
|
4
|
+
class EdgeTodoTypes < T::Enum
|
5
|
+
enums do
|
6
|
+
Dependency = new
|
7
|
+
Privacy = new
|
8
|
+
Architecture = new
|
9
|
+
Visibility = new
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
4
13
|
class FocusPackEdgeDirection < T::Enum
|
5
14
|
enums do
|
15
|
+
None = new
|
16
|
+
All = new
|
6
17
|
In = new
|
7
18
|
Out = new
|
8
19
|
InOut = new
|
@@ -16,19 +27,17 @@ class Options < T::Struct
|
|
16
27
|
prop :show_layers, T::Boolean, default: true
|
17
28
|
prop :show_dependencies, T::Boolean, default: true
|
18
29
|
prop :show_todos, T::Boolean, default: true
|
19
|
-
prop :only_todo_types, T::Array[
|
30
|
+
prop :only_todo_types, T::Array[EdgeTodoTypes], default: EdgeTodoTypes.values
|
20
31
|
prop :show_privacy, T::Boolean, default: true
|
21
32
|
prop :show_teams, T::Boolean, default: true
|
22
33
|
|
23
|
-
prop :focus_folder, T.nilable(String)
|
24
34
|
prop :focus_pack, T::Array[String], default: []
|
25
|
-
prop :show_only_edges_to_focus_pack,
|
35
|
+
prop :show_only_edges_to_focus_pack, FocusPackEdgeDirection, default: FocusPackEdgeDirection::All
|
26
36
|
|
27
37
|
prop :roll_nested_into_parent_packs, T::Boolean, default: false
|
28
38
|
prop :show_nested_relationships, T::Boolean, default: true
|
29
39
|
|
30
40
|
prop :exclude_packs, T::Array[String], default: []
|
31
|
-
prop :include_packs, T.nilable(T::Array[String]), default: nil
|
32
41
|
|
33
42
|
prop :remote_base_url, T.nilable(String)
|
34
43
|
end
|
data/lib/visualize_packs.rb
CHANGED
@@ -57,20 +57,19 @@ module VisualizePacks
|
|
57
57
|
sig { params(options: Options, max_todo_count: T.nilable(Integer)).returns(String) }
|
58
58
|
def self.diagram_title(options, max_todo_count)
|
59
59
|
app_name = File.basename(Dir.pwd)
|
60
|
-
focus_edge_info = options.focus_pack.any? && options.show_only_edges_to_focus_pack ? "showing only edges to/from focus pack" : "showing all edges between visible packs"
|
61
|
-
focus_info = options.focus_pack.any?
|
60
|
+
focus_edge_info = options.focus_pack.any? && options.show_only_edges_to_focus_pack != FocusPackEdgeDirection::All ? "showing only edges to/from focus pack" : "showing all edges between visible packs"
|
61
|
+
focus_info = options.focus_pack.any? ? "Focus on #{limited_sentence(options.focus_pack)} (#{focus_edge_info})" : "All packs"
|
62
62
|
skipped_info =
|
63
63
|
[
|
64
64
|
options.show_legend ? nil : "hiding legend",
|
65
65
|
options.show_layers ? nil : "hiding layers",
|
66
66
|
options.show_dependencies ? nil : "hiding dependencies",
|
67
67
|
options.show_todos ? nil : "hiding todos",
|
68
|
-
options.only_todo_types.
|
68
|
+
EdgeTodoTypes.values.size == options.only_todo_types.size ? nil : "only #{limited_sentence(options.only_todo_types.map &:serialize)} todos",
|
69
69
|
options.show_privacy ? nil : "hiding privacy",
|
70
70
|
options.show_teams ? nil : "hiding teams",
|
71
71
|
options.roll_nested_into_parent_packs ? "hiding nested packs" : nil,
|
72
72
|
options.show_nested_relationships ? nil : "hiding nested relationships",
|
73
|
-
options.include_packs ? "including only: #{limited_sentence(options.include_packs)}" : nil,
|
74
73
|
options.exclude_packs.empty? ? nil : "excluding pack#{options.exclude_packs.size > 1 ? 's' : ''}: #{limited_sentence(options.exclude_packs)}",
|
75
74
|
].compact.join(', ').strip
|
76
75
|
main_title = "#{app_name}: #{focus_info}#{skipped_info != '' ? ' - ' + skipped_info : ''}"
|
@@ -95,25 +94,19 @@ module VisualizePacks
|
|
95
94
|
sig { params(options: Options, all_package_names: T::Array[String]).returns(T.proc.params(arg0: String, arg1: String).returns(T::Boolean)) }
|
96
95
|
def self.show_edge_builder(options, all_package_names)
|
97
96
|
return lambda do |start_node, end_node|
|
97
|
+
all_package_names.include?(start_node) &&
|
98
|
+
all_package_names.include?(end_node) &&
|
98
99
|
(
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
when FocusPackEdgeDirection::InOut then
|
110
|
-
match_packs?(start_node, options.focus_pack) || match_packs?(end_node, options.focus_pack)
|
111
|
-
when FocusPackEdgeDirection::In then
|
112
|
-
match_packs?(end_node, options.focus_pack)
|
113
|
-
when FocusPackEdgeDirection::Out then
|
114
|
-
match_packs?(start_node, options.focus_pack)
|
115
|
-
end
|
116
|
-
)
|
100
|
+
case options.show_only_edges_to_focus_pack
|
101
|
+
when FocusPackEdgeDirection::All then
|
102
|
+
true
|
103
|
+
when FocusPackEdgeDirection::InOut then
|
104
|
+
match_packs?(start_node, options.focus_pack) || match_packs?(end_node, options.focus_pack)
|
105
|
+
when FocusPackEdgeDirection::In then
|
106
|
+
match_packs?(end_node, options.focus_pack)
|
107
|
+
when FocusPackEdgeDirection::Out then
|
108
|
+
match_packs?(start_node, options.focus_pack)
|
109
|
+
end
|
117
110
|
)
|
118
111
|
end
|
119
112
|
end
|
@@ -140,7 +133,7 @@ module VisualizePacks
|
|
140
133
|
todos_by_package&.keys&.each do |todos_to_package|
|
141
134
|
todo_types = todos_by_package&& todos_by_package[todos_to_package]&.group_by(&:type)
|
142
135
|
todo_types&.keys&.each do |todo_type|
|
143
|
-
if options.only_todo_types.
|
136
|
+
if options.only_todo_types.include?(EdgeTodoTypes.deserialize(todo_type))
|
144
137
|
if show_edge.call(package.name, todos_to_package)
|
145
138
|
key = "#{package.name}->#{todos_to_package}:#{todo_type}"
|
146
139
|
todo_counts[key] = todo_types && todo_types[todo_type]&.count
|
@@ -173,16 +166,14 @@ module VisualizePacks
|
|
173
166
|
|
174
167
|
edge_width = min_width + width_delta
|
175
168
|
edge_width.round(2)
|
176
|
-
|
169
|
+
end
|
177
170
|
|
178
|
-
|
179
|
-
|
171
|
+
sig { params(packages: T::Array[ParsePackwerk::Package], options: Options).returns(T::Array[ParsePackwerk::Package]) }
|
172
|
+
def self.filtered(packages, options)
|
180
173
|
focus_pack = options.focus_pack
|
181
|
-
focus_folder = options.focus_folder
|
182
|
-
include_packs = options.include_packs
|
183
174
|
exclude_packs = options.exclude_packs
|
184
175
|
|
185
|
-
return packages unless focus_pack.any? ||
|
176
|
+
return packages unless focus_pack.any? || exclude_packs.any?
|
186
177
|
|
187
178
|
nested_packages = all_nested_packages(packages.map { |p| p.name })
|
188
179
|
|
@@ -200,10 +191,10 @@ module VisualizePacks
|
|
200
191
|
if options.show_dependencies
|
201
192
|
result += packages.select { |p| p.dependencies.any? { |d| match_packs?(d, focus_pack) }}.map { |pack| pack.name }
|
202
193
|
end
|
203
|
-
if options.show_todos && [
|
194
|
+
if options.show_todos && [FocusPackEdgeDirection::All, FocusPackEdgeDirection::In, FocusPackEdgeDirection::InOut].include?(options.show_only_edges_to_focus_pack)
|
204
195
|
result += packages.select do
|
205
196
|
|p| (p.violations || []).inject([]) do |res, todo|
|
206
|
-
res << todo.to_package_name if options.only_todo_types.
|
197
|
+
res << todo.to_package_name if options.only_todo_types.include?(EdgeTodoTypes.deserialize(todo.type))
|
207
198
|
res
|
208
199
|
end.any? { |v| match_packs?(v, focus_pack) }
|
209
200
|
end.map { |pack| pack.name }
|
@@ -212,9 +203,9 @@ module VisualizePacks
|
|
212
203
|
if options.show_dependencies
|
213
204
|
result += packages_by_name[p].dependencies
|
214
205
|
end
|
215
|
-
if options.show_todos && [
|
206
|
+
if options.show_todos && [FocusPackEdgeDirection::All, FocusPackEdgeDirection::Out, FocusPackEdgeDirection::InOut].include?(options.show_only_edges_to_focus_pack)
|
216
207
|
result += (packages_by_name[p].violations || []).inject([]) do |res, todo|
|
217
|
-
res << todo.to_package_name if options.only_todo_types.
|
208
|
+
res << todo.to_package_name if options.only_todo_types.include?(EdgeTodoTypes.deserialize(todo.type))
|
218
209
|
res
|
219
210
|
end
|
220
211
|
end
|
@@ -227,14 +218,6 @@ module VisualizePacks
|
|
227
218
|
result = (result + parent_packs).uniq.compact
|
228
219
|
end
|
229
220
|
|
230
|
-
if focus_folder
|
231
|
-
result = result.select { |p| p.include? focus_folder }
|
232
|
-
end
|
233
|
-
|
234
|
-
if include_packs
|
235
|
-
result = result.select { |p| match_packs?(p, include_packs) }
|
236
|
-
end
|
237
|
-
|
238
221
|
if exclude_packs.any?
|
239
222
|
result = result.reject { |p| match_packs?(p, exclude_packs) }
|
240
223
|
end
|
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.16
|
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-09-
|
11
|
+
date: 2023-09-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|