bundler 1.1.rc.7 → 1.1.rc.8

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.

@@ -17,7 +17,6 @@ env:
17
17
  - RGV=v1.6.2
18
18
  - RGV=v1.7.2
19
19
  - RGV=v1.8.10
20
- - RGV=master
21
20
 
22
21
  matrix:
23
22
  exclude:
@@ -37,3 +36,4 @@ matrix:
37
36
  notifications:
38
37
  email:
39
38
  - travis-ci@andrearko.com
39
+ - hone02@gmail.com
@@ -1,3 +1,16 @@
1
+ ## 1.1.rc.8 (Jan 13, 2011)
2
+
3
+ Performance:
4
+
5
+ - don't resolve if the Gemfile.lock and Gemfile haven't changed
6
+
7
+ Bugfixes:
8
+
9
+ - Load gemspecs from git even when a released gem has the same version (#1609)
10
+ - Declare an accurate Ruby version requirement of 1.8.7 or newer (#1619)
11
+ - handle gemspec development dependencies correctly (@raggi, #1639)
12
+ - Avoid passing RUBYOPT changes in with_clean_env block. (eric1234, #1604)
13
+
1
14
  ## 1.1.rc.7 (Dec 29, 2011)
2
15
 
3
16
  Bugfixes:
data/Rakefile CHANGED
@@ -2,6 +2,8 @@
2
2
  $:.unshift File.expand_path("../lib", __FILE__)
3
3
  require 'bundler/gem_tasks'
4
4
 
5
+ task :release => ["man:clean", "man:build"]
6
+
5
7
  def safe_task(&block)
6
8
  yield
7
9
  true
@@ -14,6 +14,7 @@ Gem::Specification.new do |s|
14
14
  s.summary = %q{The best way to manage your application's dependencies}
15
15
  s.description = %q{Bundler manages an application's dependencies through its entire life, across many machines, systematically and repeatably}
16
16
 
17
+ s.required_ruby_version = ">= 1.8.7"
17
18
  s.required_rubygems_version = ">= 1.3.6"
18
19
  s.rubyforge_project = "bundler"
19
20
 
@@ -192,6 +192,10 @@ module Bundler
192
192
  def with_clean_env
193
193
  with_original_env do
194
194
  ENV.delete_if { |k,_| k[0,7] == 'BUNDLE_' }
195
+ if ENV.has_key? 'RUBYOPT'
196
+ ENV['RUBYOPT'] = ENV['RUBYOPT'].sub '-rbundler/setup', ''
197
+ ENV['RUBYOPT'] = ENV['RUBYOPT'].sub "-I#{File.expand_path('..', __FILE__)}", ''
198
+ end
195
199
  yield
196
200
  end
197
201
  end
@@ -1,4 +1,5 @@
1
1
  require "digest/sha1"
2
+ require "set"
2
3
 
3
4
  module Bundler
4
5
  class Definition
@@ -30,6 +31,8 @@ module Bundler
30
31
  =end
31
32
 
32
33
  def initialize(lockfile, dependencies, sources, unlock)
34
+ @unlocking = unlock == true || !unlock.empty?
35
+
33
36
  @dependencies, @sources, @unlock = dependencies, sources, unlock
34
37
  @remote = false
35
38
  @specs = nil
@@ -65,11 +68,45 @@ module Bundler
65
68
  @new_platform = !@platforms.include?(current_platform)
66
69
  @platforms |= [current_platform]
67
70
 
71
+ @path_changes = @sources.any? do |source|
72
+ next unless source.instance_of?(Source::Path)
73
+
74
+ locked = @locked_sources.find do |ls|
75
+ ls.class == source.class && ls.path == source.path
76
+ end
77
+
78
+ if locked
79
+ unlocking = locked.specs.any? do |spec|
80
+ @locked_specs.any? do |locked_spec|
81
+ locked_spec.source != locked
82
+ end
83
+ end
84
+ end
85
+
86
+ !locked || unlocking || source.specs != locked.specs
87
+ end
68
88
  eager_unlock = expand_dependencies(@unlock[:gems])
69
89
  @unlock[:gems] = @locked_specs.for(eager_unlock).map { |s| s.name }
70
90
 
71
- converge_sources
72
- converge_dependencies
91
+ @source_changes = converge_sources
92
+ @dependency_changes = converge_dependencies
93
+
94
+ fixup_dependency_types!
95
+ end
96
+
97
+ def fixup_dependency_types!
98
+ # XXX This is a temporary workaround for a bug when using rubygems 1.8.15
99
+ # where Gem::Dependency#== matches Gem::Dependency#type. As the lockfile
100
+ # doesn't carry a notion of the dependency type, if you use
101
+ # add_development_dependency in a gemspec that's loaded with the gemspec
102
+ # directive, the lockfile dependencies and resolved dependencies end up
103
+ # with a mismatch on #type.
104
+ # Test coverage to catch a regression on this is in gemspec_spec.rb
105
+ @dependencies.each do |d|
106
+ if ld = @locked_deps.find { |l| l.name == d.name }
107
+ ld.instance_variable_set(:@type, d.type)
108
+ end
109
+ end
73
110
  end
74
111
 
75
112
  def resolve_with_cache!
@@ -137,7 +174,7 @@ module Bundler
137
174
 
138
175
  def resolve
139
176
  @resolve ||= begin
140
- if Bundler.settings[:frozen]
177
+ if Bundler.settings[:frozen] || (!@unlocking && !@source_changes && !@dependency_changes && !@new_platform && !@path_changes)
141
178
  @locked_specs
142
179
  else
143
180
  last_resolve = converge_locked_specs
@@ -159,20 +196,18 @@ module Bundler
159
196
 
160
197
  def index
161
198
  @index ||= Index.build do |idx|
162
- other_sources = @sources.find_all{|s| !s.is_a?(Bundler::Source::Rubygems) }
163
- rubygems_sources = @sources.find_all{|s| s.is_a?(Bundler::Source::Rubygems) }
164
-
165
199
  dependency_names = @dependencies.dup || []
166
200
  dependency_names.map! {|d| d.name }
167
- other_sources.each do |s|
168
- source_index = s.specs
169
- dependency_names += source_index.unmet_dependency_names
170
- idx.add_source source_index
171
- end
172
201
 
173
- rubygems_sources.each do |s|
174
- s.dependency_names = dependency_names.uniq if s.is_a?(Bundler::Source::Rubygems)
175
- idx.add_source s.specs
202
+ @sources.each do |s|
203
+ if s.is_a?(Bundler::Source::Rubygems)
204
+ s.dependency_names = dependency_names.uniq
205
+ idx.add_source s.specs
206
+ else
207
+ source_index = s.specs
208
+ dependency_names += source_index.unmet_dependency_names
209
+ idx.add_source source_index
210
+ end
176
211
  end
177
212
  end
178
213
  end
@@ -325,20 +360,41 @@ module Bundler
325
360
  end
326
361
 
327
362
  def converge_sources
363
+ changes = false
364
+
365
+ # Get the Rubygems source from the Gemfile.lock
328
366
  locked_gem = @locked_sources.find { |s| Source::Rubygems === s }
367
+
368
+ # Get the Rubygems source from the Gemfile
329
369
  actual_gem = @sources.find { |s| Source::Rubygems === s }
330
370
 
371
+ # If there is a Rubygems source in both
331
372
  if locked_gem && actual_gem
332
- locked_gem.merge_remotes actual_gem
373
+ # Merge the remotes from the Gemfile into the Gemfile.lock
374
+ changes = changes | locked_gem.replace_remotes(actual_gem)
333
375
  end
334
376
 
377
+ # Replace the sources from the Gemfile with the sources from the Gemfile.lock,
378
+ # if they exist in the Gemfile.lock and are `==`. If you can't find an equivalent
379
+ # source in the Gemfile.lock, use the one from the Gemfile.
335
380
  @sources.map! do |source|
336
381
  @locked_sources.find { |s| s == source } || source
337
382
  end
383
+ changes = changes | (Set.new(@sources) != Set.new(@locked_sources))
338
384
 
339
385
  @sources.each do |source|
340
- source.unlock! if source.respond_to?(:unlock!) && @unlock[:sources].include?(source.name)
386
+ # If the source is unlockable and the current command allows an unlock of
387
+ # the source (for example, you are doing a `bundle update <foo>` of a git-pinned
388
+ # gem), unlock it. For git sources, this means to unlock the revision, which
389
+ # will cause the `ref` used to be the most recent for the branch (or master) if
390
+ # an explicit `ref` is not used.
391
+ if source.respond_to?(:unlock!) && @unlock[:sources].include?(source.name)
392
+ source.unlock!
393
+ changes = true
394
+ end
341
395
  end
396
+
397
+ changes
342
398
  end
343
399
 
344
400
  def converge_dependencies
@@ -347,6 +403,7 @@ module Bundler
347
403
  dep.source = @sources.find { |s| dep.source == s }
348
404
  end
349
405
  end
406
+ Set.new(@dependencies) != Set.new(@locked_deps)
350
407
  end
351
408
 
352
409
  # Remove elements from the locked specs that are expired. This will most
@@ -133,8 +133,10 @@ module Bundler
133
133
  begin
134
134
  Bundler.ui.debug "Fetching from: #{uri}"
135
135
  response = @@connection.request(uri)
136
- rescue SocketError, Timeout::Error, Net::HTTP::Persistent::Error
137
- raise Bundler::HTTPError, "Network error while fetching #{uri}"
136
+ rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
137
+ SocketError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
138
+ Net::HTTP::Persistent::Error, Net::ProtocolError => e
139
+ raise HTTPError, "Network error while fetching #{uri}"
138
140
  end
139
141
 
140
142
  case response
@@ -1,3 +1,5 @@
1
+ require "set"
2
+
1
3
  module Bundler
2
4
  class Index
3
5
  include Enumerable
@@ -41,9 +43,15 @@ module Bundler
41
43
  # about, returning all of the results.
42
44
  def search(query, base = nil)
43
45
  results = local_search(query, base)
46
+ seen = Set.new(results.map { |spec| [spec.name, spec.version, spec.platform] })
47
+
44
48
  @sources.each do |source|
45
- results += source.search(query, base)
49
+ source.search(query, base).each do |spec|
50
+ results << spec unless seen.include?([spec.name, spec.version, spec.platform])
51
+ seen << [spec.name, spec.version, spec.platform]
52
+ end
46
53
  end
54
+
47
55
  results
48
56
  end
49
57
 
@@ -109,8 +117,9 @@ module Bundler
109
117
  end
110
118
 
111
119
  def ==(o)
112
- all? do |s|
113
- s2 = o[s].first and (s.dependencies & s2.dependencies).empty?
120
+ all? do |spec|
121
+ other_spec = o[spec].first
122
+ (spec.dependencies & other_spec.dependencies).empty? && spec.source == other_spec.source
114
123
  end
115
124
  end
116
125
 
@@ -342,13 +342,14 @@ module Bundler
342
342
  length = @stack.length
343
343
  @stack << requirement.name
344
344
  retval = catch(requirement.name) do
345
- # clear the search cache since the catch means we couldn't meet the
346
- # requirement we need with the current constraints on search
347
- clear_search_cache
348
345
  # try to resolve the next option
349
346
  resolve(reqs, activated)
350
347
  end
351
348
 
349
+ # clear the search cache since the catch means we couldn't meet the
350
+ # requirement we need with the current constraints on search
351
+ clear_search_cache
352
+
352
353
  # Since we're doing a lot of throw / catches. A push does not necessarily match
353
354
  # up to a pop. So, we simply slice the stack back to what it was before the catch
354
355
  # block.
@@ -127,11 +127,15 @@ module Bundler
127
127
  @remotes << normalize_uri(source)
128
128
  end
129
129
 
130
- def merge_remotes(source)
130
+ def replace_remotes(source)
131
+ return false if source.remotes == @remotes
132
+
131
133
  @remotes = []
132
134
  source.remotes.each do |r|
133
135
  add_remote r.to_s
134
136
  end
137
+
138
+ true
135
139
  end
136
140
 
137
141
  private
@@ -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.1.rc.7" unless defined?(::Bundler::VERSION)
5
+ VERSION = "1.1.rc.8" unless defined?(::Bundler::VERSION)
6
6
  end
@@ -110,6 +110,27 @@ describe "bundle install from an existing gemspec" do
110
110
  should_be_installed "bar-dev 1.0.0", :groups => :dev
111
111
  end
112
112
 
113
+ it "should match a lockfile even if the gemspec defines development dependencies" do
114
+ build_lib("foo", :path => tmp.join("foo")) do |s|
115
+ s.write("Gemfile", "source 'file://#{gem_repo1}'\ngemspec")
116
+ s.add_dependency "actionpack", "=2.3.2"
117
+ s.add_development_dependency "rake", '=0.8.7'
118
+ end
119
+
120
+ Dir.chdir(tmp.join("foo")) do
121
+ bundle "install"
122
+ # This should really be able to rely on $stderr, but, it's not written
123
+ # right, so we can't. In fact, this is a bug negation test, and so it'll
124
+ # ghost pass in future, and will only catch a regression if the message
125
+ # doesn't change. Exit codes should be used correctly (they can be more
126
+ # than just 0 and 1).
127
+ output = bundle("install --deployment")
128
+ output.should_not match(/You have added to the Gemfile/)
129
+ output.should_not match(/You have deleted from the Gemfile/)
130
+ output.should_not match(/install in deployment mode after changing/)
131
+ end
132
+ end
133
+
113
134
  it "should evaluate the gemspec in its directory" do
114
135
  build_lib("foo", :path => tmp.join("foo"))
115
136
  File.open(tmp.join("foo/foo.gemspec"), "w") do |s|
@@ -122,4 +143,28 @@ describe "bundle install from an existing gemspec" do
122
143
  @err.should_not match(/ahh/)
123
144
  end
124
145
 
146
+ context "when child gemspecs conflict with a released gemspec" do
147
+ before do
148
+ # build the "parent" gem that depends on another gem in the same repo
149
+ build_lib "source_conflict", :path => bundled_app do |s|
150
+ s.add_dependency "rack_middleware"
151
+ end
152
+
153
+ # build the "child" gem that is the same version as a released gem, but
154
+ # has completely different and conflicting dependency requirements
155
+ build_lib "rack_middleware", "1.0", :path => bundled_app("rack_middleware") do |s|
156
+ s.add_dependency "rack", "1.0" # anything other than 0.9.1
157
+ end
158
+ end
159
+
160
+ it "should install the child gemspec's deps" do
161
+ install_gemfile <<-G
162
+ source "file://#{gem_repo1}"
163
+ gemspec
164
+ G
165
+
166
+ should_be_installed "rack 1.0"
167
+ end
168
+ end
169
+
125
170
  end
@@ -15,10 +15,10 @@ describe "Bundler.with_env helpers" do
15
15
  end
16
16
 
17
17
  around do |example|
18
- bundle_path = Bundler::ORIGINAL_ENV['BUNDLE_PATH']
18
+ env = Bundler::ORIGINAL_ENV.dup
19
19
  Bundler::ORIGINAL_ENV['BUNDLE_PATH'] = "./Gemfile"
20
20
  example.run
21
- Bundler::ORIGINAL_ENV['BUNDLE_PATH'] = bundle_path
21
+ Bundler::ORIGINAL_ENV.replace env
22
22
  end
23
23
 
24
24
  describe "Bundler.with_clean_env" do
@@ -31,6 +31,18 @@ describe "Bundler.with_env helpers" do
31
31
  end
32
32
  end
33
33
 
34
+ it "should not pass RUBYOPT changes" do
35
+ lib_path = File.expand_path('../../../lib', __FILE__)
36
+ Bundler::ORIGINAL_ENV['RUBYOPT'] = " -I#{lib_path} -rbundler/setup"
37
+
38
+ Bundler.with_clean_env do
39
+ `echo $RUBYOPT`.strip.should_not include '-rbundler/setup'
40
+ `echo $RUBYOPT`.strip.should_not include "-I#{lib_path}"
41
+ end
42
+
43
+ Bundler::ORIGINAL_ENV['RUBYOPT'].should == " -I#{lib_path} -rbundler/setup"
44
+ end
45
+
34
46
  it "should not change ORIGINAL_ENV" do
35
47
  Bundler::ORIGINAL_ENV['BUNDLE_PATH'].should == './Gemfile'
36
48
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bundler
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15424243
5
- prerelease: true
4
+ hash: 15424237
5
+ prerelease: 4
6
6
  segments:
7
7
  - 1
8
8
  - 1
9
9
  - rc
10
- - 7
11
- version: 1.1.rc.7
10
+ - 8
11
+ version: 1.1.rc.8
12
12
  platform: ruby
13
13
  authors:
14
14
  - "Andr\xC3\xA9 Arko"
@@ -19,8 +19,7 @@ autorequire:
19
19
  bindir: bin
20
20
  cert_chain: []
21
21
 
22
- date: 2011-12-29 00:00:00 -05:00
23
- default_executable:
22
+ date: 2012-03-03 00:00:00 Z
24
23
  dependencies:
25
24
  - !ruby/object:Gem::Dependency
26
25
  name: ronn
@@ -249,7 +248,6 @@ files:
249
248
  - lib/bundler/man/bundle.txt
250
249
  - lib/bundler/man/bundle-package.txt
251
250
  - lib/bundler/man/bundle-install.txt
252
- has_rdoc: true
253
251
  homepage: http://gembundler.com
254
252
  licenses: []
255
253
 
@@ -263,10 +261,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
263
261
  requirements:
264
262
  - - ">="
265
263
  - !ruby/object:Gem::Version
266
- hash: 3
264
+ hash: 57
267
265
  segments:
268
- - 0
269
- version: "0"
266
+ - 1
267
+ - 8
268
+ - 7
269
+ version: 1.8.7
270
270
  required_rubygems_version: !ruby/object:Gem::Requirement
271
271
  none: false
272
272
  requirements:
@@ -281,7 +281,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
281
281
  requirements: []
282
282
 
283
283
  rubyforge_project: bundler
284
- rubygems_version: 1.3.7
284
+ rubygems_version: 1.8.11
285
285
  signing_key:
286
286
  specification_version: 3
287
287
  summary: The best way to manage your application's dependencies