visualize_packs 0.5.3 → 0.5.5

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: 2a14f60b122081e11447ca15b17f75693f2797ed56f26ea7918f5eea7422ea8b
4
- data.tar.gz: b09d7f7b1683ddb4422ae839f6a6d5d8af159e16a34cd7798ad9155dd713e46f
3
+ metadata.gz: b4ade528fc794c71afb2470d457f31d72b2456b85a484f2b328ca1c73e7fc2cf
4
+ data.tar.gz: 239feaba7ced4136ac77625e6ed1632a031492e86ca6d1c0d025976b23e31300
5
5
  SHA512:
6
- metadata.gz: 07c3ae10e94edd11c917293de275b2c0fef42e2acc74139817adee33691f3d37dbfb1df6d643c4d2a302dc2eea28948b9316ba0cf5610fdf2f63a9c53293a70a
7
- data.tar.gz: 1cd63442e74739d13a30638557f891c72809b121e938526542cc201bd621dc596b3352d16697d876f465992f874230fe65a70b0cf9f966c3c5b56d318711cc5e
6
+ metadata.gz: 18a67a3b983c99f4d273a8e32e390a63bb0fa0398c7da51d4552fee73eedda0e77debfe45a3e196cae5b8d0e370124f7eeb82d202f4daba7b68bb90fb5b15708
7
+ data.tar.gz: 60e06eaacba3c796ee9045223d47203f63b19e83664c58b9db69696c591f68169f217bc8172287fcb9cc61befaa2008c4a337e486febd0477b6a0b8d14100520
data/bin/visualize_packs CHANGED
@@ -10,20 +10,37 @@ require_relative '../lib/options'
10
10
 
11
11
  options = Options.new
12
12
 
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
+
13
26
  OptionParser.new do |opt|
27
+ opt.on('--no-legend', "Don't show legend") { |o| options.show_legend = false }
14
28
  opt.on('--no-layers', "Don't show architectural layers") { |o| options.show_layers = false }
15
29
  opt.on('--no-dependencies', "Don't show accepted dependencies") { |o| options.show_dependencies = false }
16
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) }
17
32
  opt.on('--no-privacy', "Don't show privacy enforcement") { |o| options.show_privacy = false }
18
33
  opt.on('--no-teams', "Don't show team colors") { |o| options.show_teams = false }
19
34
 
20
- opt.on('--focus-on=PACKAGE', "Don't show privacy enforcement") { |o| options.focus_package = o }
35
+ opt.on('--focus-on=PACKAGE', "Focus on a specific package") { |o| options.focus_package = o }
21
36
  opt.on('--only-edges-to-focus', "If focus is set, this shows only the edges to/from the focus node instead of all edges in the focussed graph. This only has effect when --focus-on is set.") { |o| options.show_only_edges_to_focus_package = true }
22
37
 
23
38
  opt.on('--roll_nested_todos_into_top_level', "Don't show nested packages (not counting root). Connect edges to top-level package instead") { |o| options.roll_nested_todos_into_top_level = true }
24
39
  opt.on('--focus_folder=FOLDER', "Draw package diagram only for packages in FOLDER") { |o| options.focus_folder = o }
25
40
  opt.on('--no_nested_relationships', "Don't draw nested package relationships") { |o| options.show_nested_relationships = false }
26
41
 
42
+ opt.on('--exclude-packs=pack1,pack2,etc', "Exclude these packs from diagram") { |o| options.exclude_packs = o.to_s.split(",") }
43
+
27
44
  opt.on('--remote-base-url=PACKAGE', "Link package nodes to an URL (affects graphviz SVG generation)") { |o| options.remote_base_url = o }
28
45
 
29
46
  opt.on_tail("-h", "--help", "Show this message") do
data/lib/graph.dot.erb CHANGED
@@ -81,10 +81,14 @@ digraph package_diagram {
81
81
  <%- end -%>
82
82
  <%- if options.show_todos -%>
83
83
  <%- all_packages.each do |package| -%>
84
- <%- violations_by_package = package.violations.group_by(&:to_package_name) -%>
84
+ <%- filtered_violations = package.violations -%>
85
+ <%- if options.only_todo_types.any? -%>
86
+ <%- filtered_violations = filtered_violations.select { options.only_todo_types.include?(_1.type) } -%>
87
+ <%- end -%>
88
+ <%- violations_by_package = filtered_violations.group_by(&:to_package_name) -%>
85
89
  <%- violations_by_package.keys.each do |violations_to_package| -%>
86
- <%- violation_types = violations_by_package[violations_to_package].group_by(&:type) -%>
87
- <%- violation_types.keys.each do |violation_type| -%>
90
+ <%- todo_types = violations_by_package[violations_to_package].group_by(&:type) -%>
91
+ <%- todo_types.keys.each do |violation_type| -%>
88
92
  <%- if show_edge.call(package.name, violations_to_package) -%>
89
93
  "<%= package.name -%>" -> "<%= violations_to_package -%>"<%= violation_type == 'privacy' ? ':private' : '' -%> [ color=darkred style=dashed
90
94
  constraint=false
@@ -100,7 +104,7 @@ digraph package_diagram {
100
104
  <%- end -%>
101
105
  <%-
102
106
  max_edge_width = 10
103
- edge_width = (violation_types[violation_type].count / max_violation_count.to_f * max_edge_width).to_i
107
+ edge_width = (todo_types[violation_type].count / max_violation_count.to_f * max_edge_width).to_i
104
108
  -%>
105
109
  penwidth=<%= edge_width -%>
106
110
  ]
@@ -118,28 +122,30 @@ digraph package_diagram {
118
122
  <%- end -%>
119
123
  <%- end -%>
120
124
  <%- end -%>
121
- subgraph cluster_legend {
122
- fontsize=16
123
- label="Edges Styles and Arrow Heads"
124
- A [ fontsize=12 shape=box label="package"]
125
- B [ fontsize=12 shape=box label="package"]
126
- C [ fontsize=12 shape=box label="package"]
127
- D [ fontsize=12 shape=box label="package"]
128
- E [ fontsize=12 shape=box label="package"]
129
- F [ fontsize=12 shape=box label="package"]
130
- G [ fontsize=12 shape=box label="package"]
131
- H [ fontsize=12 shape=box label="package"]
132
- I [ fontsize=12 shape=box label="package"]
133
- J [ fontsize=12 shape=box label="package"]
134
- K [ fontsize=12 shape=box label="package"]
135
- L [ fontsize=12 shape=box label="package"]
136
- A -> B [label="accepted dependency" color=darkgreen]
137
- C -> D [label="privac todo" color=darkred style=dashed arrowhead=crow]
138
- E -> F [label="architecture todo" color=darkred style=dashed arrowhead=invodot]
139
- G -> H [label="visibility todo" color=darkred style=dashed arrowhead=obox]
140
- I -> J [label="dependency todo" color=darkred style=dashed arrowhead=odot]
141
- K -> L [label="nested package" color=purple penwidth=3]
142
- }
125
+ <%- if options.show_legend -%>
126
+ subgraph cluster_legend {
127
+ fontsize=16
128
+ label="Edges Styles and Arrow Heads"
129
+ A [ fontsize=12 shape=box label="package"]
130
+ B [ fontsize=12 shape=box label="package"]
131
+ C [ fontsize=12 shape=box label="package"]
132
+ D [ fontsize=12 shape=box label="package"]
133
+ E [ fontsize=12 shape=box label="package"]
134
+ F [ fontsize=12 shape=box label="package"]
135
+ G [ fontsize=12 shape=box label="package"]
136
+ H [ fontsize=12 shape=box label="package"]
137
+ I [ fontsize=12 shape=box label="package"]
138
+ J [ fontsize=12 shape=box label="package"]
139
+ K [ fontsize=12 shape=box label="package"]
140
+ L [ fontsize=12 shape=box label="package"]
141
+ A -> B [label="accepted dependency" color=darkgreen]
142
+ C -> D [label="privac todo" color=darkred style=dashed arrowhead=crow]
143
+ E -> F [label="architecture todo" color=darkred style=dashed arrowhead=invodot]
144
+ G -> H [label="visibility todo" color=darkred style=dashed arrowhead=obox]
145
+ I -> J [label="dependency todo" color=darkred style=dashed arrowhead=odot]
146
+ K -> L [label="nested package" color=purple penwidth=3]
147
+ }
148
+ <%- end -%>
143
149
  <%- if options.show_teams && all_team_names != [] -%>
144
150
  subgraph cluster_teams_legend {
145
151
  fontsize=16
@@ -157,6 +163,8 @@ digraph package_diagram {
157
163
  <%- end %>
158
164
  <%- end -%>
159
165
  }
160
- J -> "<%= all_team_names.last %><%= all_team_names.last %>" [style=invis]
166
+ <%- if options.show_legend -%>
167
+ J -> "<%= all_team_names.last %><%= all_team_names.last %>" [style=invis]
168
+ <%- end -%>
161
169
  <%- end -%>
162
170
  }
data/lib/options.rb CHANGED
@@ -4,9 +4,11 @@
4
4
  class Options < T::Struct
5
5
  extend T::Sig
6
6
 
7
+ prop :show_legend, T::Boolean, default: true
7
8
  prop :show_layers, T::Boolean, default: true
8
9
  prop :show_dependencies, T::Boolean, default: true
9
10
  prop :show_todos, T::Boolean, default: true
11
+ prop :only_todo_types, T::Array[String], default: []
10
12
  prop :show_privacy, T::Boolean, default: true
11
13
  prop :show_teams, T::Boolean, default: true
12
14
 
@@ -17,5 +19,7 @@ class Options < T::Struct
17
19
  prop :focus_folder, T.nilable(String)
18
20
  prop :show_nested_relationships, T::Boolean, default: true
19
21
 
22
+ prop :exclude_packs, T::Array[String], default: []
23
+
20
24
  prop :remote_base_url, T.nilable(String)
21
25
  end
@@ -11,7 +11,7 @@ module VisualizePacks
11
11
  def self.package_graph!(options, raw_config, packages)
12
12
  raise ArgumentError, "Package #{options.focus_package} does not exist. Found packages #{packages.map(&:name).join(", ")}" if options.focus_package && !packages.map(&:name).include?(options.focus_package)
13
13
 
14
- all_packages = filtered(packages, options.focus_package, options.focus_folder).sort_by {|x| x.name }
14
+ all_packages = filtered(packages, options.focus_package, options.focus_folder, options.exclude_packs).sort_by {|x| x.name }
15
15
  all_package_names = all_packages.map &:name
16
16
 
17
17
  all_packages = remove_nested_packs(all_packages) if options.roll_nested_todos_into_top_level
@@ -58,13 +58,16 @@ module VisualizePacks
58
58
  focus_info = options.focus_package || options.focus_folder ? "Focus on #{[options.focus_package, options.focus_folder].compact.join(' and ')} (#{focus_edge_info})" : "All packs"
59
59
  skipped_info =
60
60
  [
61
+ options.show_legend ? nil : "hiding legend",
61
62
  options.show_layers ? nil : "hiding layers",
62
63
  options.show_dependencies ? nil : "hiding dependencies",
63
64
  options.show_todos ? nil : "hiding todos",
65
+ options.only_todo_types.empty? ? nil : "only #{limited_sentence(options.only_todo_types)} todos",
64
66
  options.show_privacy ? nil : "hiding privacy",
65
67
  options.show_teams ? nil : "hiding teams",
66
68
  options.roll_nested_todos_into_top_level ? "hiding nested packs" : nil,
67
69
  options.show_nested_relationships ? nil : "hiding nested relationships",
70
+ options.exclude_packs.empty? ? nil : "excluding pack#{options.exclude_packs.size > 1 ? 's' : ''}: #{limited_sentence(options.exclude_packs)}",
68
71
  ].compact.join(', ').strip
69
72
  main_title = "#{app_name}: #{focus_info}#{skipped_info != '' ? ' - ' + skipped_info : ''}"
70
73
  sub_title = ""
@@ -74,6 +77,14 @@ module VisualizePacks
74
77
  "<<b>#{main_title}</b>#{sub_title}>"
75
78
  end
76
79
 
80
+ def self.limited_sentence(list)
81
+ if list.size <= 2
82
+ list.join(" and ")
83
+ else
84
+ "#{list[0, 2].join(", ")}, and #{list.size - 2} more"
85
+ end
86
+ end
87
+
77
88
  def self.show_edge_builder(options, all_package_names)
78
89
  return lambda do |start_node, end_node|
79
90
  (
@@ -107,11 +118,11 @@ module VisualizePacks
107
118
  all_packages.each do |package|
108
119
  violations_by_package = package.violations.group_by(&:to_package_name)
109
120
  violations_by_package.keys.each do |violations_to_package|
110
- violation_types = violations_by_package[violations_to_package].group_by(&:type)
111
- violation_types.keys.each do |violation_type|
121
+ todo_types = violations_by_package[violations_to_package].group_by(&:type)
122
+ todo_types.keys.each do |violation_type|
112
123
  if show_edge.call(package.name, violations_to_package)
113
124
  key = "#{package.name}->#{violations_to_package}:#{violation_type}"
114
- violation_counts[key] = violation_types[violation_type].count
125
+ violation_counts[key] = todo_types[violation_type].count
115
126
  # violation_counts[key] += 1
116
127
  end
117
128
  end
@@ -120,8 +131,8 @@ module VisualizePacks
120
131
  violation_counts.values.max
121
132
  end
122
133
 
123
- def self.filtered(packages, filter_package, filter_folder)
124
- return packages unless filter_package || filter_folder
134
+ def self.filtered(packages, filter_package, filter_folder, exclude_packs)
135
+ return packages unless filter_package || filter_folder || exclude_packs.any?
125
136
 
126
137
  result = packages.map { |pack| pack.name }
127
138
 
@@ -138,6 +149,10 @@ module VisualizePacks
138
149
  result = result.select { |p| p.include? filter_folder }
139
150
  end
140
151
 
152
+ if exclude_packs.any?
153
+ result = result.reject { |p| exclude_packs.include? p }
154
+ end
155
+
141
156
  result.map { |pack_name| ParsePackwerk.find(pack_name) }
142
157
  end
143
158
 
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.3
4
+ version: 0.5.5
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-08-18 00:00:00.000000000 Z
11
+ date: 2023-08-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler