bundler-stats 2.2.0 → 2.3.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: 38f866872f6ba724ee82db46ba1715c05bcf8f22272f0ae6a23a96b1760232ce
4
+ data.tar.gz: ee9b4655d4c8faa1da7f23d3602820ab70eeaf10aad836f4bc7c544cd10bf795
5
5
  SHA512:
6
- metadata.gz: 57c12161cd51c19804cfd15fb17903c1a1a9a82fe1347cd303230f5979539c7306165b926d5db4e65434d43c19c9a8649afbe0c30ee58a41cfebc2cdc653b250
7
- data.tar.gz: ee3ffeaa9580d4866a8fb11a947274ecd70e926cfdd3db83147a04500ab2a76e15ce89384268911e7e45587d483501d81d44d13e5733fe4c79f5746820887563
6
+ metadata.gz: e31cce716bfae8bdc92e525d1047678b96c4ea18f80aee2875718f84c690a8a76dbd34ee923b445724716f45eb0e9cdbeab69e13b0d6479284cb4a1185beeecf
7
+ data.tar.gz: 2644320effea69f6e117a92154e3ddf0e0a3327a23d8141262dc4138fefa8a8a84eab049e68686ded2f778d2b271cbf8a00c43a6eb2b9fa06c09d01b11ce694d
data/CHANGELOG.md CHANGED
@@ -1,6 +1,13 @@
1
1
  Changelog
2
2
  =============
3
3
 
4
+ ## [2.3.0] - 2022-02-12
5
+
6
+ ### Added
7
+ - Skiplist now correctly removes dependencies from 1st and onward levels
8
+ - Wildcard ability for specifying gems for skiplist
9
+ - Document `versions` in README
10
+
4
11
  ## [2.2.0] - 2022-02-09
5
12
 
6
13
  ### 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
  {
@@ -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
 
@@ -99,7 +99,7 @@ module Bundler
99
99
 
100
100
  def draw_versions(stats, target)
101
101
  dependers = stats[:top_level_dependencies] # they do the depending
102
- say "bundle-stats for #{target}"
102
+ say "version dependencies for #{target}"
103
103
  say Printer.new(
104
104
  headers: nil,
105
105
  borders: false,
@@ -121,13 +121,8 @@ module Bundler
121
121
  end
122
122
 
123
123
  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)
124
+ skiplist = Bundler::Stats::Skiplist.new(options[:nofollow])
125
+ @calculator ||= Bundler::Stats::Calculator.new(gemfile_path, lockfile_path, skiplist)
131
126
  end
132
127
 
133
128
  def gemfile_path
@@ -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.3.0'
4
4
  end
5
5
  end
data/lib/bundler/stats.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require_relative 'stats/calculator'
2
2
  require_relative 'stats/printer'
3
3
  require_relative 'stats/remover'
4
+ require_relative 'stats/skiplist'
4
5
  require_relative 'stats/tree'
5
6
  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
 
@@ -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.3.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: 2022-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -150,6 +150,7 @@ files:
150
150
  - lib/bundler/stats/cli.rb
151
151
  - lib/bundler/stats/printer.rb
152
152
  - lib/bundler/stats/remover.rb
153
+ - lib/bundler/stats/skiplist.rb
153
154
  - lib/bundler/stats/tree.rb
154
155
  - lib/bundler/stats/version.rb
155
156
  - spec/lib/bundler/stats/calculator_spec.rb