visualize_packs 0.5.20 → 0.5.21

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b8efefa896a6d002c7333dad53f2a8fa0be10d8c0004895682239c7a7f6a1105
4
- data.tar.gz: 0046a3a518c25de488b4b2e0d89c04ced6e45c1ff5d90e9e85d71d46b5256e89
3
+ metadata.gz: 72b6b3b6121cd9e3a2f30a4b927882be78fab2bbff55d2168100552cdf5b8276
4
+ data.tar.gz: 2281e4d89e00c73e18ed025b8b636d2cbafef28addc4955ff4f82ea22ddc442d
5
5
  SHA512:
6
- metadata.gz: 5282d8a1af4103a3d6c38675c378adee512029eb4320a29874b91463c2fc4aa7380a76165306f8dc2d8163b67e60875b2496aeacca209b40ebdb09217744888c
7
- data.tar.gz: 99f84713ec95080f82668184bd69ce4e67dc30fbc739803f67efe8ebbe51728dbd4717d22eec946a2e24ce1128cd646d3cca47413a09a481718b76c029c47ae7
6
+ metadata.gz: 3b9affb4f63a85e56125c00e412373d60c705f793c8da118d0e11899b1dcff0e143cade00d4d2562d23d075e3f2a58d9be594cc751e6ee67038a5d591e6c1c27
7
+ data.tar.gz: e99623cfaaa59016939a675a500f12357da8401d2fb3ac6e87c37b1a1f861c5976665e59e830f2fc44fe38c33e7cc6926721e264a9516e2dd57df20e1bff95dc
data/bin/visualize_packs CHANGED
@@ -17,11 +17,12 @@ OptionParser.new do |opt|
17
17
  opt.on('--no-layers', "Don't show architectural layers") { |o| options.show_layers = false }
18
18
  opt.on('--no-visibility-arrows', "Don't show visibility arrows") { |o| options.show_visibility = false }
19
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 }
20
+ opt.on('--no-todo-edges', "Don't show todos for package relationships") { |o| options.show_relationship_todos = false }
21
+ 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) } }
22
+ 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 }
23
23
 
24
24
  opt.on('--no-teams', "Don't show team colors") { |o| options.show_teams = false }
25
+ opt.on('--no-node-todos', "Don't show package-based todos") { |o| options.show_node_todos = false }
25
26
 
26
27
  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
28
  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) }
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
- </td></tr></table>
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.show_todos -%>
89
+ <%- if options.show_relationship_todos -%>
83
90
  <%- all_packages.each do |package| -%>
84
- <%- filtered_todos = package.violations.select { options.only_todo_types.include?(EdgeTodoTypes.deserialize(_1.type)) } -%>
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.use_todos_for_layout -%>
98
+ <%- if !options.use_relationship_todos_for_layout -%>
92
99
  constraint=false
93
100
  <%- end -%>
94
101
  # headlabel="<%= todo_type -%>"
@@ -143,23 +150,23 @@ digraph package_diagram {
143
150
  N [ fontsize=12 shape=box label="package"]
144
151
  M -> N [label="visibile to" <%= VisualizePacks::ArrowHead::ConfiguredVisibileTo.serialize %>]
145
152
  <%- end -%>
146
- <%- if options.show_todos -%>
147
- <%- if options.only_todo_types.include?(EdgeTodoTypes::Privacy) -%>
153
+ <%- if options.show_relationship_todos -%>
154
+ <%- if options.relationship_todo_types.include?(EdgeTodoTypes::Privacy) -%>
148
155
  C [ fontsize=12 shape=box label="package"]
149
156
  D [ fontsize=12 shape=box label="package"]
150
157
  C -> D [label="privacy todo" <%= VisualizePacks::ArrowHead::PrivacyTodo.serialize %>]
151
158
  <%- end -%>
152
- <%- if options.only_todo_types.include?(EdgeTodoTypes::Architecture) -%>
159
+ <%- if options.relationship_todo_types.include?(EdgeTodoTypes::Architecture) -%>
153
160
  E [ fontsize=12 shape=box label="package"]
154
161
  F [ fontsize=12 shape=box label="package"]
155
162
  E -> F [label="architecture todo" <%= VisualizePacks::ArrowHead::ArchitectureTodo.serialize %>]
156
163
  <%- end -%>
157
- <%- if options.only_todo_types.include?(EdgeTodoTypes::Visibility) -%>
164
+ <%- if options.relationship_todo_types.include?(EdgeTodoTypes::Visibility) -%>
158
165
  G [ fontsize=12 shape=box label="package"]
159
166
  H [ fontsize=12 shape=box label="package"]
160
167
  G -> H [label="visibility todo" <%= VisualizePacks::ArrowHead::VisibilityTodo.serialize %>]
161
168
  <%- end -%>
162
- <%- if options.only_todo_types.include?(EdgeTodoTypes::Dependency) -%>
169
+ <%- if options.relationship_todo_types.include?(EdgeTodoTypes::Dependency) -%>
163
170
  I [ fontsize=12 shape=box label="package"]
164
171
  J [ fontsize=12 shape=box label="package"]
165
172
  I -> J [label="dependency todo" <%= VisualizePacks::ArrowHead::DependencyTodo.serialize %>]
@@ -30,11 +30,12 @@ class Options < T::Struct
30
30
  prop :show_layers, T::Boolean, default: true
31
31
  prop :show_visibility, T::Boolean, default: true
32
32
 
33
- prop :show_todos, T::Boolean, default: true
34
- prop :only_todo_types, T::Array[EdgeTodoTypes], default: EdgeTodoTypes.values
35
- prop :use_todos_for_layout, T::Boolean, default: false
33
+ prop :show_relationship_todos, T::Boolean, default: true
34
+ prop :relationship_todo_types, T::Array[EdgeTodoTypes], default: EdgeTodoTypes.values
35
+ prop :use_relationship_todos_for_layout, T::Boolean, default: false
36
36
 
37
37
  prop :show_teams, T::Boolean, default: true
38
+ prop :show_node_todos, T::Boolean, default: true
38
39
 
39
40
  prop :focus_pack, T.nilable(T::Array[String]), default: nil
40
41
  prop :show_only_edges_to_focus_pack, FocusPackEdgeDirection, default: FocusPackEdgeDirection::All
@@ -31,6 +31,7 @@ module VisualizePacks
31
31
 
32
32
  show_edge = show_edge_builder(options, all_package_names)
33
33
  node_color = node_color_builder()
34
+ node_protection = package_based_todos_text_maker()
34
35
  max_todo_count = max_todo_count(all_packages, show_edge, options)
35
36
 
36
37
  title = diagram_title(options, max_todo_count)
@@ -80,22 +81,23 @@ module VisualizePacks
80
81
  options.show_legend ? nil : "legend",
81
82
  options.show_layers ? nil : "layers",
82
83
  options.show_dependencies ? nil : "dependencies",
83
- options.show_todos ? nil : "todos",
84
+ options.show_relationship_todos ? nil : "edge todos",
84
85
  options.show_privacy ? nil : "privacy",
85
86
  options.show_teams ? nil : "teams",
87
+ options.show_node_todos ? nil : "node todos",
86
88
  options.show_visibility ? nil : "visibility",
87
89
  options.roll_nested_into_parent_packs ? "nested packs" : nil,
88
90
  options.show_nested_relationships ? nil : "nested relationships",
89
91
  ].compact.join(', ').strip
90
92
  hidden_aspects_title = hidden_aspects != '' ? "Hiding #{hidden_aspects}" : nil
91
93
 
92
- todo_types = EdgeTodoTypes.values.size == options.only_todo_types.size ? nil : "Only #{options.only_todo_types.map &:serialize} todos",
94
+ todo_types = EdgeTodoTypes.values.size == options.relationship_todo_types.size ? nil : "Only #{options.relationship_todo_types.map &:serialize} todos",
93
95
 
94
96
  exclusions = options.exclude_packs.empty? ? nil : "Excluding pack#{options.exclude_packs.size > 1 ? 's' : ''}: #{limited_sentence(options.exclude_packs)}",
95
97
 
96
98
  main_title = [focus_info, hidden_aspects_title, todo_types, exclusions].compact.join('. ')
97
99
 
98
- if options.show_todos && max_todo_count
100
+ if options.show_relationship_todos && max_todo_count
99
101
  sub_title = "<br/><font point-size='12'>Widest todo edge is #{max_todo_count} todo#{max_todo_count > 1 ? 's' : ''}</font>"
100
102
  end
101
103
  "<<b>#{main_title}</b>#{sub_title}>"
@@ -150,13 +152,13 @@ module VisualizePacks
150
152
  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
153
  def self.max_todo_count(all_packages, show_edge, options)
152
154
  todo_counts = {}
153
- if options.show_todos
155
+ if options.show_relationship_todos
154
156
  all_packages.each do |package|
155
157
  todos_by_package = package.violations&.group_by(&:to_package_name)
156
158
  todos_by_package&.keys&.each do |todos_to_package|
157
159
  todo_types = todos_by_package&& todos_by_package[todos_to_package]&.group_by(&:type)
158
160
  todo_types&.keys&.each do |todo_type|
159
- if options.only_todo_types.include?(EdgeTodoTypes.deserialize(todo_type))
161
+ if options.relationship_todo_types.include?(EdgeTodoTypes.deserialize(todo_type))
160
162
  if show_edge.call(package.name, todos_to_package)
161
163
  key = "#{package.name}->#{todos_to_package}:#{todo_type}"
162
164
  todo_counts[key] = todo_types && todo_types[todo_type]&.count
@@ -215,8 +217,8 @@ module VisualizePacks
215
217
 
216
218
  dependents = options.show_dependencies ? dependents_on(packages, focus_pack_name) : []
217
219
  dependencies = options.show_dependencies ? dependencies_of(packages, focus_pack_name) : []
218
- todos_out = options.show_todos ? todos_out(packages, focus_pack_name, options) : []
219
- todos_in = options.show_todos ? todos_in(packages, focus_pack_name, options) : []
220
+ todos_out = options.show_relationship_todos ? todos_out(packages, focus_pack_name, options) : []
221
+ todos_in = options.show_relationship_todos ? todos_in(packages, focus_pack_name, options) : []
220
222
 
221
223
  case options.show_only_edges_to_focus_pack
222
224
  when FocusPackEdgeDirection::All, FocusPackEdgeDirection::InOut then
@@ -342,7 +344,7 @@ module VisualizePacks
342
344
  def self.todos_in(all_packages, focus_packs_names, options)
343
345
  all_packages.select do |p|
344
346
  (p.violations || []).inject([]) do |res, todo|
345
- res << todo.to_package_name if options.only_todo_types.include?(EdgeTodoTypes.deserialize(todo.type))
347
+ res << todo.to_package_name if options.relationship_todo_types.include?(EdgeTodoTypes.deserialize(todo.type))
346
348
  res
347
349
  end.any? { |v| focus_packs_names.include?(v) }
348
350
  end.map { |pack| pack.name }
@@ -352,9 +354,43 @@ module VisualizePacks
352
354
  def self.todos_out(all_packages, focus_packs_names, options)
353
355
  all_packages.inject([]) do |result, p|
354
356
  focus_packs_names.include?(p.name) && (p.violations || []).each do |todo|
355
- result << todo.to_package_name if options.only_todo_types.include?(EdgeTodoTypes.deserialize(todo.type))
357
+ result << todo.to_package_name if options.relationship_todo_types.include?(EdgeTodoTypes.deserialize(todo.type))
356
358
  end
357
359
  result
358
360
  end
359
361
  end
362
+
363
+ 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)) }
364
+ def self.package_based_todos_for(protection, package_name, rubocop_config, rubocop_todo)
365
+ rubocop_config = {} if rubocop_config.is_a?(TrueClass) || rubocop_config.is_a?(FalseClass) || rubocop_config.is_a?(NilClass)
366
+ rubocop_todo = {} if rubocop_todo.is_a?(TrueClass) || rubocop_todo.is_a?(FalseClass) || rubocop_todo.is_a?(NilClass)
367
+
368
+ raise ArgumentError unless ['Packs/ClassMethodsAsPublicApis', 'Packs/DocumentedPublicApis', 'Packs/RootNamespaceIsPackName', 'Packs/TypedPublicApis'].include?(protection)
369
+ return nil unless (rubocop_config.dig(protection)&.dig('Enabled'))
370
+
371
+ (rubocop_todo.dig(protection)&.dig('Exclude') || []).inject(0) do |result, todo|
372
+ result += 1 if todo.start_with?("#{package_name}/")
373
+ result
374
+ end
375
+ end
376
+
377
+ sig { returns(T.untyped) }
378
+ def self.package_based_todos_text_maker
379
+ ->(package_name) {
380
+ [
381
+ 'Packs/ClassMethodsAsPublicApis',
382
+ 'Packs/DocumentedPublicApis',
383
+ 'Packs/RootNamespaceIsPackName',
384
+ 'Packs/TypedPublicApis'
385
+ ].map do |protection|
386
+ rubocop_config = File.exist?("#{package_name}/.rubocop.yml") ? YAML.load_file("#{package_name}/.rubocop.yml") : {}
387
+ rubocop_todo = File.exist?(".rubocop_todo.yml") ? YAML.load_file(".rubocop_todo.yml") : {}
388
+
389
+ todo_value = package_based_todos_for(protection, package_name, rubocop_config, rubocop_todo)
390
+ abbreviation = T.must(protection.split('/')[1]).chars[0]
391
+
392
+ "#{abbreviation}: #{todo_value}" if todo_value
393
+ end.compact.join(", ")
394
+ }
395
+ end
360
396
  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.20
4
+ version: 0.5.21
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-17 00:00:00.000000000 Z
11
+ date: 2023-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler