bundler-stats 2.2.0 → 2.4.0

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: fad76aec2c17866fce619ae8dbdaa4e580a58f1c0d89c53681a35dba5e266998
4
- data.tar.gz: 27d5b7a9ac01d7f7c0856cd2422b127d18fcd4de1cda1b2bcb0bf5c596528ad6
3
+ metadata.gz: 8ecad684af63a04d936d307b3b165a0273b82ec21e7caab0b7473d2a3017fa35
4
+ data.tar.gz: f2564f384b1b5df0b3be76ad95b4cc67091f5f65b7d442c6f7ee0513ea14cc00
5
5
  SHA512:
6
- metadata.gz: 57c12161cd51c19804cfd15fb17903c1a1a9a82fe1347cd303230f5979539c7306165b926d5db4e65434d43c19c9a8649afbe0c30ee58a41cfebc2cdc653b250
7
- data.tar.gz: ee3ffeaa9580d4866a8fb11a947274ecd70e926cfdd3db83147a04500ab2a76e15ce89384268911e7e45587d483501d81d44d13e5733fe4c79f5746820887563
6
+ metadata.gz: c58e25a9360895d6727a46b7e0f4399b28bcc34d9eb5afd06db5f814511a69dfa0bfd4fec5383f769df987ab74fe8fc45b1514327468be1664f37d5f4c54e626
7
+ data.tar.gz: e2dbf4e320175d710add987c485f4e3491da9ff4d2d8ddee96328d0335444e312f88f2ab499f8b079828316a2254422a38465730587dd6a828f8498279a1a06d
data/CHANGELOG.md CHANGED
@@ -1,6 +1,18 @@
1
1
  Changelog
2
2
  =============
3
3
 
4
+ ## [2.4.0] - 2023-07-01
5
+
6
+ ### Added
7
+ - Make it possible to specify custom path for gem/Gemfile.
8
+
9
+ ## [2.3.0] - 2022-02-12
10
+
11
+ ### Added
12
+ - Skiplist now correctly removes dependencies from 1st and onward levels
13
+ - Wildcard ability for specifying gems for skiplist
14
+ - Document `versions` in README
15
+
4
16
  ## [2.2.0] - 2022-02-09
5
17
 
6
18
  ### Added
data/README.md CHANGED
@@ -34,8 +34,10 @@ Usage
34
34
  bundle-stats version # Prints the bundler-stats version
35
35
  bundle-stats versions TARGET # Shows versions requirements for target in other dependencies
36
36
 
37
+ ### Auditing Your Gemfile
38
+
37
39
  The most obvious thing to do is run the command by itself, which should help
38
- identify problem areas:
40
+ identify problem areas.
39
41
 
40
42
  > bundle-stats
41
43
 
@@ -62,7 +64,7 @@ identify problem areas:
62
64
  Unpinned Versions 54
63
65
  Github Refs 0
64
66
 
65
- It looks like rails_admin is a huge problem. Use `show` to investigate:
67
+ It looks like rails_admin is a huge problem. Use `show` to investigate.
66
68
 
67
69
  > bundle-stats show rails_admin
68
70
  bundle-stats for rails_admin
@@ -98,22 +100,117 @@ It looks like rails_admin is a huge problem. Use `show` to investigate:
98
100
  | | bundler |
99
101
  +--------------------------------|----------------------------------------+
100
102
 
101
- Removing the dep will only actually remove 9 gems. The rest are shared
102
- dependencies with other gems like rails. We can also omit trees we aren't going
103
- to remove (hi rails) by not following them:
103
+ ### Skipping Common Dependencies
104
+
105
+ Let's take a look at another common gem to rails codebases. In this case,
106
+ we have some unique dependencies, but also many dependencies on rails, and on
107
+ its constituent gems.
108
+
109
+ > bundle-stats show compass-rails
110
+ bundle-stats for compass-rails
111
+
112
+ +--------------------------------|----------------------------------------+
113
+ | Depended Upon By (0) | |
114
+ | Depends On (35) | compass, sass-rails, sprockets |
115
+ | | chunky_png, compass-core |
116
+ | | compass-import-once, rb-fsevent |
117
+ | | rb-inotify, sass, multi_json, ffi |
118
+ | | railties, sprockets-rails, tilt |
119
+ | | actionpack, activesupport, method_source |
120
+ | | rake, thor, actionview, rack, rack-test |
121
+ | | rails-dom-testing, rails-html-sanitizer |
122
+ | | builder, erubi, concurrent-ruby, i18n |
123
+ | | minitest, tzinfo, thread_safe, nokogiri |
124
+ | | mini_portile2, loofah, crass |
125
+ | Unique to This (3) | compass, compass-core |
126
+ | | compass-import-once |
127
+ +--------------------------------|----------------------------------------+
128
+
129
+ We're not looking to remove rails, so there's not much point in including it
130
+ within this output. Instead, we can use the `nofollow` flag to skip it in all
131
+ output lists.
104
132
 
105
- > bundle-stats show sass-rails --nofollow="railties,activesupport,actionpack"
106
- bundle-stats for sass-rails
133
+ > bundle-stats show compass-rails --nofollow="railties,activeupport,actionview,actionpack"
134
+ bundle-stats for compass-rails
107
135
 
108
136
  +--------------------------------|----------------------------------------+
109
- | Depended Upon By (2) | compass-rails, rails_admin |
110
- | Depends On (9) | railties, sass, sprockets |
137
+ | Depended Upon By (0) | |
138
+ | Depends On (20) | compass, sass-rails, sprockets |
139
+ | | chunky_png, compass-core |
140
+ | | compass-import-once, rb-fsevent |
141
+ | | rb-inotify, sass, multi_json, ffi |
111
142
  | | sprockets-rails, tilt, concurrent-ruby |
112
- | | rack, actionpack, activesupport |
113
- | Unique to This (0) | |
143
+ | | rack, activesupport, i18n, minitest |
144
+ | | tzinfo, thread_safe |
145
+ | Unique to This (3) | compass, compass-core |
146
+ | | compass-import-once |
114
147
  +--------------------------------|----------------------------------------+
115
148
 
116
- To consume information with a build job or somesuch, all commands can emit JSON:
149
+ This is better, but for other codebases it's common for gems to depend on each
150
+ of the _many many_ child gems of rails individually. Rather than specifying each
151
+ by itself, we can use wildcards to remove them in bulk.
152
+
153
+ > bundle-stats show compass-rails --nofollow="rail*,action*,active*"
154
+ bundle-stats for compass-rails
155
+
156
+ +--------------------------------|----------------------------------------+
157
+ | Depended Upon By (0) | |
158
+ | Depends On (15) | compass, sass-rails, sprockets |
159
+ | | chunky_png, compass-core |
160
+ | | compass-import-once, rb-fsevent |
161
+ | | rb-inotify, sass, multi_json, ffi |
162
+ | | sprockets-rails, tilt, concurrent-ruby |
163
+ | | rack |
164
+ | Unique to This (3) | compass, compass-core |
165
+ | | compass-import-once |
166
+ +--------------------------------|----------------------------------------+
167
+
168
+ ### Showing Required Versions
169
+
170
+ Sometimes you try to upgrade a gem, you ask bundler _very nicely_, but you
171
+ find that the version hasn't changed. When that happens, sometimes it's not
172
+ clear why the gem version isn't changing.
173
+
174
+ In that case, use `versions` to list all required dependencies on your gem.
175
+
176
+ > bundle-stats versions actionpack
177
+ version dependencies for actionpack
178
+
179
+ Depended Upon By 24
180
+ Resolved Version 5.2.0
181
+
182
+ +----------------------------|------------------+
183
+ | Name | Required Version |
184
+ +----------------------------|------------------+
185
+ | webpacker | = 5.2.0 |
186
+ | actionmailer | = 5.2.0 |
187
+ | activestorage | = 5.2.0 |
188
+ | coffee-rails | = 5.2.0 |
189
+ | compass-rails | = 5.2.0 |
190
+ | devise | = 5.2.0 |
191
+ | factory_bot_rails | = 5.2.0 |
192
+ | font-awesome-rails | = 5.2.0 |
193
+ | rails_admin | = 5.2.0 |
194
+ | railties | = 5.2.0 |
195
+ | sass-rails | = 5.2.0 |
196
+ | scenic | = 5.2.0 |
197
+ | versionist | = 5.2.0 |
198
+ | actioncable | = 5.2.0 |
199
+ | jquery-rails | = 5.2.0 |
200
+ | jquery-ui-rails | = 5.2.0 |
201
+ | jquery_file_download-rails | = 5.2.0 |
202
+ | rails | = 5.2.0 |
203
+ | rspec-rails | >= 3.0 |
204
+ | sprockets-rails | >= 4.0 |
205
+ | haml-rails | >= 4.0.1 |
206
+ | responders | >= 4.2.0, < 5.3 |
207
+ | simple_form | >= 5.0 |
208
+ | rails-controller-testing | ~> 5.x, >= 5.0.1 |
209
+ +----------------------------|------------------+
210
+
211
+ ### Output Formats
212
+
213
+ To consume information with a build job or somesuch, all commands can emit JSON.
117
214
 
118
215
  > bundle-stats show sass-rails --nofollow="railties,activesupport,actionpack" -f json
119
216
  {
@@ -140,6 +237,14 @@ To consume information with a build job or somesuch, all commands can emit JSON:
140
237
  ]
141
238
  }
142
239
 
240
+ ### Custom Gemfile path
241
+
242
+ This gem by default attempts to locate the Gemfile and Gemfile.lock files in parent directories. If you want to specify a specific location for your Gemfile/gems.rb file, you can use the `--gemfile_path` option.
243
+
244
+ > bundle-stats show sass-rails --gemfile_path=/Users/user/project/Gemfile
245
+
246
+ Keep in mind that the location of the Gemfile.lock/gems.locked file will be inferred from the location of the Gemfile/gems.rb file.
247
+
143
248
  Contributing
144
249
  ------------
145
250
 
@@ -5,7 +5,7 @@ module Bundler
5
5
  class Calculator
6
6
  attr_reader :parser, :tree, :gemfile, :remover
7
7
 
8
- def initialize(gemfile_path, lockfile_path, options = {})
8
+ def initialize(gemfile_path, lockfile_path, skiplist = nil)
9
9
  raise ArgumentError unless File.readable?(lockfile_path)
10
10
  raise ArgumentError unless File.readable?(gemfile_path)
11
11
 
@@ -17,9 +17,7 @@ module Bundler
17
17
  lock_contents = File.read(lockfile_path)
18
18
  @parser = Bundler::LockfileParser.new(lock_contents)
19
19
 
20
- skiplist = options.fetch(:skiplist, [])
21
20
  @tree = Bundler::Stats::Tree.new(@parser, skiplist: skiplist)
22
-
23
21
  @remover = Bundler::Stats::Remover.new(@tree, @gemfile)
24
22
  end
25
23
 
@@ -13,6 +13,7 @@ module Bundler
13
13
  desc 'stats', 'Displays basic stats about the gems in your Gemfile'
14
14
  method_option :format, aliases: "-f", description: "Output format, either JSON or text"
15
15
  method_option :nofollow, description: "A comma delimited list of dependencies not to follow."
16
+ method_option :gemfile_path, description: "Custom path for Gemfile/gems.rb and Gemfile.lock/gems.locked"
16
17
  def stats
17
18
  calculator = build_calculator(options)
18
19
  stats = calculator.stats
@@ -27,6 +28,7 @@ module Bundler
27
28
  desc 'show TARGET', 'Prints the dependency tree for a single gem in your Gemfile'
28
29
  method_option :format, aliases: "-f", description: "Output format, either JSON or text"
29
30
  method_option :nofollow, description: "A comma delimited list of dependencies not to follow."
31
+ method_option :gemfile_path, description: "Custom path for Gemfile/gems.rb and Gemfile.lock/gems.locked"
30
32
  def show(target)
31
33
  calculator = build_calculator(options)
32
34
  stats = calculator.summarize(target)
@@ -41,6 +43,7 @@ module Bundler
41
43
  desc 'versions TARGET', 'Shows versions requirements for target in other dependencies'
42
44
  method_option :format, aliases: "-f", description: "Output format, either JSON or text"
43
45
  method_option :nofollow, description: "A comma delimited list of dependencies not to follow."
46
+ method_option :gemfile_path, description: "Custom path for Gemfile/gems.rb and Gemfile.lock/gems.locked"
44
47
  def versions(target)
45
48
  calculator = build_calculator(options)
46
49
  stats = calculator.versions(target)
@@ -99,7 +102,7 @@ module Bundler
99
102
 
100
103
  def draw_versions(stats, target)
101
104
  dependers = stats[:top_level_dependencies] # they do the depending
102
- say "bundle-stats for #{target}"
105
+ say "version dependencies for #{target}"
103
106
  say Printer.new(
104
107
  headers: nil,
105
108
  borders: false,
@@ -121,35 +124,16 @@ module Bundler
121
124
  end
122
125
 
123
126
  def build_calculator(options)
124
- if !options[:nofollow].nil?
125
- skiplist = options[:nofollow].gsub(/\s+/, '').split(",")
126
- else
127
- skiplist = []
128
- end
129
-
130
- @calculator ||= Bundler::Stats::Calculator.new(gemfile_path, lockfile_path, skiplist: skiplist)
127
+ skiplist = Bundler::Stats::Skiplist.new(options[:nofollow])
128
+ @calculator ||= Bundler::Stats::Calculator.new(
129
+ file_path_resolver.gemfile_path,
130
+ file_path_resolver.lockfile_path,
131
+ skiplist
132
+ )
131
133
  end
132
134
 
133
- def gemfile_path
134
- cwd = Pathname.new("./")
135
- until cwd.realdirpath.root? do
136
- %w(gems.rb Gemfile).each do |gemfile|
137
- return (cwd + gemfile) if File.exist?(cwd + gemfile)
138
- end
139
- cwd = cwd.parent
140
- end
141
- raise ArgumentError, "Couldn't find gems.rb nor Gemfile in this directory or parents"
142
- end
143
-
144
- def lockfile_path
145
- cwd = Pathname.new(".")
146
- until cwd.realdirpath.root? do
147
- %w(gems.locked Gemfile.lock).each do |lockfile|
148
- return (cwd + lockfile) if File.exist?(cwd + lockfile)
149
- end
150
- cwd = cwd.parent
151
- end
152
- raise ArgumentError, "Couldn't find gems.locked nor Gemfile.lock in this directory or parents"
135
+ def file_path_resolver
136
+ @file_path_resolver ||= Bundler::Stats::FilePathResolver.new(options[:gemfile_path])
153
137
  end
154
138
  end
155
139
  end
@@ -0,0 +1,56 @@
1
+ module Bundler
2
+ module Stats
3
+ class FilePathResolver
4
+ FILES_MAP = {
5
+ "gems.rb" => "gems.locked",
6
+ "Gemfile" => "Gemfile.lock"
7
+ }
8
+
9
+ def initialize(specific_gemfile_path = nil)
10
+ @specific_gemfile_path = specific_gemfile_path
11
+ end
12
+
13
+ def gemfile_path
14
+ resolve_file_path(FILES_MAP.keys, specific_gemfile_path)
15
+ end
16
+
17
+ def lockfile_path
18
+ resolve_file_path(FILES_MAP.values, resolve_lockfile_path)
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :specific_gemfile_path
24
+
25
+ def resolve_lockfile_path
26
+ return unless specific_gemfile_path
27
+
28
+ file_path = Pathname.new(specific_gemfile_path)
29
+ file_name = file_path.basename.to_s
30
+ locked_file_name = FILES_MAP[file_name]
31
+ raise ArgumentError, "Invalid file name: #{file_name}" if locked_file_name.nil?
32
+ file_path.dirname.join(locked_file_name).to_s
33
+ end
34
+
35
+ def resolve_file_path(file_names, custom_path)
36
+ if custom_path
37
+ raise ArgumentError, "Couldn't find #{custom_path} file path" unless File.exist?(custom_path)
38
+ return custom_path
39
+ end
40
+
41
+ find_file_path(file_names)
42
+ end
43
+
44
+ def find_file_path(file_names)
45
+ cwd = Pathname.new(".")
46
+ until cwd.realdirpath.root? do
47
+ file_names.each do |file|
48
+ return (cwd + file).to_s if File.exist?(cwd + file)
49
+ end
50
+ cwd = cwd.parent
51
+ end
52
+ raise ArgumentError, "Couldn't find #{file_names.join(" nor ")} in this directory or parents"
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,32 @@
1
+ class Bundler::Stats::Skiplist
2
+ attr_reader :regex_list
3
+
4
+ def initialize(list = '')
5
+ @regex_list = if list.respond_to?(:regex_list)
6
+ list.regex_list
7
+ elsif list.respond_to?(:split)
8
+ list
9
+ .gsub(/\s+/, '')
10
+ .split(",")
11
+ .map { |str| glob_to_regex(str) }
12
+ else
13
+ (list || []).map { |str| glob_to_regex(str) }
14
+ end
15
+ end
16
+
17
+ def filter(gem_list)
18
+ gem_list.reject { |gem| self.include?(gem) }
19
+ end
20
+
21
+ def include?(target)
22
+ @regex_list.any? { |pattern| pattern =~ target.name }
23
+ end
24
+
25
+ private
26
+
27
+ def glob_to_regex(str)
28
+ str.gsub!('*','.*') # weird globbish behavior
29
+
30
+ /^#{str}$/
31
+ end
32
+ end
@@ -1,20 +1,21 @@
1
1
  class Bundler::Stats::Tree
2
- attr_accessor :tree
2
+ attr_accessor :tree, :skiplist
3
3
 
4
4
  ERR_MESSAGE = "The dependency `%s` wasn't found. It may not be present in " \
5
5
  "your Gemfile.lock. This often happens when a dependency isn't " \
6
6
  "installed on your platform."
7
7
 
8
- def initialize(parser, skiplist: [])
8
+ def initialize(parser, skiplist: '')
9
9
  raise ArgumentError unless parser.respond_to?(:specs)
10
10
 
11
11
  @parser = parser
12
12
  @tree = specs_as_tree(@parser.specs)
13
- @skiplist = skiplist
13
+ @skiplist = Bundler::Stats::Skiplist.new(skiplist)
14
14
  end
15
15
 
16
16
  def summarize(target)
17
17
  transitive_dependencies = transitive_dependencies(target)
18
+
18
19
  { name: target,
19
20
  total_dependencies: transitive_dependencies.count,
20
21
  first_level_dependencies: first_level_dependencies(target).count,
@@ -51,12 +52,12 @@ class Bundler::Stats::Tree
51
52
  return []
52
53
  end
53
54
 
54
- top_level = @tree[target].dependencies
55
+ top_level = skiplist.filter(@tree[target].dependencies)
55
56
  all_level = top_level + top_level.inject([]) do |arr, dep|
56
57
  # turns out bundler refuses to include itself in the dependency tree,
57
58
  # which is sneaky
58
59
  next arr if dep.name == "bundler"
59
- next arr if @skiplist.include? dep.name
60
+ next arr if skiplist.include? dep
60
61
 
61
62
  arr += transitive_dependencies(dep.name)
62
63
  end
@@ -1,5 +1,5 @@
1
1
  module Bundler
2
2
  module Stats
3
- VERSION = '2.2.0'
3
+ VERSION = '2.4.0'
4
4
  end
5
5
  end
data/lib/bundler/stats.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require_relative 'stats/calculator'
2
+ require_relative 'stats/file_path_resolver'
2
3
  require_relative 'stats/printer'
3
4
  require_relative 'stats/remover'
5
+ require_relative 'stats/skiplist'
4
6
  require_relative 'stats/tree'
5
7
  require_relative 'stats/version'
@@ -38,9 +38,9 @@ describe Bundler::Stats::Calculator do
38
38
  # this sucks. break this dependency further
39
39
  allow(Bundler::LockfileParser).to receive(:new) { "parser" }
40
40
 
41
- target = subject.new(gemfile_path, lockfile_path, skiplist: "abc")
41
+ target = subject.new(gemfile_path, lockfile_path, "skiplist")
42
42
 
43
- expect(Bundler::Stats::Tree).to have_received(:new).with("parser", skiplist: "abc")
43
+ expect(Bundler::Stats::Tree).to have_received(:new).with("parser", skiplist: "skiplist")
44
44
  end
45
45
  end
46
46
 
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+
3
+ describe Bundler::Stats::FilePathResolver do
4
+ let(:file_path_resolver) { described_class.new(specific_gemfile_path) }
5
+
6
+ context "with undefined specific gemfile path" do
7
+ let(:specific_gemfile_path) { nil }
8
+
9
+ before do
10
+ allow(File).to receive(:exist?).and_return(false)
11
+ end
12
+
13
+ context "without files found" do
14
+ it do
15
+ expect { file_path_resolver.gemfile_path }.to raise_error(
16
+ ArgumentError, "Couldn't find gems.rb nor Gemfile in this directory or parents"
17
+ )
18
+ end
19
+
20
+ it do
21
+ expect { file_path_resolver.lockfile_path }.to raise_error(
22
+ ArgumentError, "Couldn't find gems.locked nor Gemfile.lock in this directory or parents"
23
+ )
24
+ end
25
+ end
26
+
27
+ context "with files found" do
28
+ before do
29
+ allow(File).to receive(:exist?).with(Pathname.new("../Gemfile")).and_return(true)
30
+ allow(File).to receive(:exist?).with(Pathname.new("../../gems.locked")).and_return(true)
31
+ end
32
+
33
+ it { expect(file_path_resolver.gemfile_path).to eq("../Gemfile") }
34
+ it { expect(file_path_resolver.lockfile_path).to eq("../../gems.locked") }
35
+ end
36
+ end
37
+
38
+ context "with specific gemfile path" do
39
+ let(:specific_gemfile_path) { "some-project/Gemfile" }
40
+
41
+ context "with valid file path" do
42
+ before do
43
+ allow(File).to receive(:exist?).and_return(true)
44
+ end
45
+
46
+ it { expect(file_path_resolver.gemfile_path).to eq("some-project/Gemfile") }
47
+ it { expect(file_path_resolver.lockfile_path).to eq("some-project/Gemfile.lock") }
48
+
49
+ context "with gems.rb file" do
50
+ let(:specific_gemfile_path) { "some-project/gems.rb" }
51
+
52
+ it { expect(file_path_resolver.gemfile_path).to eq("some-project/gems.rb") }
53
+ it { expect(file_path_resolver.lockfile_path).to eq("some-project/gems.locked") }
54
+ end
55
+
56
+ context "with invalid file name" do
57
+ let(:specific_gemfile_path) { "some-project/yeimfile" }
58
+
59
+ it do
60
+ expect { file_path_resolver.lockfile_path }.to raise_error(
61
+ ArgumentError, "Invalid file name: yeimfile"
62
+ )
63
+ end
64
+ end
65
+ end
66
+
67
+ context "with invalid file path" do
68
+ before do
69
+ allow(File).to receive(:exist?).and_return(false)
70
+ end
71
+
72
+ it do
73
+ expect { file_path_resolver.gemfile_path }.to raise_error(
74
+ ArgumentError, "Couldn't find some-project/Gemfile file path"
75
+ )
76
+ end
77
+
78
+ it do
79
+ expect { file_path_resolver.lockfile_path }.to raise_error(
80
+ ArgumentError, "Couldn't find some-project/Gemfile.lock file path"
81
+ )
82
+ end
83
+ end
84
+ end
85
+ end
@@ -140,20 +140,24 @@ describe Bundler::Stats::Tree do
140
140
  end
141
141
 
142
142
  context "skip lists" do
143
- it "still includes the skipped entry" do
143
+ it "skips processing the requested entry, plus children of skipped entries" do
144
144
  tree = subject.new(parser, skiplist: ["depth-three"])
145
145
 
146
146
  target = tree.transitive_dependencies("depth-one")
147
147
 
148
- expect(target.map(&:name)).to include("depth-three")
148
+ expect(target.map(&:name)).to include("depth-two")
149
+ expect(target.map(&:name)).not_to include("depth-three")
150
+ expect(target.map(&:name)).not_to include("depth-four")
149
151
  end
150
152
 
151
- it "stops processing the children of skipped entries" do
152
- tree = subject.new(parser, skiplist: ["depth-three"])
153
+ it "allows skiplist wildcards" do
154
+ tree = subject.new(parser, skiplist: ["depth-t*"])
153
155
 
154
156
  target = tree.transitive_dependencies("depth-one")
155
157
 
156
- expect(target.map(&:name)).not_to include("depth-four")
158
+ expect(target.map(&:name)).not_to include("depth-two")
159
+ expect(target.map(&:name)).not_to include("depth-three")
160
+ expect(target.map(&:name)).not_to include("depth-four") # because transitive
157
161
  end
158
162
  end
159
163
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bundler-stats
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joseph Mastey
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-09 00:00:00.000000000 Z
11
+ date: 2023-07-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -148,11 +148,14 @@ files:
148
148
  - lib/bundler/stats.rb
149
149
  - lib/bundler/stats/calculator.rb
150
150
  - lib/bundler/stats/cli.rb
151
+ - lib/bundler/stats/file_path_resolver.rb
151
152
  - lib/bundler/stats/printer.rb
152
153
  - lib/bundler/stats/remover.rb
154
+ - lib/bundler/stats/skiplist.rb
153
155
  - lib/bundler/stats/tree.rb
154
156
  - lib/bundler/stats/version.rb
155
157
  - spec/lib/bundler/stats/calculator_spec.rb
158
+ - spec/lib/bundler/stats/file_path_resolver_spec.rb
156
159
  - spec/lib/bundler/stats/printer_spec.rb
157
160
  - spec/lib/bundler/stats/remover_spec.rb
158
161
  - spec/lib/bundler/stats/tree_spec.rb