bundler 1.7.0 → 1.7.1.pre

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bundler might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 155503cb2801c3408a1a6290488e86d95fc44377
4
- data.tar.gz: 155ff56ba76e00285762682095374af6978dc701
3
+ metadata.gz: 1213efeb576d584ede27b76fe40b77dbd6448ccf
4
+ data.tar.gz: 9117d8aa3a74e6a2141341beb3c46f355dcb0e8b
5
5
  SHA512:
6
- metadata.gz: 79b16bf6b319c496e5dd80d74582217e9def1ca17f937c7173e20b973066064406d0a21f092e175a504ad1743ee86ff17b56639c336b3c78ea621485b790cea8
7
- data.tar.gz: c61d725503a3ac4d74a1708ee30ce80bea1b075118df1bc054c0339fd538809284f2dcda20057bba1950ae1414297118dc869cf1d6752f3fa0d09001522d0b83
6
+ metadata.gz: dfc4d08a4d524d312750479bb191421316e2b3f031aac807ee6032ab15d028718929691de7392cd99bdf16d6365764a4ceb5ee46264db96ecf05953e8a90c745
7
+ data.tar.gz: 0dfeea04bba5099692f3f90e68f6b4aae7fa682e040974d17087c43de38327a16fc87781f7693b3b40ccead090484229e51ecf8bbec7b8f64609aa73a1271130
@@ -1,8 +1,14 @@
1
+ ## 1.7.1
2
+
3
+ Bugfixes:
4
+
5
+ - Install gems from one source needed by gems in another source (@indirect)
6
+
1
7
  ## 1.7.0 (2014-08-13)
2
8
 
3
9
  Security:
4
10
 
5
- - Fix for CVE-2013-0334, installing gems from an unexpected source
11
+ - Fix for CVE-2013-0334, installing gems from an unexpected source (@tmoore)
6
12
 
7
13
  Features:
8
14
 
@@ -189,15 +189,6 @@ module Bundler
189
189
  else
190
190
  last_resolve = converge_locked_specs
191
191
 
192
- # Record the specs available in each gem's source, so that those
193
- # specs will be available later when the resolver knows where to
194
- # look for that gemspec (or its dependencies)
195
- source_requirements = {}
196
- dependencies.each do |dep|
197
- next unless dep.source
198
- source_requirements[dep.name] = dep.source.specs
199
- end
200
-
201
192
  # Run a resolve against the locally available gems
202
193
  last_resolve.merge Resolver.resolve(expanded_dependencies, index, source_requirements, last_resolve)
203
194
  end
@@ -210,14 +201,9 @@ module Bundler
210
201
  dependency_names.map! {|d| d.name }
211
202
 
212
203
  sources.all_sources.each do |s|
213
- if s.is_a?(Bundler::Source::Rubygems)
214
- s.dependency_names = dependency_names.uniq
215
- idx.add_source s.specs
216
- else
217
- source_index = s.specs
218
- dependency_names += source_index.unmet_dependency_names
219
- idx.add_source source_index
220
- end
204
+ s.dependency_names = dependency_names
205
+ idx.add_source s.specs
206
+ dependency_names.push(*s.unmet_deps).uniq!
221
207
  end
222
208
  end
223
209
  end
@@ -462,8 +448,19 @@ module Bundler
462
448
  def converge_sources
463
449
  changes = false
464
450
 
465
- # Get the Rubygems source from the Gemfile.lock
466
- locked_gem = @locked_sources.select { |s| s.kind_of?(Source::Rubygems) }
451
+ # Get the Rubygems sources from the Gemfile.lock
452
+ locked_gem_sources = @locked_sources.select { |s| s.kind_of?(Source::Rubygems) }
453
+ # Get the Rubygems sources from the Gemfile
454
+ actual_gem_sources = @sources.rubygems_sources
455
+
456
+ # If there is a Rubygems source in both
457
+ unless locked_gem_sources.empty? && actual_gem_sources.empty?
458
+ actual_remotes = actual_gem_sources.map(&:remotes).flatten.uniq
459
+ locked_gem_sources.each do |locked_gem|
460
+ # Merge the remotes from the Gemfile into the Gemfile.lock
461
+ changes = changes | locked_gem.replace_remotes(actual_remotes)
462
+ end
463
+ end
467
464
 
468
465
  # Replace the sources from the Gemfile with the sources from the Gemfile.lock,
469
466
  # if they exist in the Gemfile.lock and are `==`. If you can't find an equivalent
@@ -593,5 +590,19 @@ module Bundler
593
590
  groups.map! { |g| g.to_sym }
594
591
  dependencies.reject { |d| !d.should_include? || (d.groups & groups).empty? }
595
592
  end
593
+
594
+ def source_requirements
595
+ # Load all specs from remote sources
596
+ index
597
+
598
+ # Record the specs available in each gem's source, so that those
599
+ # specs will be available later when the resolver knows where to
600
+ # look for that gemspec (or its dependencies)
601
+ dependencies.each_with_object({}) do |dep, source_requirements|
602
+ next unless dep.source
603
+ source_requirements[dep.name] = dep.source.specs
604
+ end
605
+ end
606
+
596
607
  end
597
608
  end
@@ -161,6 +161,7 @@ module Bundler
161
161
 
162
162
  # return the specs in the bundler format as an index
163
163
  def specs(gem_names, source)
164
+ old = Bundler.rubygems.sources
164
165
  index = Index.new
165
166
 
166
167
  if gem_names && use_api
@@ -193,6 +194,8 @@ module Bundler
193
194
  rescue CertificateFailureError => e
194
195
  Bundler.ui.info "" if gem_names && use_api # newline after dots
195
196
  raise e
197
+ ensure
198
+ Bundler.rubygems.sources = old
196
199
  end
197
200
 
198
201
  # fetch index
@@ -289,9 +292,9 @@ module Bundler
289
292
  end
290
293
 
291
294
  def dependency_api_uri(gem_names = [])
292
- url = "#{redirected_uri}api/v1/dependencies"
293
- url << "?gems=#{URI.encode(gem_names.join(","))}" if gem_names.any?
294
- URI.parse(url)
295
+ uri = fetch_uri + "api/v1/dependencies"
296
+ uri.query = "gems=#{URI.encode(gem_names.join(","))}" if gem_names.any?
297
+ uri
295
298
  end
296
299
 
297
300
  # fetch from Gemcutter Dependency Endpoint API
@@ -378,18 +381,18 @@ module Bundler
378
381
  yield
379
382
  end
380
383
 
381
- private
382
- def redirected_uri
383
- return bundler_uri if rubygems?
384
- return @remote_uri
385
- end
386
-
387
- def rubygems?
388
- @remote_uri.host == "rubygems.org"
389
- end
384
+ private
390
385
 
391
- def bundler_uri
392
- URI.parse("#{@remote_uri.scheme}://bundler.#{@remote_uri.host}/")
386
+ def fetch_uri
387
+ @fetch_uri ||= begin
388
+ if @remote_uri.host == "rubygems.org"
389
+ uri = @remote_uri.dup
390
+ uri.host = "bundler.rubygems.org"
391
+ uri
392
+ else
393
+ @remote_uri
394
+ end
395
+ end
393
396
  end
394
397
 
395
398
  end
@@ -106,12 +106,11 @@ module Bundler
106
106
 
107
107
  # returns a list of the dependencies
108
108
  def unmet_dependency_names
109
- dependency_names = specs.values.map do |array_of_s|
110
- array_of_s.map do |s|
111
- s.dependencies.map{|d| d.name }
112
- end
113
- end.flatten.uniq
114
- dependency_names.select{|name| name != 'bundler' && specs_by_name(name).empty? }
109
+ names = []
110
+ each{|s| names.push *s.dependencies.map{|d| d.name } }
111
+ names.uniq!
112
+ names.delete_if{|n| n == "bundler" }
113
+ names.select{|n| search(n).empty? }
115
114
  end
116
115
 
117
116
  def use(other, override_dupes = false)
@@ -14,6 +14,12 @@ module Bundler
14
14
  mirrors[normalized_key] || uri
15
15
  end
16
16
 
17
+ attr_accessor :dependency_names
18
+
19
+ def unmet_deps
20
+ specs.unmet_dependency_names
21
+ end
22
+
17
23
  def version_message(spec)
18
24
  locked_spec = Bundler.locked_gems.specs.find { |s| s.name == spec.name } if Bundler.locked_gems
19
25
  locked_spec_version = locked_spec.version if locked_spec
@@ -8,12 +8,10 @@ module Bundler
8
8
  API_REQUEST_LIMIT = 100 # threshold for switching back to the modern index instead of fetching every spec
9
9
 
10
10
  attr_reader :remotes, :caches
11
- attr_accessor :dependency_names
12
11
 
13
12
  def initialize(options = {})
14
13
  @options = options
15
14
  @remotes = []
16
- @fetchers = {}
17
15
  @dependency_names = []
18
16
  @allow_remote = false
19
17
  @allow_cached = false
@@ -35,7 +33,7 @@ module Bundler
35
33
  end
36
34
 
37
35
  def eql?(o)
38
- o.is_a?(Rubygems) && remotes == o.remotes
36
+ o.is_a?(Rubygems) && remotes_equal?(o.remotes)
39
37
  end
40
38
 
41
39
  alias == eql?
@@ -67,7 +65,15 @@ module Bundler
67
65
  alias_method :name, :to_s
68
66
 
69
67
  def specs
70
- @specs ||= fetch_specs
68
+ @specs ||= begin
69
+ # remote_specs usually generates a way larger Index than the other
70
+ # sources, and large_idx.use small_idx is way faster than
71
+ # small_idx.use large_idx.
72
+ idx = @allow_remote ? remote_specs.dup : Index.new
73
+ idx.use(cached_specs, :override_dupes) if @allow_cached || @allow_remote
74
+ idx.use(installed_specs, :override_dupes)
75
+ idx
76
+ end
71
77
  end
72
78
 
73
79
  def install(spec)
@@ -163,6 +169,23 @@ module Bundler
163
169
  @remotes.unshift(uri) unless @remotes.include?(uri)
164
170
  end
165
171
 
172
+ def replace_remotes(other_remotes)
173
+ return false if other_remotes == @remotes
174
+
175
+ @remotes = []
176
+ other_remotes.reverse_each do |r|
177
+ add_remote r.to_s
178
+ end
179
+ end
180
+
181
+ def unmet_deps
182
+ if fetchers.any? && fetchers.all?{|f| f.use_api }
183
+ remote_specs.unmet_dependency_names
184
+ else
185
+ []
186
+ end
187
+ end
188
+
166
189
  protected
167
190
 
168
191
  def source_uris_for_spec(spec)
@@ -193,7 +216,7 @@ module Bundler
193
216
  end
194
217
 
195
218
  def suppress_configured_credentials(remote)
196
- remote_nouser = remote.tap { |uri| uri.user = uri.password = nil }.to_s
219
+ remote_nouser = remote.dup.tap { |uri| uri.user = uri.password = nil }.to_s
197
220
  if remote.userinfo && remote.userinfo == Bundler.settings[remote_nouser]
198
221
  remote_nouser
199
222
  else
@@ -201,20 +224,6 @@ module Bundler
201
224
  end
202
225
  end
203
226
 
204
- def fetch_specs
205
- # remote_specs usually generates a way larger Index than the other
206
- # sources, and large_idx.use small_idx is way faster than
207
- # small_idx.use large_idx.
208
- if @allow_remote
209
- idx = remote_specs.dup
210
- else
211
- idx = Index.new
212
- end
213
- idx.use(cached_specs, :override_dupes) if @allow_cached || @allow_remote
214
- idx.use(installed_specs, :override_dupes)
215
- idx
216
- end
217
-
218
227
  def installed_specs
219
228
  @installed_specs ||= begin
220
229
  idx = Index.new
@@ -261,12 +270,14 @@ module Bundler
261
270
  idx
262
271
  end
263
272
 
264
- def remote_specs
265
- @remote_specs ||= begin
266
- old = Bundler.rubygems.sources
267
- idx = Index.new
273
+ def fetchers
274
+ @fetchers ||= remotes.map do |url|
275
+ Bundler::Fetcher.new(url)
276
+ end
277
+ end
268
278
 
269
- fetchers = remotes.map { |uri| Bundler::Fetcher.new(uri) }
279
+ def remote_specs
280
+ @remote_specs ||= Index.build do |idx|
270
281
  api_fetchers = fetchers.select { |f| f.use_api }
271
282
  index_fetchers = fetchers - api_fetchers
272
283
 
@@ -275,7 +286,6 @@ module Bundler
275
286
  Bundler.ui.info "Fetching source index from #{f.uri}"
276
287
  idx.use f.specs(nil, self)
277
288
  end
278
- return idx if api_fetchers.empty?
279
289
 
280
290
  # because ensuring we have all the gems we need involves downloading
281
291
  # the gemspecs of those gems, if the non-api sites contain more than
@@ -289,7 +299,7 @@ module Bundler
289
299
  Bundler.ui.info "" if !Bundler.ui.debug? # new line now that the dots are over
290
300
  end
291
301
 
292
- if api_fetchers.all?{|f| f.use_api }
302
+ if api_fetchers.any? && api_fetchers.all?{|f| f.use_api }
293
303
  # it's possible that gems from one source depend on gems from some
294
304
  # other source, so now we download gemspecs and iterate over those
295
305
  # dependencies, looking for gems we don't have info on yet.
@@ -312,10 +322,6 @@ module Bundler
312
322
  idx.use f.specs(nil, self)
313
323
  end
314
324
  end
315
-
316
- return idx
317
- ensure
318
- Bundler.rubygems.sources = old
319
325
  end
320
326
  end
321
327
 
@@ -331,6 +337,10 @@ module Bundler
331
337
  # Ruby 2.0, where gemspecs are stored in specifications/default/
332
338
  spec.loaded_from && spec.loaded_from.include?("specifications/default/")
333
339
  end
340
+
341
+ def remotes_equal?(other_remotes)
342
+ remotes.map(&method(:suppress_configured_credentials)) == other_remotes.map(&method(:suppress_configured_credentials))
343
+ end
334
344
  end
335
345
  end
336
346
  end
@@ -2,5 +2,5 @@ module Bundler
2
2
  # We're doing this because we might write tests that deal
3
3
  # with other versions of bundler and we are unsure how to
4
4
  # handle this better.
5
- VERSION = "1.7.0" unless defined?(::Bundler::VERSION)
5
+ VERSION = "1.7.1.pre" unless defined?(::Bundler::VERSION)
6
6
  end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Bundler::SourceList do
4
4
  before do
5
- Bundler.stub(:root) { Pathname.new '/' }
5
+ allow(Bundler).to receive(:root) { Pathname.new '/' }
6
6
  end
7
7
 
8
8
  subject(:source_list) { Bundler::SourceList.new }
@@ -337,23 +337,12 @@ describe Bundler::SourceList do
337
337
  let(:git_source) { source_list.add_git_source('uri' => 'git://host/path.git') }
338
338
  let(:path_source) { source_list.add_path_source('path' => '/path/to/gem') }
339
339
 
340
- before do
341
- rubygems_source.stub(:cached!)
342
- git_source.stub(:cached!)
343
- path_source.stub(:cached!)
340
+ it "calls #cached! on all the sources" do
341
+ expect(rubygems_source).to receive(:cached!)
342
+ expect(git_source).to receive(:cached!)
343
+ expect(path_source).to receive(:cached!)
344
344
  source_list.cached!
345
345
  end
346
-
347
- it "calls #cached! on the included rubygems source" do
348
- expect(rubygems_source).to have_received(:cached!)
349
- end
350
-
351
- it "calls #cached! on the included git source" do
352
- expect(git_source).to have_received(:cached!)
353
- end
354
- it "calls #cached! on the included path source" do
355
- expect(path_source).to have_received(:cached!)
356
- end
357
346
  end
358
347
 
359
348
  describe "#remote!" do
@@ -361,22 +350,12 @@ describe Bundler::SourceList do
361
350
  let(:git_source) { source_list.add_git_source('uri' => 'git://host/path.git') }
362
351
  let(:path_source) { source_list.add_path_source('path' => '/path/to/gem') }
363
352
 
364
- before do
365
- rubygems_source.stub(:remote!)
366
- git_source.stub(:remote!)
367
- path_source.stub(:remote!)
353
+ it "calls #remote! on all the sources" do
354
+ expect(rubygems_source).to receive(:remote!)
355
+ expect(git_source).to receive(:remote!)
356
+ expect(path_source).to receive(:remote!)
368
357
  source_list.remote!
369
358
  end
370
-
371
- it "calls #remote! on the included rubygems source" do
372
- expect(rubygems_source).to have_received(:remote!)
373
- end
374
-
375
- it "calls #remote! on the included git source" do
376
- expect(git_source).to have_received(:remote!)
377
- end
378
- it "calls #remote! on the included path source" do
379
- expect(path_source).to have_received(:remote!)
380
- end
381
359
  end
360
+
382
361
  end
@@ -67,6 +67,18 @@ describe "install with --deployment or --frozen" do
67
67
  expect(exitstatus).to eq(0)
68
68
  end
69
69
 
70
+ it "works when there are credentials in the source URL" do
71
+ install_gemfile(<<-G, :artifice => "endpoint_strict_basic_authentication", :quiet => true)
72
+ source "http://user:pass@localgemserver.test/"
73
+
74
+ gem "rack-obama", ">= 1.0"
75
+ G
76
+
77
+ bundle "install --deployment", :exitstatus => true, :artifice => "endpoint_strict_basic_authentication"
78
+
79
+ expect(exitstatus).to eq(0)
80
+ end
81
+
70
82
  describe "with an existing lockfile" do
71
83
  before do
72
84
  bundle "install"
@@ -46,7 +46,7 @@ describe "The library itself" do
46
46
  actual.empty?
47
47
  end
48
48
 
49
- failure_message_for_should do |actual|
49
+ failure_message do |actual|
50
50
  actual.join("\n")
51
51
  end
52
52
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bundler
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.0
4
+ version: 1.7.1.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - André Arko
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2014-08-14 00:00:00.000000000 Z
14
+ date: 2014-08-16 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rdiscount
@@ -376,7 +376,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
376
376
  version: 1.3.6
377
377
  requirements: []
378
378
  rubyforge_project:
379
- rubygems_version: 2.2.2
379
+ rubygems_version: 2.4.1
380
380
  signing_key:
381
381
  specification_version: 4
382
382
  summary: The best way to manage your application's dependencies