visualize_packs 0.5.15 → 0.5.17

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: 2a1fb5d4a88ec1f052663cae4ae4b356fddc90ad34ffef47e241a1b35d13da66
4
- data.tar.gz: bbc12cc3b7a7fb6bbf015569f38fa7f2ba6928b0c07f6dfbe5d80551674507c8
3
+ metadata.gz: 13042fc696d4570039e5edbb4b1ba1f9ea710b865be44cbf0054739137f21913
4
+ data.tar.gz: 660624c8afc17b6dabfefc7969c91af2dacd6858346997220c0a0bfac3382288
5
5
  SHA512:
6
- metadata.gz: 3124d697f0ecedc3dfc8c0d82cf5125c9886dc7691eff89ca75ba2c61ea8af05aa6ee16efe6c4b6e38c927b762cb99d7b8ae00db1f19d55fcfd94d40ede16f8b
7
- data.tar.gz: 83a3ee2ca08dc704642a48bdf00b05e6b96f108e9c8e9034e6aa46ceb5d2a8dbda757980a65cec3cc3fa041b16fa6742a7ec3cb3034b1e18d0847388c8f1f96d
6
+ metadata.gz: 7776c8d9a0aeee1aa2bc74e1fb071f1f2e76820883e30785a879b49dc86646701b12e82d9f4cdcfec1e6585f7509ab5a2ab81eb239a12bb1bc934f153ecfce99
7
+ data.tar.gz: 4a67c4ba2efbb24f5d084d8bf19e47d56a8d08b4faf5a02238eb939987c9fdc56b0055cff10049bd7257473f4015df1d5b8f4bc27ca77c998fa3de913b376395
data/README.md CHANGED
@@ -19,7 +19,7 @@ find . -iname 'package.yml' | sed 's/\/package.yml//g' | sed 's/\.\///' | xargs
19
19
  If your app is large and has many packages and todos, the above graphs will likely be too big. Try this version to get only the edges to and from the focus package for each diagram:
20
20
 
21
21
  ```
22
- find . -iname 'package.yml' | sed 's/\/package.yml//g' | sed 's/\.\///' | xargs -I % sh -c "bundle exec visualize_packs --only=% --only-edges-to-focus > %/packs.dot && dot %/packs.dot -Tpng -o %/packs.png"
22
+ find . -iname 'package.yml' | sed 's/\/package.yml//g' | sed 's/\.\///' | xargs -I % sh -c "bundle exec visualize_packs --only=% --focus-pack-edge-mode=inout > %/packs.dot && dot %/packs.dot -Tpng -o %/packs.png"
23
23
  ```
24
24
 
25
25
 
data/bin/visualize_packs CHANGED
@@ -9,39 +9,27 @@ require_relative '../lib/visualize_packs'
9
9
 
10
10
  options = Options.new
11
11
 
12
- supported_todo_types = %w[
13
- privacy
14
- architecture
15
- visibility
16
- dependency
17
- ].sort.freeze
18
-
19
- def validated_list(o, valid_arguments)
20
- list = o.to_s.split(",").uniq
21
- raise OptionParser::InvalidArgument, o unless (list - valid_arguments).empty?
22
- list
23
- end
24
-
25
12
  OptionParser.new do |opt|
26
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 }
27
17
  opt.on('--no-layers', "Don't show architectural layers") { |o| options.show_layers = false }
28
- opt.on('--no-dependencies', "Don't show accepted dependencies") { |o| options.show_dependencies = false }
29
- opt.on('--no-todos', "Don't show package todos") { |o| options.show_todos = false }
30
- 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) }
31
- opt.on('--no-privacy', "Don't show privacy enforcement") { |o| options.show_privacy = false }
32
- opt.on('--no-teams', "Don't show team colors") { |o| options.show_teams = false }
18
+ opt.on('--no-visibility-arrows', "Don't show visibility arrows") { |o| options.show_visibility = false }
33
19
 
34
- opt.on('--focus-folder=FOLDER', "Draw package diagram only for packages in FOLDER. Matches with 'include' for partial matches") { |o| options.focus_folder = o.empty? ? nil : o }
35
- opt.on('--focus-pack=pack1,pack2', "Focus on a specific package(s). Wildcards support: 'packs/*'") { |o| options.focus_pack = o.to_s.split(",") }
36
- opt.on('--only-edges-to-focus=[in,out,inout]', "If focus-pack is set, this shows only the edges into / out of / in and out of the focus node instead of all edges in the focussed graph.") { |o| options.show_only_edges_to_focus_pack = FocusPackEdgeDirection.deserialize(o) }
20
+ opt.on('--no-todo-arrows', "Don't show pack todos") { |o| options.show_todos = false }
21
+ opt.on("--only-todo-types=", "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
+
23
+ opt.on('--no-teams', "Don't show team colors") { |o| options.show_teams = false }
37
24
 
38
- opt.on('--roll-nested-into-parent-packs', "Don't show nested packages (not counting root). Connect edges to top-level package instead") { |o| options.roll_nested_into_parent_packs = true }
39
- opt.on('--no-nested-relationships', "Don't draw relationships between parents and nested packs") { |o| options.show_nested_relationships = false }
25
+ opt.on('--focus-pack=', "Focus on a specific pack(s). Comma-separated list of packs. Wildcards supported: 'packs/*'") { |o| options.focus_pack = o.to_s.split(",") }
26
+ opt.on('--focus-pack-edge-mode=', "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) }
27
+ 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(",") }
40
28
 
41
- opt.on('--exclude-packs=pack1,pack2,etc', "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(",") }
42
- opt.on('--include-packs=pack1,pack2,etc', "Include only listed packs in diagram. If used with exclude you will get all included that are not excluded. Wildcards support: 'packs/ignores/*'") { |o| options.include_packs = o.to_s.split(",") }
29
+ 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 }
30
+ opt.on('--no-nesting-arrows', "Don't draw relationships between parents and nested packs") { |o| options.show_nested_relationships = false }
43
31
 
44
- opt.on('--remote-base-url=PACKAGE', "Link package nodes to an URL (affects graphviz SVG generation)") { |o| options.remote_base_url = o }
32
+ opt.on('--remote-base-url=', "Link pack packs to a URL (affects graphviz SVG generation)") { |o| options.remote_base_url = o }
45
33
 
46
34
  opt.on_tail("-h", "--help", "Show this message") do
47
35
  puts opt
@@ -52,5 +40,5 @@ end.parse!
52
40
  puts VisualizePacks.package_graph!(
53
41
  options,
54
42
  ParsePackwerk::Configuration.fetch.raw,
55
- Packs.all.map { |pack| ParsePackwerk.find(pack.name) }
43
+ Packs.all.map { ParsePackwerk.find(_1.name) }
56
44
  )
data/lib/graph.dot.erb CHANGED
@@ -33,7 +33,7 @@ digraph package_diagram {
33
33
  <%- end -%>
34
34
  <%- grouped_packages[layer_name].each do |package| -%>
35
35
  "<%= package.name -%>" [
36
- fontsize=<%= options.focus_pack.any? && options.focus_pack.any? {|p| File.fnmatch(p, package.name)} ? 18.0 : 12.0 -%>
36
+ fontsize=<%= options.focus_pack && options.focus_pack.any? {|p| File.fnmatch(p, package.name)} ? 18.0 : 12.0 -%>
37
37
  <%- if options.remote_base_url %>
38
38
  URL="<%= options.remote_base_url %>/<%= package.name == '.' ? '' : package.name -%>"
39
39
  <%- end %>
@@ -81,10 +81,7 @@ digraph package_diagram {
81
81
  <%- end -%>
82
82
  <%- if options.show_todos -%>
83
83
  <%- all_packages.each do |package| -%>
84
- <%- filtered_todos = package.violations -%>
85
- <%- if options.only_todo_types.any? -%>
86
- <%- filtered_todos = filtered_todos.select { options.only_todo_types.include?(_1.type) } -%>
87
- <%- end -%>
84
+ <%- filtered_todos = package.violations.select { options.only_todo_types.include?(EdgeTodoTypes.deserialize(_1.type)) } -%>
88
85
  <%- todos_by_package = filtered_todos.group_by(&:to_package_name) -%>
89
86
  <%- todos_by_package.keys.each do |todos_to_package| -%>
90
87
  <%- todo_types = todos_by_package[todos_to_package].group_by(&:type) -%>
@@ -112,20 +109,32 @@ digraph package_diagram {
112
109
  <%- end -%>
113
110
  <%- end -%>
114
111
  <%- if options.show_nested_relationships -%>
115
- <%- all_packages.each do |package| -%>
116
- <%- all_packages.each do |nested_package| -%>
117
- <%- if nested_package.name.include?("#{package.name}/") && !(nested_package.name == package.name) -%>
118
- "<%= package.name -%>" -> "<%= nested_package.name -%>" [ color=purple penwidth=3 ]
112
+ <%- all_packages.each do |package| -%>
113
+ <%- all_packages.each do |nested_package| -%>
114
+ <%- if nested_package.name.include?("#{package.name}/") && !(nested_package.name == package.name) -%>
115
+ "<%= package.name -%>" -> "<%= nested_package.name -%>" [ color=purple ]
116
+ <%- end -%>
117
+ <%- end -%>
118
+ <%- end -%>
119
+ <%- end -%>
120
+ <%- if options.show_visibility -%>
121
+ <%- all_packages.each do |package| -%>
122
+ <%- (package.config['visible_to'] || []).each do |other_package_name| -%>
123
+ "<%= package.name -%>" -> "<%= other_package_name -%>" [ color=blue constraint=false ]
119
124
  <%- end -%>
120
125
  <%- end -%>
121
126
  <%- end -%>
122
- <%- end -%>
123
127
  <%- if options.show_legend -%>
124
128
  subgraph cluster_legend {
125
129
  fontsize=16
126
130
  label="Edges Styles and Arrow Heads"
127
131
  A [ fontsize=12 shape=box label="package"]
128
132
  B [ fontsize=12 shape=box label="package"]
133
+ K [ fontsize=12 shape=box label="package"]
134
+ L [ fontsize=12 shape=box label="package"]
135
+ M [ fontsize=12 shape=box label="package"]
136
+ N [ fontsize=12 shape=box label="package"]
137
+
129
138
  C [ fontsize=12 shape=box label="package"]
130
139
  D [ fontsize=12 shape=box label="package"]
131
140
  E [ fontsize=12 shape=box label="package"]
@@ -134,14 +143,15 @@ digraph package_diagram {
134
143
  H [ fontsize=12 shape=box label="package"]
135
144
  I [ fontsize=12 shape=box label="package"]
136
145
  J [ fontsize=12 shape=box label="package"]
137
- K [ fontsize=12 shape=box label="package"]
138
- L [ fontsize=12 shape=box label="package"]
146
+
139
147
  A -> B [label="accepted dependency" color=darkgreen]
148
+ K -> L [label="nested package" color=purple]
149
+ M -> N [label="visibile to" color=darkgreen]
150
+
140
151
  C -> D [label="privacy todo" color=darkred style=dashed arrowhead=crow]
141
152
  E -> F [label="architecture todo" color=darkred style=dashed arrowhead=invodot]
142
153
  G -> H [label="visibility todo" color=darkred style=dashed arrowhead=obox]
143
154
  I -> J [label="dependency todo" color=darkred style=dashed arrowhead=odot]
144
- K -> L [label="nested package" color=purple penwidth=3]
145
155
  }
146
156
  <%- end -%>
147
157
  <%- if options.show_teams && all_team_names != [] -%>
@@ -1,11 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
  # typed: strict
3
3
 
4
+ class EdgeTodoTypes < T::Enum
5
+ enums do
6
+ Dependency = new
7
+ Privacy = new
8
+ Architecture = new
9
+ Visibility = new
10
+ end
11
+ end
12
+
4
13
  class FocusPackEdgeDirection < T::Enum
5
14
  enums do
6
- In = new
7
- Out = new
8
- InOut = new
15
+ None = new # don't include non-focus packs and thus show no edges to/from them
16
+ All = new # include non-focus packs and show all edges between all visible nodes
17
+ In = new # include non-focus packs and show edges that go towards focus packs (and show all edges between focus packs)
18
+ Out = new # include non-focus packs and show edges that go away from focus packs (and show all edges between focus packs)
19
+ InOut = new # include non-focus packs and show edges that go towards or away from focus packs (and show all edges between focus packs)
9
20
  end
10
21
  end
11
22
 
@@ -13,22 +24,23 @@ class Options < T::Struct
13
24
  extend T::Sig
14
25
 
15
26
  prop :show_legend, T::Boolean, default: true
16
- prop :show_layers, T::Boolean, default: true
27
+
17
28
  prop :show_dependencies, T::Boolean, default: true
18
- prop :show_todos, T::Boolean, default: true
19
- prop :only_todo_types, T::Array[String], default: []
20
29
  prop :show_privacy, T::Boolean, default: true
30
+ prop :show_layers, T::Boolean, default: true
31
+ prop :show_visibility, T::Boolean, default: true
32
+
33
+ prop :show_todos, T::Boolean, default: true
34
+ prop :only_todo_types, T::Array[EdgeTodoTypes], default: EdgeTodoTypes.values
35
+
21
36
  prop :show_teams, T::Boolean, default: true
22
37
 
23
- prop :focus_folder, T.nilable(String)
24
- prop :focus_pack, T::Array[String], default: []
25
- prop :show_only_edges_to_focus_pack, T.nilable(FocusPackEdgeDirection), default: nil
38
+ prop :focus_pack, T.nilable(T::Array[String]), default: nil
39
+ prop :show_only_edges_to_focus_pack, FocusPackEdgeDirection, default: FocusPackEdgeDirection::All
40
+ prop :exclude_packs, T::Array[String], default: []
26
41
 
27
42
  prop :roll_nested_into_parent_packs, T::Boolean, default: false
28
43
  prop :show_nested_relationships, T::Boolean, default: true
29
44
 
30
- prop :exclude_packs, T::Array[String], default: []
31
- prop :include_packs, T.nilable(T::Array[String]), default: nil
32
-
33
45
  prop :remote_base_url, T.nilable(String)
34
46
  end
@@ -57,20 +57,20 @@ module VisualizePacks
57
57
  sig { params(options: Options, max_todo_count: T.nilable(Integer)).returns(String) }
58
58
  def self.diagram_title(options, max_todo_count)
59
59
  app_name = File.basename(Dir.pwd)
60
- focus_edge_info = options.focus_pack.any? && options.show_only_edges_to_focus_pack ? "showing only edges to/from focus pack" : "showing all edges between visible packs"
61
- focus_info = options.focus_pack.any? || options.focus_folder ? "Focus on #{[limited_sentence(options.focus_pack), options.focus_folder].compact.join(' and ')} (#{focus_edge_info})" : "All packs"
60
+ focus_edge_info = options.focus_pack && options.show_only_edges_to_focus_pack != FocusPackEdgeDirection::All ? "showing only edges to/from focus pack" : "showing all edges between visible packs"
61
+ focus_info = options.focus_pack ? "Focus on #{limited_sentence(options.focus_pack)} (#{focus_edge_info})" : "All packs"
62
62
  skipped_info =
63
63
  [
64
64
  options.show_legend ? nil : "hiding legend",
65
65
  options.show_layers ? nil : "hiding layers",
66
66
  options.show_dependencies ? nil : "hiding dependencies",
67
67
  options.show_todos ? nil : "hiding todos",
68
- options.only_todo_types.empty? ? nil : "only #{limited_sentence(options.only_todo_types)} todos",
68
+ EdgeTodoTypes.values.size == options.only_todo_types.size ? nil : "only #{limited_sentence(options.only_todo_types.map &:serialize)} todos",
69
69
  options.show_privacy ? nil : "hiding privacy",
70
70
  options.show_teams ? nil : "hiding teams",
71
+ options.show_visibility ? nil : "hiding visibility",
71
72
  options.roll_nested_into_parent_packs ? "hiding nested packs" : nil,
72
73
  options.show_nested_relationships ? nil : "hiding nested relationships",
73
- options.include_packs ? "including only: #{limited_sentence(options.include_packs)}" : nil,
74
74
  options.exclude_packs.empty? ? nil : "excluding pack#{options.exclude_packs.size > 1 ? 's' : ''}: #{limited_sentence(options.exclude_packs)}",
75
75
  ].compact.join(', ').strip
76
76
  main_title = "#{app_name}: #{focus_info}#{skipped_info != '' ? ' - ' + skipped_info : ''}"
@@ -95,25 +95,19 @@ module VisualizePacks
95
95
  sig { params(options: Options, all_package_names: T::Array[String]).returns(T.proc.params(arg0: String, arg1: String).returns(T::Boolean)) }
96
96
  def self.show_edge_builder(options, all_package_names)
97
97
  return lambda do |start_node, end_node|
98
+ all_package_names.include?(start_node) &&
99
+ all_package_names.include?(end_node) &&
98
100
  (
99
- !options.show_only_edges_to_focus_pack &&
100
- all_package_names.include?(start_node) &&
101
- all_package_names.include?(end_node)
102
- ) ||
103
- (
104
- options.show_only_edges_to_focus_pack &&
105
- all_package_names.include?(start_node) &&
106
- all_package_names.include?(end_node) &&
107
- (
108
- case options.show_only_edges_to_focus_pack
109
- when FocusPackEdgeDirection::InOut then
110
- match_packs?(start_node, options.focus_pack) || match_packs?(end_node, options.focus_pack)
111
- when FocusPackEdgeDirection::In then
112
- match_packs?(end_node, options.focus_pack)
113
- when FocusPackEdgeDirection::Out then
114
- match_packs?(start_node, options.focus_pack)
115
- end
116
- )
101
+ case options.show_only_edges_to_focus_pack
102
+ when FocusPackEdgeDirection::All then
103
+ true
104
+ when FocusPackEdgeDirection::InOut then
105
+ match_packs?(start_node, options.focus_pack) || match_packs?(end_node, options.focus_pack)
106
+ when FocusPackEdgeDirection::In then
107
+ match_packs?(end_node, options.focus_pack)
108
+ when FocusPackEdgeDirection::Out then
109
+ match_packs?(start_node, options.focus_pack)
110
+ end
117
111
  )
118
112
  end
119
113
  end
@@ -140,7 +134,7 @@ module VisualizePacks
140
134
  todos_by_package&.keys&.each do |todos_to_package|
141
135
  todo_types = todos_by_package&& todos_by_package[todos_to_package]&.group_by(&:type)
142
136
  todo_types&.keys&.each do |todo_type|
143
- if options.only_todo_types.empty? || options.only_todo_types.include?(todo_type)
137
+ if options.only_todo_types.include?(EdgeTodoTypes.deserialize(todo_type))
144
138
  if show_edge.call(package.name, todos_to_package)
145
139
  key = "#{package.name}->#{todos_to_package}:#{todo_type}"
146
140
  todo_counts[key] = todo_types && todo_types[todo_type]&.count
@@ -173,16 +167,14 @@ module VisualizePacks
173
167
 
174
168
  edge_width = min_width + width_delta
175
169
  edge_width.round(2)
176
- end
170
+ end
177
171
 
178
- sig { params(packages: T::Array[ParsePackwerk::Package], options: Options).returns(T::Array[ParsePackwerk::Package]) }
179
- def self.filtered(packages, options)
172
+ sig { params(packages: T::Array[ParsePackwerk::Package], options: Options).returns(T::Array[ParsePackwerk::Package]) }
173
+ def self.filtered(packages, options)
180
174
  focus_pack = options.focus_pack
181
- focus_folder = options.focus_folder
182
- include_packs = options.include_packs
183
175
  exclude_packs = options.exclude_packs
184
176
 
185
- return packages unless focus_pack.any? || focus_folder || include_packs || exclude_packs.any?
177
+ return packages unless focus_pack || exclude_packs.any?
186
178
 
187
179
  nested_packages = all_nested_packages(packages.map { |p| p.name })
188
180
 
@@ -194,16 +186,16 @@ module VisualizePacks
194
186
  result = T.let([], T::Array[T.nilable(String)])
195
187
  result = packages.map { |pack| pack.name }
196
188
 
197
- if !focus_pack.empty?
189
+ if focus_pack && !focus_pack.empty?
198
190
  result = []
199
191
  result += packages.map { |pack| pack.name }.select { |p| match_packs?(p, focus_pack) }
200
192
  if options.show_dependencies
201
193
  result += packages.select { |p| p.dependencies.any? { |d| match_packs?(d, focus_pack) }}.map { |pack| pack.name }
202
194
  end
203
- if options.show_todos && [nil, FocusPackEdgeDirection::In, FocusPackEdgeDirection::InOut].include?(options.show_only_edges_to_focus_pack)
195
+ if options.show_todos && [FocusPackEdgeDirection::All, FocusPackEdgeDirection::In, FocusPackEdgeDirection::InOut].include?(options.show_only_edges_to_focus_pack)
204
196
  result += packages.select do
205
197
  |p| (p.violations || []).inject([]) do |res, todo|
206
- res << todo.to_package_name if options.only_todo_types.empty? || options.only_todo_types.include?(todo.type)
198
+ res << todo.to_package_name if options.only_todo_types.include?(EdgeTodoTypes.deserialize(todo.type))
207
199
  res
208
200
  end.any? { |v| match_packs?(v, focus_pack) }
209
201
  end.map { |pack| pack.name }
@@ -212,9 +204,9 @@ module VisualizePacks
212
204
  if options.show_dependencies
213
205
  result += packages_by_name[p].dependencies
214
206
  end
215
- if options.show_todos && [nil, FocusPackEdgeDirection::Out, FocusPackEdgeDirection::InOut].include?(options.show_only_edges_to_focus_pack)
207
+ if options.show_todos && [FocusPackEdgeDirection::All, FocusPackEdgeDirection::Out, FocusPackEdgeDirection::InOut].include?(options.show_only_edges_to_focus_pack)
216
208
  result += (packages_by_name[p].violations || []).inject([]) do |res, todo|
217
- res << todo.to_package_name if options.only_todo_types.empty? || options.only_todo_types.include?(todo.type)
209
+ res << todo.to_package_name if options.only_todo_types.include?(EdgeTodoTypes.deserialize(todo.type))
218
210
  res
219
211
  end
220
212
  end
@@ -227,14 +219,6 @@ module VisualizePacks
227
219
  result = (result + parent_packs).uniq.compact
228
220
  end
229
221
 
230
- if focus_folder
231
- result = result.select { |p| p.include? focus_folder }
232
- end
233
-
234
- if include_packs
235
- result = result.select { |p| match_packs?(p, include_packs) }
236
- end
237
-
238
222
  if exclude_packs.any?
239
223
  result = result.reject { |p| match_packs?(p, exclude_packs) }
240
224
  end
@@ -316,8 +300,8 @@ module VisualizePacks
316
300
  morphed_packages.reject { |p| nested_packages.keys.include?(p.name) }
317
301
  end
318
302
 
319
- sig { params(pack: String, packs_name_with_wildcards: T::Array[String]).returns(T::Boolean) }
303
+ sig { params(pack: String, packs_name_with_wildcards: T.nilable(T::Array[String])).returns(T::Boolean) }
320
304
  def self.match_packs?(pack, packs_name_with_wildcards)
321
- packs_name_with_wildcards.any? {|p| File.fnmatch(p, pack)}
305
+ !packs_name_with_wildcards || packs_name_with_wildcards.any? {|p| File.fnmatch(p, pack)}
322
306
  end
323
307
  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.15
4
+ version: 0.5.17
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-05 00:00:00.000000000 Z
11
+ date: 2023-09-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler