visualize_packs 0.5.3 → 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
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