bundler-stats 2.2.0 → 2.4.0
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 +4 -4
- data/CHANGELOG.md +12 -0
- data/README.md +117 -12
- data/lib/bundler/stats/calculator.rb +1 -3
- data/lib/bundler/stats/cli.rb +12 -28
- data/lib/bundler/stats/file_path_resolver.rb +56 -0
- data/lib/bundler/stats/skiplist.rb +32 -0
- data/lib/bundler/stats/tree.rb +6 -5
- data/lib/bundler/stats/version.rb +1 -1
- data/lib/bundler/stats.rb +2 -0
- data/spec/lib/bundler/stats/calculator_spec.rb +2 -2
- data/spec/lib/bundler/stats/file_path_resolver_spec.rb +85 -0
- data/spec/lib/bundler/stats/tree_spec.rb +9 -5
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8ecad684af63a04d936d307b3b165a0273b82ec21e7caab0b7473d2a3017fa35
|
4
|
+
data.tar.gz: f2564f384b1b5df0b3be76ad95b4cc67091f5f65b7d442c6f7ee0513ea14cc00
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
102
|
-
|
103
|
-
|
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
|
106
|
-
bundle-stats for
|
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 (
|
110
|
-
|
|
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,
|
113
|
-
|
|
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
|
-
|
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,
|
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
|
|
data/lib/bundler/stats/cli.rb
CHANGED
@@ -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 "
|
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
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
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
|
134
|
-
|
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
|
data/lib/bundler/stats/tree.rb
CHANGED
@@ -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
|
60
|
+
next arr if skiplist.include? dep
|
60
61
|
|
61
62
|
arr += transitive_dependencies(dep.name)
|
62
63
|
end
|
data/lib/bundler/stats.rb
CHANGED
@@ -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
|
41
|
+
target = subject.new(gemfile_path, lockfile_path, "skiplist")
|
42
42
|
|
43
|
-
expect(Bundler::Stats::Tree).to have_received(:new).with("parser", skiplist: "
|
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 "
|
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-
|
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 "
|
152
|
-
tree = subject.new(parser, skiplist: ["depth-
|
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-
|
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.
|
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:
|
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
|