visualize_packs 0.5.20 → 0.5.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|