visualize_packs 0.5.14 → 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 -27
- data/lib/graph.dot.erb +1 -4
- data/lib/{options.rb → visualize_packs/options.rb} +13 -4
- data/lib/visualize_packs.rb +28 -41
- metadata +3 -3
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
@@ -6,43 +6,30 @@ require "optparse"
|
|
6
6
|
require "ostruct"
|
7
7
|
|
8
8
|
require_relative '../lib/visualize_packs'
|
9
|
-
require_relative '../lib/options'
|
10
9
|
|
11
10
|
options = Options.new
|
12
11
|
|
13
|
-
supported_todo_types = %w[
|
14
|
-
privacy
|
15
|
-
architecture
|
16
|
-
visibility
|
17
|
-
dependency
|
18
|
-
].sort.freeze
|
19
|
-
|
20
|
-
def validated_list(o, valid_arguments)
|
21
|
-
list = o.to_s.split(",").uniq
|
22
|
-
raise OptionParser::InvalidArgument, o unless (list - valid_arguments).empty?
|
23
|
-
list
|
24
|
-
end
|
25
|
-
|
26
12
|
OptionParser.new do |opt|
|
27
13
|
opt.on('--no-legend', "Don't show legend") { |o| options.show_legend = false }
|
14
|
+
|
28
15
|
opt.on('--no-layers', "Don't show architectural layers") { |o| options.show_layers = false }
|
29
|
-
|
30
|
-
opt.on('--no-todos', "Don't show package todos") { |o| options.show_todos = false }
|
31
|
-
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) }
|
32
|
-
opt.on('--no-privacy', "Don't show privacy enforcement") { |o| options.show_privacy = false }
|
16
|
+
|
33
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 }
|
34
20
|
|
35
|
-
opt.on('--
|
36
|
-
opt.on(
|
37
|
-
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 }
|
38
24
|
|
39
|
-
opt.on('--
|
40
|
-
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 }
|
41
27
|
|
42
|
-
opt.on('--
|
43
|
-
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(",") }
|
44
31
|
|
45
|
-
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 }
|
46
33
|
|
47
34
|
opt.on_tail("-h", "--help", "Show this message") do
|
48
35
|
puts opt
|
@@ -53,5 +40,5 @@ end.parse!
|
|
53
40
|
puts VisualizePacks.package_graph!(
|
54
41
|
options,
|
55
42
|
ParsePackwerk::Configuration.fetch.raw,
|
56
|
-
Packs.all.map {
|
43
|
+
Packs.all.map { ParsePackwerk.find(_1.name) }
|
57
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
@@ -6,6 +6,8 @@ require 'packs-specification'
|
|
6
6
|
require 'parse_packwerk'
|
7
7
|
require 'digest/md5'
|
8
8
|
|
9
|
+
require 'visualize_packs/options'
|
10
|
+
|
9
11
|
module VisualizePacks
|
10
12
|
extend T::Sig
|
11
13
|
|
@@ -55,20 +57,19 @@ module VisualizePacks
|
|
55
57
|
sig { params(options: Options, max_todo_count: T.nilable(Integer)).returns(String) }
|
56
58
|
def self.diagram_title(options, max_todo_count)
|
57
59
|
app_name = File.basename(Dir.pwd)
|
58
|
-
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"
|
59
|
-
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"
|
60
62
|
skipped_info =
|
61
63
|
[
|
62
64
|
options.show_legend ? nil : "hiding legend",
|
63
65
|
options.show_layers ? nil : "hiding layers",
|
64
66
|
options.show_dependencies ? nil : "hiding dependencies",
|
65
67
|
options.show_todos ? nil : "hiding todos",
|
66
|
-
options.only_todo_types.
|
68
|
+
EdgeTodoTypes.values.size == options.only_todo_types.size ? nil : "only #{limited_sentence(options.only_todo_types.map &:serialize)} todos",
|
67
69
|
options.show_privacy ? nil : "hiding privacy",
|
68
70
|
options.show_teams ? nil : "hiding teams",
|
69
71
|
options.roll_nested_into_parent_packs ? "hiding nested packs" : nil,
|
70
72
|
options.show_nested_relationships ? nil : "hiding nested relationships",
|
71
|
-
options.include_packs ? "including only: #{limited_sentence(options.include_packs)}" : nil,
|
72
73
|
options.exclude_packs.empty? ? nil : "excluding pack#{options.exclude_packs.size > 1 ? 's' : ''}: #{limited_sentence(options.exclude_packs)}",
|
73
74
|
].compact.join(', ').strip
|
74
75
|
main_title = "#{app_name}: #{focus_info}#{skipped_info != '' ? ' - ' + skipped_info : ''}"
|
@@ -93,25 +94,19 @@ module VisualizePacks
|
|
93
94
|
sig { params(options: Options, all_package_names: T::Array[String]).returns(T.proc.params(arg0: String, arg1: String).returns(T::Boolean)) }
|
94
95
|
def self.show_edge_builder(options, all_package_names)
|
95
96
|
return lambda do |start_node, end_node|
|
97
|
+
all_package_names.include?(start_node) &&
|
98
|
+
all_package_names.include?(end_node) &&
|
96
99
|
(
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
when FocusPackEdgeDirection::InOut then
|
108
|
-
match_packs?(start_node, options.focus_pack) || match_packs?(end_node, options.focus_pack)
|
109
|
-
when FocusPackEdgeDirection::In then
|
110
|
-
match_packs?(end_node, options.focus_pack)
|
111
|
-
when FocusPackEdgeDirection::Out then
|
112
|
-
match_packs?(start_node, options.focus_pack)
|
113
|
-
end
|
114
|
-
)
|
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
|
115
110
|
)
|
116
111
|
end
|
117
112
|
end
|
@@ -138,7 +133,7 @@ module VisualizePacks
|
|
138
133
|
todos_by_package&.keys&.each do |todos_to_package|
|
139
134
|
todo_types = todos_by_package&& todos_by_package[todos_to_package]&.group_by(&:type)
|
140
135
|
todo_types&.keys&.each do |todo_type|
|
141
|
-
if options.only_todo_types.
|
136
|
+
if options.only_todo_types.include?(EdgeTodoTypes.deserialize(todo_type))
|
142
137
|
if show_edge.call(package.name, todos_to_package)
|
143
138
|
key = "#{package.name}->#{todos_to_package}:#{todo_type}"
|
144
139
|
todo_counts[key] = todo_types && todo_types[todo_type]&.count
|
@@ -167,18 +162,18 @@ module VisualizePacks
|
|
167
162
|
count_delta = todo_count - min_count
|
168
163
|
|
169
164
|
width_delta = count_delta / todo_range.to_f * width_range
|
165
|
+
width_delta = 0 if width_delta.nan?
|
166
|
+
|
170
167
|
edge_width = min_width + width_delta
|
171
168
|
edge_width.round(2)
|
172
|
-
|
169
|
+
end
|
173
170
|
|
174
|
-
|
175
|
-
|
171
|
+
sig { params(packages: T::Array[ParsePackwerk::Package], options: Options).returns(T::Array[ParsePackwerk::Package]) }
|
172
|
+
def self.filtered(packages, options)
|
176
173
|
focus_pack = options.focus_pack
|
177
|
-
focus_folder = options.focus_folder
|
178
|
-
include_packs = options.include_packs
|
179
174
|
exclude_packs = options.exclude_packs
|
180
175
|
|
181
|
-
return packages unless focus_pack.any? ||
|
176
|
+
return packages unless focus_pack.any? || exclude_packs.any?
|
182
177
|
|
183
178
|
nested_packages = all_nested_packages(packages.map { |p| p.name })
|
184
179
|
|
@@ -196,10 +191,10 @@ module VisualizePacks
|
|
196
191
|
if options.show_dependencies
|
197
192
|
result += packages.select { |p| p.dependencies.any? { |d| match_packs?(d, focus_pack) }}.map { |pack| pack.name }
|
198
193
|
end
|
199
|
-
if options.show_todos && [
|
194
|
+
if options.show_todos && [FocusPackEdgeDirection::All, FocusPackEdgeDirection::In, FocusPackEdgeDirection::InOut].include?(options.show_only_edges_to_focus_pack)
|
200
195
|
result += packages.select do
|
201
196
|
|p| (p.violations || []).inject([]) do |res, todo|
|
202
|
-
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))
|
203
198
|
res
|
204
199
|
end.any? { |v| match_packs?(v, focus_pack) }
|
205
200
|
end.map { |pack| pack.name }
|
@@ -208,9 +203,9 @@ module VisualizePacks
|
|
208
203
|
if options.show_dependencies
|
209
204
|
result += packages_by_name[p].dependencies
|
210
205
|
end
|
211
|
-
if options.show_todos && [
|
206
|
+
if options.show_todos && [FocusPackEdgeDirection::All, FocusPackEdgeDirection::Out, FocusPackEdgeDirection::InOut].include?(options.show_only_edges_to_focus_pack)
|
212
207
|
result += (packages_by_name[p].violations || []).inject([]) do |res, todo|
|
213
|
-
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))
|
214
209
|
res
|
215
210
|
end
|
216
211
|
end
|
@@ -223,14 +218,6 @@ module VisualizePacks
|
|
223
218
|
result = (result + parent_packs).uniq.compact
|
224
219
|
end
|
225
220
|
|
226
|
-
if focus_folder
|
227
|
-
result = result.select { |p| p.include? focus_folder }
|
228
|
-
end
|
229
|
-
|
230
|
-
if include_packs
|
231
|
-
result = result.select { |p| match_packs?(p, include_packs) }
|
232
|
-
end
|
233
|
-
|
234
221
|
if exclude_packs.any?
|
235
222
|
result = result.reject { |p| match_packs?(p, exclude_packs) }
|
236
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
|
@@ -120,8 +120,8 @@ files:
|
|
120
120
|
- bin/tapioca
|
121
121
|
- bin/visualize_packs
|
122
122
|
- lib/graph.dot.erb
|
123
|
-
- lib/options.rb
|
124
123
|
- lib/visualize_packs.rb
|
124
|
+
- lib/visualize_packs/options.rb
|
125
125
|
homepage: https://github.com/rubyatscale/visualize_packs
|
126
126
|
licenses:
|
127
127
|
- MIT
|