visualize_packs 0.5.20 → 0.5.22
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/visualize_packs +1 -45
- data/lib/graph.dot.erb +30 -16
- data/lib/visualize_packs/options.rb +5 -3
- data/lib/visualize_packs/options_parser.rb +55 -0
- data/lib/visualize_packs.rb +70 -16
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4bf6ada5b7fe3dbfc435be39f2eb2e7d7053f8326c80fe56caa321b114aa2c06
|
4
|
+
data.tar.gz: ec7ec07be1e5c7b4b747c92a2f16067c74a163df8ccf2ac9f8d5656247268f45
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '02108ec30cd93949952ef1fbcae5c0105158f466f01eeaa94b3490d3b0663509ebe1deac01c270a5cacbe448e263b13c942cdaa7a364df78d813bfe29f1df843'
|
7
|
+
data.tar.gz: c3c50c11a25725ce40aa028f522215c026b1a992ab18cfe5097e40c01be08b3e957e5eeeaa51a1f57e45e920b72c5d2045b3707cf8a519adf3066875e4e46a62
|
data/bin/visualize_packs
CHANGED
@@ -1,54 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require "pathname"
|
5
|
-
require "optparse"
|
6
|
-
require "ostruct"
|
7
|
-
|
8
4
|
require_relative '../lib/visualize_packs'
|
9
5
|
|
10
|
-
options = Options.new
|
11
|
-
|
12
|
-
OptionParser.new do |opt|
|
13
|
-
opt.on('--no-legend', "Don't show legend") { |o| options.show_legend = false }
|
14
|
-
|
15
|
-
opt.on('--no-dependency-arrows', "Don't show accepted dependency arrows") { |o| options.show_dependencies = false }
|
16
|
-
opt.on('--no-privacy-boxes', "Don't show privacy enforcement box on a pack") { |o| options.show_privacy = false }
|
17
|
-
opt.on('--no-layers', "Don't show architectural layers") { |o| options.show_layers = false }
|
18
|
-
opt.on('--no-visibility-arrows', "Don't show visibility arrows") { |o| options.show_visibility = false }
|
19
|
-
|
20
|
-
opt.on('--no-todo-arrows', "Don't show pack todos") { |o| options.show_todos = false }
|
21
|
-
opt.on("--only-todo-types=STRING", "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) } }
|
22
|
-
opt.on("--use-todos-for-layout", "Show only the selected types of todos. Comma-separated list of #{EdgeTodoTypes.values.map &:serialize}") { |o| options.use_todos_for_layout = true }
|
23
|
-
|
24
|
-
opt.on('--no-teams', "Don't show team colors") { |o| options.show_teams = false }
|
25
|
-
|
26
|
-
opt.on('--focus-pack=STRING', "Focus on a specific pack(s). Comma-separated list of packs. Wildcards supported: 'packs/*'") { |o| options.focus_pack = o.to_s.split(",") }
|
27
|
-
opt.on('--focus-pack-edge-mode=STRING', "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) }
|
28
|
-
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(",") }
|
29
|
-
|
30
|
-
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 }
|
31
|
-
opt.on('--no-nesting-arrows', "Don't draw relationships between parents and nested packs") { |o| options.show_nested_relationships = false }
|
32
|
-
|
33
|
-
opt.on('--remote-base-url=STRING', "Link pack packs to a URL (affects graphviz SVG generation)") { |o| options.remote_base_url = o }
|
34
|
-
|
35
|
-
opt.on('--title=STRING', "Set a custom diagram title") { |o| options.title = o }
|
36
|
-
|
37
|
-
opt.on('-V', '--version', "Show version") do
|
38
|
-
spec_path = File.expand_path("../visualize_packs.gemspec", __dir__)
|
39
|
-
spec = Gem::Specification::load(spec_path)
|
40
|
-
puts "Version #{spec.version}"
|
41
|
-
exit
|
42
|
-
end
|
43
|
-
|
44
|
-
opt.on_tail("-h", "--help", "Show this message") do
|
45
|
-
puts opt
|
46
|
-
exit
|
47
|
-
end
|
48
|
-
end.parse!
|
49
|
-
|
50
6
|
puts VisualizePacks.package_graph!(
|
51
|
-
|
7
|
+
ARGV,
|
52
8
|
ParsePackwerk::Configuration.fetch.raw,
|
53
9
|
Packs.all.map { ParsePackwerk.find(_1.name) }
|
54
10
|
)
|
data/lib/graph.dot.erb
CHANGED
@@ -46,11 +46,18 @@ digraph package_diagram {
|
|
46
46
|
<table border='0' cellborder='1' cellspacing='0' cellpadding='4'>
|
47
47
|
<tr> <td port='private'> <%= package.name -%> </td> </tr>
|
48
48
|
</table>
|
49
|
-
|
49
|
+
</td></tr>
|
50
|
+
<%- if options.show_node_todos && node_protection.(package.name) != "" -%>
|
51
|
+
<tr><td CELLPADDING='1' ALIGN='RIGHT'><%= node_protection.(package.name) %></td></tr>
|
52
|
+
<%- end -%>
|
53
|
+
</table>
|
50
54
|
>
|
51
55
|
<%- else -%><
|
52
56
|
<table border='0' cellborder='1' cellspacing='0' cellpadding='4'>
|
53
57
|
<tr> <td align='left'> <%= package.name -%> </td> </tr>
|
58
|
+
<%- if options.show_node_todos && node_protection.(package.name) != "" -%>
|
59
|
+
<tr><td CELLPADDING='1' ALIGN='RIGHT'><%= node_protection.(package.name) %></td></tr>
|
60
|
+
<%- end -%>
|
54
61
|
</table>
|
55
62
|
>
|
56
63
|
<%- end -%>
|
@@ -79,16 +86,16 @@ digraph package_diagram {
|
|
79
86
|
<%- end -%>
|
80
87
|
<%- end -%>
|
81
88
|
<%- end -%>
|
82
|
-
<%- if options.
|
89
|
+
<%- if options.show_relationship_todos -%>
|
83
90
|
<%- all_packages.each do |package| -%>
|
84
|
-
<%- filtered_todos = package.violations.select { options.
|
91
|
+
<%- filtered_todos = package.violations.select { options.relationship_todo_types.include?(EdgeTodoTypes.deserialize(_1.type)) } -%>
|
85
92
|
<%- todos_by_package = filtered_todos.group_by(&:to_package_name) -%>
|
86
93
|
<%- todos_by_package.keys.each do |todos_to_package| -%>
|
87
94
|
<%- todo_types = todos_by_package[todos_to_package].group_by(&:type) -%>
|
88
95
|
<%- todo_types.keys.each do |todo_type| -%>
|
89
96
|
<%- if show_edge.call(package.name, todos_to_package) -%>
|
90
97
|
"<%= package.name -%>" -> "<%= todos_to_package -%>"<%= todo_type == 'privacy' ? ':private' : '' -%> [
|
91
|
-
<%- if !options.
|
98
|
+
<%- if !options.use_relationship_todos_for_layout -%>
|
92
99
|
constraint=false
|
93
100
|
<%- end -%>
|
94
101
|
# headlabel="<%= todo_type -%>"
|
@@ -98,6 +105,8 @@ digraph package_diagram {
|
|
98
105
|
<%= VisualizePacks::ArrowHead::ArchitectureTodo.serialize %>
|
99
106
|
<%- elsif todo_type == 'visibility' -%>
|
100
107
|
<%= VisualizePacks::ArrowHead::VisibilityTodo.serialize %>
|
108
|
+
<%- elsif todo_type == 'folder_visibility' -%>
|
109
|
+
<%= VisualizePacks::ArrowHead::FolderVisibilityTodo.serialize %>
|
101
110
|
<%- elsif todo_type == 'dependency' -%>
|
102
111
|
<%= VisualizePacks::ArrowHead::DependencyTodo.serialize %>
|
103
112
|
<%- end -%>
|
@@ -134,35 +143,40 @@ digraph package_diagram {
|
|
134
143
|
A -> B [label="accepted dependency" <%= VisualizePacks::ArrowHead::ConfiguredDependency.serialize %>]
|
135
144
|
<%- end -%>
|
136
145
|
<%- if options.show_nested_relationships -%>
|
137
|
-
K [ fontsize=12 shape=box label="package"]
|
138
|
-
L [ fontsize=12 shape=box label="package"]
|
139
|
-
K -> L [label="nested package" <%= VisualizePacks::ArrowHead::ConfiguredNested.serialize %>]
|
140
|
-
<%- end -%>
|
141
|
-
<%- if options.show_visibility -%>
|
142
146
|
M [ fontsize=12 shape=box label="package"]
|
143
147
|
N [ fontsize=12 shape=box label="package"]
|
144
|
-
M -> N [label="
|
148
|
+
M -> N [label="nested package" <%= VisualizePacks::ArrowHead::ConfiguredNested.serialize %>]
|
145
149
|
<%- end -%>
|
146
|
-
<%- if options.
|
147
|
-
|
150
|
+
<%- if options.show_visibility -%>
|
151
|
+
O [ fontsize=12 shape=box label="package"]
|
152
|
+
P [ fontsize=12 shape=box label="package"]
|
153
|
+
O -> P [label="visibile to" <%= VisualizePacks::ArrowHead::ConfiguredVisibileTo.serialize %>]
|
154
|
+
<%- end -%>
|
155
|
+
<%- if options.show_relationship_todos -%>
|
156
|
+
<%- if options.relationship_todo_types.include?(EdgeTodoTypes::Privacy) -%>
|
148
157
|
C [ fontsize=12 shape=box label="package"]
|
149
158
|
D [ fontsize=12 shape=box label="package"]
|
150
159
|
C -> D [label="privacy todo" <%= VisualizePacks::ArrowHead::PrivacyTodo.serialize %>]
|
151
160
|
<%- end -%>
|
152
|
-
<%- if options.
|
161
|
+
<%- if options.relationship_todo_types.include?(EdgeTodoTypes::Architecture) -%>
|
153
162
|
E [ fontsize=12 shape=box label="package"]
|
154
163
|
F [ fontsize=12 shape=box label="package"]
|
155
164
|
E -> F [label="architecture todo" <%= VisualizePacks::ArrowHead::ArchitectureTodo.serialize %>]
|
156
165
|
<%- end -%>
|
157
|
-
<%- if options.
|
166
|
+
<%- if options.relationship_todo_types.include?(EdgeTodoTypes::Visibility) -%>
|
158
167
|
G [ fontsize=12 shape=box label="package"]
|
159
168
|
H [ fontsize=12 shape=box label="package"]
|
160
169
|
G -> H [label="visibility todo" <%= VisualizePacks::ArrowHead::VisibilityTodo.serialize %>]
|
161
170
|
<%- end -%>
|
162
|
-
<%- if options.
|
171
|
+
<%- if options.relationship_todo_types.include?(EdgeTodoTypes::Folder_Visibility) -%>
|
163
172
|
I [ fontsize=12 shape=box label="package"]
|
164
173
|
J [ fontsize=12 shape=box label="package"]
|
165
|
-
I -> J [label="
|
174
|
+
I -> J [label="folder visibility todo" <%= VisualizePacks::ArrowHead::FolderVisibilityTodo.serialize %>]
|
175
|
+
<%- end -%>
|
176
|
+
<%- if options.relationship_todo_types.include?(EdgeTodoTypes::Dependency) -%>
|
177
|
+
K [ fontsize=12 shape=box label="package"]
|
178
|
+
L [ fontsize=12 shape=box label="package"]
|
179
|
+
K -> L [label="dependency todo" <%= VisualizePacks::ArrowHead::DependencyTodo.serialize %>]
|
166
180
|
<%- end -%>
|
167
181
|
<%- end -%>
|
168
182
|
LEGEND_NODE_1 [ label="" peripheries=0 height=0 width=0 style=invis ]
|
@@ -7,6 +7,7 @@ class EdgeTodoTypes < T::Enum
|
|
7
7
|
Privacy = new
|
8
8
|
Architecture = new
|
9
9
|
Visibility = new
|
10
|
+
Folder_Visibility = new
|
10
11
|
end
|
11
12
|
end
|
12
13
|
|
@@ -30,11 +31,12 @@ class Options < T::Struct
|
|
30
31
|
prop :show_layers, T::Boolean, default: true
|
31
32
|
prop :show_visibility, T::Boolean, default: true
|
32
33
|
|
33
|
-
prop :
|
34
|
-
prop :
|
35
|
-
prop :
|
34
|
+
prop :show_relationship_todos, T::Boolean, default: true
|
35
|
+
prop :relationship_todo_types, T::Array[EdgeTodoTypes], default: EdgeTodoTypes.values
|
36
|
+
prop :use_relationship_todos_for_layout, T::Boolean, default: false
|
36
37
|
|
37
38
|
prop :show_teams, T::Boolean, default: true
|
39
|
+
prop :show_node_todos, T::Boolean, default: true
|
38
40
|
|
39
41
|
prop :focus_pack, T.nilable(T::Array[String]), default: nil
|
40
42
|
prop :show_only_edges_to_focus_pack, FocusPackEdgeDirection, default: FocusPackEdgeDirection::All
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#typed: strict
|
3
|
+
|
4
|
+
require "optparse"
|
5
|
+
|
6
|
+
class OptionsParser
|
7
|
+
extend T::Sig
|
8
|
+
|
9
|
+
sig { params(args: T::Array[String]).returns(Options) }
|
10
|
+
def self.parse(args)
|
11
|
+
options = Options.new
|
12
|
+
|
13
|
+
OptionParser.new do |opt|
|
14
|
+
opt.on('--no-legend', "Don't show legend") { |o| options.show_legend = false }
|
15
|
+
|
16
|
+
opt.on('--no-dependency-arrows', "Don't show accepted dependency arrows") { |o| options.show_dependencies = false }
|
17
|
+
opt.on('--no-privacy-boxes', "Don't show privacy enforcement box on a pack") { |o| options.show_privacy = false }
|
18
|
+
opt.on('--no-layers', "Don't show architectural layers") { |o| options.show_layers = false }
|
19
|
+
opt.on('--no-visibility-arrows', "Don't show visibility arrows") { |o| options.show_visibility = false }
|
20
|
+
|
21
|
+
opt.on('--no-todo-edges', "Don't show todos for package relationships") { |o| options.show_relationship_todos = false }
|
22
|
+
opt.on("--edge-todo-types=STRING", "Show only the selected types of relationship todos. Comma-separated list of #{EdgeTodoTypes.values.map &:serialize}") { |o| options.relationship_todo_types = o.to_s.split(",").uniq.map { EdgeTodoTypes.deserialize(_1) } }
|
23
|
+
opt.on("--use-edge-todos-for-layout", "Show only the selected types of relationship todos. Comma-separated list of #{EdgeTodoTypes.values.map &:serialize}") { |o| options.use_relationship_todos_for_layout = true }
|
24
|
+
|
25
|
+
opt.on('--no-teams', "Don't show team colors") { |o| options.show_teams = false }
|
26
|
+
opt.on('--no-node-todos', "Don't show package-based todos") { |o| options.show_node_todos = false }
|
27
|
+
|
28
|
+
opt.on('--focus-pack=STRING', "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=STRING', "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(",") }
|
31
|
+
|
32
|
+
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 }
|
33
|
+
opt.on('--no-nesting-arrows', "Don't draw relationships between parents and nested packs") { |o| options.show_nested_relationships = false }
|
34
|
+
|
35
|
+
opt.on('--remote-base-url=STRING', "Link pack packs to a URL (affects graphviz SVG generation)") { |o| options.remote_base_url = o }
|
36
|
+
|
37
|
+
opt.on('--title=STRING', "Set a custom diagram title") { |o| options.title = o }
|
38
|
+
|
39
|
+
opt.on('-V', '--version', "Show version") do
|
40
|
+
spec_path = File.expand_path("../visualize_packs.gemspec", __dir__)
|
41
|
+
spec = Gem::Specification::load(spec_path)
|
42
|
+
puts "Version #{spec.version}"
|
43
|
+
exit
|
44
|
+
end
|
45
|
+
|
46
|
+
opt.on_tail("-h", "--help", "Show this message") do
|
47
|
+
puts opt
|
48
|
+
exit
|
49
|
+
end
|
50
|
+
end.parse(args)
|
51
|
+
|
52
|
+
options
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
data/lib/visualize_packs.rb
CHANGED
@@ -7,6 +7,7 @@ require 'parse_packwerk'
|
|
7
7
|
require 'digest/md5'
|
8
8
|
|
9
9
|
require 'visualize_packs/options'
|
10
|
+
require 'visualize_packs/options_parser'
|
10
11
|
|
11
12
|
module VisualizePacks
|
12
13
|
extend T::Sig
|
@@ -17,23 +18,27 @@ module VisualizePacks
|
|
17
18
|
PrivacyTodo = new('color=darkred style=dashed arrowhead=crow')
|
18
19
|
ArchitectureTodo = new('color=darkred style=dashed arrowhead=obox')
|
19
20
|
VisibilityTodo = new('color=darkred style=dashed arrowhead=tee')
|
21
|
+
FolderVisibilityTodo = new('color=darkred style=dashed arrowhead=odot')
|
20
22
|
ConfiguredDependency = new('color=darkgreen')
|
21
23
|
ConfiguredVisibileTo = new('color=blue')
|
22
24
|
ConfiguredNested = new('color=purple')
|
23
25
|
end
|
24
26
|
end
|
25
27
|
|
26
|
-
sig { params(
|
27
|
-
def self.package_graph!(
|
28
|
+
sig { params(args: T::Array[String], raw_config: T::Hash[String, T.untyped], packages: T::Array[ParsePackwerk::Package]).returns(String) }
|
29
|
+
def self.package_graph!(args, raw_config, packages)
|
30
|
+
options = OptionsParser.parse(args)
|
31
|
+
|
28
32
|
all_packages = filtered(packages, options).compact.sort_by {|x| x.name }
|
29
33
|
all_packages = remove_nested_packs(all_packages, options)
|
30
34
|
all_package_names = all_packages.map &:name
|
31
35
|
|
32
36
|
show_edge = show_edge_builder(options, all_package_names)
|
33
37
|
node_color = node_color_builder()
|
38
|
+
node_protection = package_based_todos_text_maker()
|
34
39
|
max_todo_count = max_todo_count(all_packages, show_edge, options)
|
35
40
|
|
36
|
-
title = diagram_title(options, max_todo_count)
|
41
|
+
title = diagram_title(args, options, max_todo_count)
|
37
42
|
|
38
43
|
architecture_layers = (raw_config['architecture_layers'] || []) + ["NotInLayer"]
|
39
44
|
grouped_packages = architecture_layers.inject({}) do |result, key|
|
@@ -66,10 +71,24 @@ module VisualizePacks
|
|
66
71
|
package.config.dig("metadata", "owner") || package.config["owner"]
|
67
72
|
end
|
68
73
|
|
69
|
-
sig { params(options: Options, max_todo_count: T.nilable(Integer)).returns(String) }
|
70
|
-
def self.diagram_title(options, max_todo_count)
|
74
|
+
sig { params(args: T::Array[String], options: Options, max_todo_count: T.nilable(Integer)).returns(String) }
|
75
|
+
def self.diagram_title(args, options, max_todo_count)
|
71
76
|
return "<<b>#{options.title}</b>>" if options.title
|
72
77
|
|
78
|
+
sub_title1_length = 0
|
79
|
+
options_to_display = args.inject('') do |result, item|
|
80
|
+
sub_title1_length += item.length
|
81
|
+
if sub_title1_length > 90
|
82
|
+
sub_title1_length = 0
|
83
|
+
result += "<br/>#{item}"
|
84
|
+
else
|
85
|
+
result += " #{item}"
|
86
|
+
end
|
87
|
+
result
|
88
|
+
end
|
89
|
+
sub_title1 = "<br/>#{options_to_display}"
|
90
|
+
|
91
|
+
|
73
92
|
focus_info = if options.focus_pack
|
74
93
|
"Focus on #{limited_sentence(options.focus_pack)} (Edge mode: #{options.show_only_edges_to_focus_pack.serialize})"
|
75
94
|
else
|
@@ -80,25 +99,26 @@ module VisualizePacks
|
|
80
99
|
options.show_legend ? nil : "legend",
|
81
100
|
options.show_layers ? nil : "layers",
|
82
101
|
options.show_dependencies ? nil : "dependencies",
|
83
|
-
options.
|
102
|
+
options.show_relationship_todos ? nil : "edge todos",
|
84
103
|
options.show_privacy ? nil : "privacy",
|
85
104
|
options.show_teams ? nil : "teams",
|
105
|
+
options.show_node_todos ? nil : "node todos",
|
86
106
|
options.show_visibility ? nil : "visibility",
|
87
107
|
options.roll_nested_into_parent_packs ? "nested packs" : nil,
|
88
108
|
options.show_nested_relationships ? nil : "nested relationships",
|
89
109
|
].compact.join(', ').strip
|
90
110
|
hidden_aspects_title = hidden_aspects != '' ? "Hiding #{hidden_aspects}" : nil
|
91
111
|
|
92
|
-
todo_types = EdgeTodoTypes.values.size == options.
|
112
|
+
todo_types = EdgeTodoTypes.values.size == options.relationship_todo_types.size ? nil : "Only #{options.relationship_todo_types.map &:serialize} todos",
|
93
113
|
|
94
114
|
exclusions = options.exclude_packs.empty? ? nil : "Excluding pack#{options.exclude_packs.size > 1 ? 's' : ''}: #{limited_sentence(options.exclude_packs)}",
|
95
115
|
|
96
116
|
main_title = [focus_info, hidden_aspects_title, todo_types, exclusions].compact.join('. ')
|
97
117
|
|
98
|
-
if options.
|
99
|
-
|
118
|
+
if options.show_relationship_todos && max_todo_count
|
119
|
+
sub_title2 = "<br/><font point-size='12'>Widest todo edge is #{max_todo_count} todo#{max_todo_count > 1 ? 's' : ''}</font>"
|
100
120
|
end
|
101
|
-
"<<b>#{main_title}</b>#{
|
121
|
+
"<<b>#{main_title}</b>#{sub_title1}#{sub_title2}>"
|
102
122
|
end
|
103
123
|
|
104
124
|
sig { params(list: T.nilable(T::Array[String])).returns(T.nilable(String)) }
|
@@ -150,13 +170,13 @@ module VisualizePacks
|
|
150
170
|
sig { params(all_packages: T::Array[ParsePackwerk::Package], show_edge: T.proc.params(arg0: String, arg1: String).returns(T::Boolean), options: Options).returns(T.nilable(Integer)) }
|
151
171
|
def self.max_todo_count(all_packages, show_edge, options)
|
152
172
|
todo_counts = {}
|
153
|
-
if options.
|
173
|
+
if options.show_relationship_todos
|
154
174
|
all_packages.each do |package|
|
155
175
|
todos_by_package = package.violations&.group_by(&:to_package_name)
|
156
176
|
todos_by_package&.keys&.each do |todos_to_package|
|
157
177
|
todo_types = todos_by_package&& todos_by_package[todos_to_package]&.group_by(&:type)
|
158
178
|
todo_types&.keys&.each do |todo_type|
|
159
|
-
if options.
|
179
|
+
if options.relationship_todo_types.include?(EdgeTodoTypes.deserialize(todo_type))
|
160
180
|
if show_edge.call(package.name, todos_to_package)
|
161
181
|
key = "#{package.name}->#{todos_to_package}:#{todo_type}"
|
162
182
|
todo_counts[key] = todo_types && todo_types[todo_type]&.count
|
@@ -215,8 +235,8 @@ module VisualizePacks
|
|
215
235
|
|
216
236
|
dependents = options.show_dependencies ? dependents_on(packages, focus_pack_name) : []
|
217
237
|
dependencies = options.show_dependencies ? dependencies_of(packages, focus_pack_name) : []
|
218
|
-
todos_out = options.
|
219
|
-
todos_in = options.
|
238
|
+
todos_out = options.show_relationship_todos ? todos_out(packages, focus_pack_name, options) : []
|
239
|
+
todos_in = options.show_relationship_todos ? todos_in(packages, focus_pack_name, options) : []
|
220
240
|
|
221
241
|
case options.show_only_edges_to_focus_pack
|
222
242
|
when FocusPackEdgeDirection::All, FocusPackEdgeDirection::InOut then
|
@@ -342,7 +362,7 @@ module VisualizePacks
|
|
342
362
|
def self.todos_in(all_packages, focus_packs_names, options)
|
343
363
|
all_packages.select do |p|
|
344
364
|
(p.violations || []).inject([]) do |res, todo|
|
345
|
-
res << todo.to_package_name if options.
|
365
|
+
res << todo.to_package_name if options.relationship_todo_types.include?(EdgeTodoTypes.deserialize(todo.type))
|
346
366
|
res
|
347
367
|
end.any? { |v| focus_packs_names.include?(v) }
|
348
368
|
end.map { |pack| pack.name }
|
@@ -352,9 +372,43 @@ module VisualizePacks
|
|
352
372
|
def self.todos_out(all_packages, focus_packs_names, options)
|
353
373
|
all_packages.inject([]) do |result, p|
|
354
374
|
focus_packs_names.include?(p.name) && (p.violations || []).each do |todo|
|
355
|
-
result << todo.to_package_name if options.
|
375
|
+
result << todo.to_package_name if options.relationship_todo_types.include?(EdgeTodoTypes.deserialize(todo.type))
|
356
376
|
end
|
357
377
|
result
|
358
378
|
end
|
359
379
|
end
|
380
|
+
|
381
|
+
sig { params(protection: String, package_name: String, rubocop_config: T.any(NilClass, T::Boolean, T::Hash[String, T.untyped]), rubocop_todo: T.any(NilClass, T::Boolean, T::Hash[String, T.untyped])).returns(T.nilable(Integer)) }
|
382
|
+
def self.package_based_todos_for(protection, package_name, rubocop_config, rubocop_todo)
|
383
|
+
rubocop_config = {} if rubocop_config.is_a?(TrueClass) || rubocop_config.is_a?(FalseClass) || rubocop_config.is_a?(NilClass)
|
384
|
+
rubocop_todo = {} if rubocop_todo.is_a?(TrueClass) || rubocop_todo.is_a?(FalseClass) || rubocop_todo.is_a?(NilClass)
|
385
|
+
|
386
|
+
raise ArgumentError unless ['Packs/ClassMethodsAsPublicApis', 'Packs/DocumentedPublicApis', 'Packs/RootNamespaceIsPackName', 'Packs/TypedPublicApis'].include?(protection)
|
387
|
+
return nil unless (rubocop_config.dig(protection)&.dig('Enabled'))
|
388
|
+
|
389
|
+
(rubocop_todo.dig(protection)&.dig('Exclude') || []).inject(0) do |result, todo|
|
390
|
+
result += 1 if todo.start_with?("#{package_name}/")
|
391
|
+
result
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
sig { returns(T.untyped) }
|
396
|
+
def self.package_based_todos_text_maker
|
397
|
+
->(package_name) {
|
398
|
+
[
|
399
|
+
'Packs/ClassMethodsAsPublicApis',
|
400
|
+
'Packs/DocumentedPublicApis',
|
401
|
+
'Packs/RootNamespaceIsPackName',
|
402
|
+
'Packs/TypedPublicApis'
|
403
|
+
].map do |protection|
|
404
|
+
rubocop_config = File.exist?("#{package_name}/.rubocop.yml") ? YAML.load_file("#{package_name}/.rubocop.yml") : {}
|
405
|
+
rubocop_todo = File.exist?(".rubocop_todo.yml") ? YAML.load_file(".rubocop_todo.yml") : {}
|
406
|
+
|
407
|
+
todo_value = package_based_todos_for(protection, package_name, rubocop_config, rubocop_todo)
|
408
|
+
abbreviation = T.must(protection.split('/')[1]).chars[0]
|
409
|
+
|
410
|
+
"#{abbreviation}: #{todo_value}" if todo_value
|
411
|
+
end.compact.join(", ")
|
412
|
+
}
|
413
|
+
end
|
360
414
|
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.22
|
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-
|
11
|
+
date: 2023-10-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -122,6 +122,7 @@ files:
|
|
122
122
|
- lib/graph.dot.erb
|
123
123
|
- lib/visualize_packs.rb
|
124
124
|
- lib/visualize_packs/options.rb
|
125
|
+
- lib/visualize_packs/options_parser.rb
|
125
126
|
homepage: https://github.com/rubyatscale/visualize_packs
|
126
127
|
licenses:
|
127
128
|
- MIT
|