bundler 1.1.pre.4 → 1.1.pre.5
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.
- data/.travis.yml +1 -0
- data/CHANGELOG.md +51 -2
- data/ISSUES.md +25 -11
- data/README.md +3 -3
- data/Rakefile +44 -48
- data/lib/bundler.rb +21 -20
- data/lib/bundler/cli.rb +46 -11
- data/lib/bundler/definition.rb +6 -4
- data/lib/bundler/dependency.rb +5 -0
- data/lib/bundler/dsl.rb +1 -7
- data/lib/bundler/endpoint_specification.rb +22 -0
- data/lib/bundler/fetcher.rb +76 -22
- data/lib/bundler/gem_helper.rb +2 -7
- data/lib/bundler/gem_tasks.rb +2 -0
- data/lib/bundler/index.rb +48 -41
- data/lib/bundler/installer.rb +5 -0
- data/lib/bundler/lazy_specification.rb +7 -6
- data/lib/bundler/resolver.rb +1 -1
- data/lib/bundler/rubygems_ext.rb +1 -1
- data/lib/bundler/rubygems_integration.rb +69 -31
- data/lib/bundler/runtime.rb +2 -2
- data/lib/bundler/setup.rb +3 -0
- data/lib/bundler/shared_helpers.rb +2 -2
- data/lib/bundler/source.rb +48 -46
- data/lib/bundler/spec_set.rb +1 -0
- data/lib/bundler/templates/newgem/Gemfile.tt +1 -1
- data/lib/bundler/templates/newgem/Rakefile.tt +2 -2
- data/lib/bundler/templates/newgem/bin/newgem.tt +1 -1
- data/lib/bundler/templates/newgem/gitignore.tt +14 -1
- data/lib/bundler/templates/newgem/lib/newgem.rb.tt +2 -0
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +13 -17
- data/lib/bundler/ui.rb +29 -15
- data/lib/bundler/vendor/net/http/persistent.rb +4 -0
- data/lib/bundler/vendored_thor.rb +7 -0
- data/lib/bundler/version.rb +1 -1
- data/man/bundle-install.ronn +7 -0
- data/man/bundle.ronn +6 -0
- data/man/gemfile.5.ronn +2 -0
- data/spec/cache/gems_spec.rb +11 -0
- data/spec/install/deploy_spec.rb +1 -1
- data/spec/install/gems/dependency_api_spec.rb +62 -7
- data/spec/install/gems/groups_spec.rb +3 -3
- data/spec/install/gems/post_install_spec.rb +47 -0
- data/spec/install/gems/sudo_spec.rb +3 -2
- data/spec/install/git_spec.rb +1 -2
- data/spec/install/path_spec.rb +1 -1
- data/spec/lock/lockfile_spec.rb +1 -1
- data/spec/other/check_spec.rb +30 -6
- data/spec/other/exec_spec.rb +4 -33
- data/spec/other/init_spec.rb +3 -3
- data/spec/other/newgem_spec.rb +5 -1
- data/spec/other/outdated_spec.rb +36 -6
- data/spec/quality_spec.rb +5 -1
- data/spec/runtime/require_spec.rb +10 -10
- data/spec/runtime/setup_spec.rb +31 -8
- data/spec/spec_helper.rb +1 -5
- data/spec/support/artifice/endpoint.rb +4 -0
- data/spec/support/artifice/endpoint_basic_authentication.rb +13 -0
- data/spec/support/artifice/endpoint_fallback.rb +0 -4
- data/spec/support/artifice/endpoint_redirect.rb +4 -0
- data/spec/support/builders.rb +6 -1
- data/spec/support/matchers.rb +1 -1
- data/spec/support/rubygems_ext.rb +4 -3
- data/spec/update/git_spec.rb +2 -2
- metadata +55 -143
@@ -46,7 +46,7 @@ module Bundler
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def gem_dir
|
49
|
-
Gem.dir
|
49
|
+
Gem.dir
|
50
50
|
end
|
51
51
|
|
52
52
|
def gem_bindir
|
@@ -58,9 +58,7 @@ module Bundler
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def gem_path
|
61
|
-
|
62
|
-
# internal Rubygems object
|
63
|
-
Gem.path.map { |x| x.to_s }
|
61
|
+
Gem.path
|
64
62
|
end
|
65
63
|
|
66
64
|
def marshal_spec_dir
|
@@ -75,6 +73,11 @@ module Bundler
|
|
75
73
|
Gem.bin_path(gem, bin, ver)
|
76
74
|
end
|
77
75
|
|
76
|
+
def preserve_paths
|
77
|
+
# this is a no-op outside of Rubygems 1.8
|
78
|
+
yield
|
79
|
+
end
|
80
|
+
|
78
81
|
def ui=(obj)
|
79
82
|
Gem::DefaultUserInteraction.ui = obj
|
80
83
|
end
|
@@ -120,7 +123,7 @@ module Bundler
|
|
120
123
|
if executables.include? File.basename(caller.first.split(':').first)
|
121
124
|
return
|
122
125
|
end
|
123
|
-
|
126
|
+
reqs.pop if reqs.last.is_a?(Hash)
|
124
127
|
|
125
128
|
unless dep.respond_to?(:name) && dep.respond_to?(:requirement)
|
126
129
|
dep = Gem::Dependency.new(dep, reqs)
|
@@ -154,6 +157,16 @@ module Bundler
|
|
154
157
|
end
|
155
158
|
end
|
156
159
|
|
160
|
+
if defined? ::Deprecate
|
161
|
+
Deprecate = ::Deprecate
|
162
|
+
elsif defined? Gem::Deprecate
|
163
|
+
Deprecate = Gem::Deprecate
|
164
|
+
else
|
165
|
+
class Deprecate
|
166
|
+
def skip_during; yield; end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
157
170
|
def stub_source_index137(specs)
|
158
171
|
# Rubygems versions lower than 1.7 use SourceIndex#from_gems_in
|
159
172
|
source_index_class = (class << Gem::SourceIndex ; self ; end)
|
@@ -169,8 +182,19 @@ module Bundler
|
|
169
182
|
def stub_source_index170(specs)
|
170
183
|
Gem::SourceIndex.send(:define_method, :initialize) do |*args|
|
171
184
|
@gems = {}
|
172
|
-
|
173
|
-
|
185
|
+
# You're looking at this thinking: Oh! This is how I make those
|
186
|
+
# rubygems deprecations go away!
|
187
|
+
#
|
188
|
+
# You'd be correct BUT using of this method in production code
|
189
|
+
# must be approved by the rubygems team itself!
|
190
|
+
#
|
191
|
+
# This is your warning. If you use this and don't have approval
|
192
|
+
# we can't protect you.
|
193
|
+
#
|
194
|
+
Deprecate.skip_during do
|
195
|
+
self.spec_dirs = *args
|
196
|
+
add_specs(*specs)
|
197
|
+
end
|
174
198
|
end
|
175
199
|
end
|
176
200
|
|
@@ -226,56 +250,70 @@ module Bundler
|
|
226
250
|
Gem.clear_paths
|
227
251
|
end
|
228
252
|
|
229
|
-
|
253
|
+
# Rubygems versions 1.3.6 through 1.6.2
|
254
|
+
class Legacy < RubygemsIntegration
|
230
255
|
def stub_rubygems(specs)
|
231
|
-
|
232
|
-
|
233
|
-
Gem.post_reset {
|
234
|
-
Gem::Specification.all = specs
|
235
|
-
}
|
236
|
-
|
237
|
-
stub_source_index170(specs)
|
256
|
+
stub_source_index137(specs)
|
238
257
|
end
|
239
258
|
|
240
259
|
def all_specs
|
241
|
-
Gem
|
260
|
+
Gem.source_index.gems.values
|
242
261
|
end
|
243
262
|
|
244
263
|
def find_name(name)
|
245
|
-
Gem
|
264
|
+
Gem.source_index.find_name(name)
|
246
265
|
end
|
266
|
+
end
|
247
267
|
|
268
|
+
# Rubygems 1.7
|
269
|
+
class Transitional < Legacy
|
270
|
+
def stub_rubygems(specs)
|
271
|
+
stub_source_index170(specs)
|
272
|
+
end
|
248
273
|
end
|
249
274
|
|
250
|
-
|
275
|
+
# Rubygems 1.8.5
|
276
|
+
class Modern < RubygemsIntegration
|
251
277
|
def stub_rubygems(specs)
|
252
|
-
|
278
|
+
Gem::Specification.all = specs
|
279
|
+
|
280
|
+
Gem.post_reset {
|
281
|
+
Gem::Specification.all = specs
|
282
|
+
}
|
283
|
+
|
284
|
+
stub_source_index170(specs)
|
253
285
|
end
|
254
286
|
|
255
287
|
def all_specs
|
256
|
-
Gem.
|
288
|
+
Gem::Specification.to_a
|
257
289
|
end
|
258
290
|
|
259
291
|
def find_name(name)
|
260
|
-
Gem.
|
292
|
+
Gem::Specification.find_all_by_name name
|
261
293
|
end
|
262
294
|
end
|
263
295
|
|
264
|
-
|
265
|
-
|
266
|
-
|
296
|
+
# Rubygems 1.8.0 to 1.8.4
|
297
|
+
class AlmostModern < Modern
|
298
|
+
# Rubygems [>= 1.8.0, < 1.8.5] has a bug that changes Gem.dir whenever
|
299
|
+
# you call Gem::Installer#install with an :install_dir set. We have to
|
300
|
+
# change it back for our sudo mode to work.
|
301
|
+
def preserve_paths
|
302
|
+
old_dir, old_path = gem_dir, gem_path
|
303
|
+
yield
|
304
|
+
Gem.use_paths(old_dir, old_path)
|
267
305
|
end
|
268
306
|
end
|
269
307
|
|
270
308
|
end
|
271
309
|
|
272
|
-
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
else
|
310
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.8.5')
|
311
|
+
@rubygems = RubygemsIntegration::Modern.new
|
312
|
+
elsif Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.8.0')
|
313
|
+
@rubygems = RubygemsIntegration::AlmostModern.new
|
314
|
+
elsif Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.7.0')
|
315
|
+
@rubygems = RubygemsIntegration::Transitional.new
|
316
|
+
else # Rubygems 1.3.6 through 1.6.2
|
279
317
|
@rubygems = RubygemsIntegration::Legacy.new
|
280
318
|
end
|
281
319
|
|
data/lib/bundler/runtime.rb
CHANGED
@@ -85,7 +85,7 @@ module Bundler
|
|
85
85
|
alias gems specs
|
86
86
|
|
87
87
|
def cache
|
88
|
-
FileUtils.mkdir_p(cache_path)
|
88
|
+
FileUtils.mkdir_p(cache_path) unless File.exists?(cache_path)
|
89
89
|
|
90
90
|
Bundler.ui.info "Updating .gem files in vendor/cache"
|
91
91
|
specs.each do |spec|
|
@@ -96,7 +96,7 @@ module Bundler
|
|
96
96
|
end
|
97
97
|
|
98
98
|
def prune_cache
|
99
|
-
FileUtils.mkdir_p(cache_path)
|
99
|
+
FileUtils.mkdir_p(cache_path) unless File.exists?(cache_path)
|
100
100
|
|
101
101
|
resolve = @definition.resolve
|
102
102
|
cached = Dir["#{cache_path}/*.gem"]
|
data/lib/bundler/setup.rb
CHANGED
@@ -8,6 +8,9 @@ if Bundler::SharedHelpers.in_bundle?
|
|
8
8
|
rescue Bundler::BundlerError => e
|
9
9
|
puts "\e[31m#{e.message}\e[0m"
|
10
10
|
puts e.backtrace.join("\n") if ENV["DEBUG"]
|
11
|
+
if Bundler::GemNotFound === e
|
12
|
+
puts "\e[33mRun `bundle install` to install missing gems.\e[0m"
|
13
|
+
end
|
11
14
|
exit e.status_code
|
12
15
|
end
|
13
16
|
else
|
@@ -58,9 +58,9 @@ module Bundler
|
|
58
58
|
if defined?(::Gem)
|
59
59
|
me = File.expand_path("../../", __FILE__)
|
60
60
|
$LOAD_PATH.reject! do |p|
|
61
|
-
next if File.expand_path(p) =~ /^#{me}/
|
61
|
+
next if File.expand_path(p) =~ /^#{Regexp.escape(me)}/
|
62
62
|
p != File.dirname(__FILE__) &&
|
63
|
-
Bundler.rubygems.gem_path.any?{|gp| p =~ /^#{gp}/ }
|
63
|
+
Bundler.rubygems.gem_path.any?{|gp| p =~ /^#{Regexp.escape(gp)}/ }
|
64
64
|
end
|
65
65
|
$LOAD_PATH.uniq!
|
66
66
|
end
|
data/lib/bundler/source.rb
CHANGED
@@ -11,6 +11,7 @@ module Bundler
|
|
11
11
|
# TODO: Refactor this class
|
12
12
|
class Rubygems
|
13
13
|
attr_reader :remotes, :caches
|
14
|
+
attr_accessor :dependencies
|
14
15
|
|
15
16
|
def initialize(options = {})
|
16
17
|
@options = options
|
@@ -65,8 +66,8 @@ module Bundler
|
|
65
66
|
end
|
66
67
|
alias_method :name, :to_s
|
67
68
|
|
68
|
-
def specs
|
69
|
-
@specs ||= fetch_specs
|
69
|
+
def specs
|
70
|
+
@specs ||= fetch_specs
|
70
71
|
end
|
71
72
|
|
72
73
|
def fetch(spec)
|
@@ -74,41 +75,35 @@ module Bundler
|
|
74
75
|
if spec
|
75
76
|
path = download_gem_from_uri(spec, uri)
|
76
77
|
s = Bundler.rubygems.spec_from_gem(path)
|
77
|
-
spec.__swap__(s)
|
78
|
+
spec.__swap__(s) if spec.is_a?(RemoteSpecification)
|
78
79
|
end
|
79
80
|
end
|
80
81
|
|
81
|
-
def outdated(spec)
|
82
|
-
installed_spec = installed_specs[spec.name]
|
83
|
-
installed_spec = installed_spec.first
|
84
|
-
|
85
|
-
if installed_spec && spec.version == installed_spec.version
|
86
|
-
Bundler.ui.debug "Up to date: #{spec.name} (#{installed_spec.version}) "
|
87
|
-
return
|
88
|
-
end
|
89
|
-
|
90
|
-
Bundler.ui.info "#{spec.name} (#{spec.version} > #{installed_spec.version}) "
|
91
|
-
end
|
92
|
-
|
93
82
|
def install(spec)
|
94
|
-
path = cached_gem(spec)
|
95
|
-
|
96
83
|
if installed_specs[spec].any?
|
97
84
|
Bundler.ui.info "Using #{spec.name} (#{spec.version}) "
|
98
85
|
return
|
99
86
|
end
|
100
87
|
|
101
88
|
Bundler.ui.info "Installing #{spec.name} (#{spec.version}) "
|
89
|
+
path = cached_gem(spec)
|
90
|
+
|
91
|
+
Bundler.rubygems.preserve_paths do
|
92
|
+
|
93
|
+
install_path = Bundler.requires_sudo? ? Bundler.tmp : Bundler.rubygems.gem_dir
|
94
|
+
options = { :install_dir => install_path,
|
95
|
+
:ignore_dependencies => true,
|
96
|
+
:wrappers => true,
|
97
|
+
:env_shebang => true }
|
98
|
+
options.merge!(:bin_dir => "#{install_path}/bin") unless spec.executables.nil? || spec.executables.empty?
|
102
99
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
:wrappers => true,
|
107
|
-
:env_shebang => true }
|
108
|
-
options.merge!(:bin_dir => "#{install_path}/bin") unless spec.executables.nil? || spec.executables.empty?
|
100
|
+
installer = Gem::Installer.new path, options
|
101
|
+
installer.install
|
102
|
+
end
|
109
103
|
|
110
|
-
|
111
|
-
|
104
|
+
if spec.post_install_message
|
105
|
+
Installer.post_install_messages[spec.name] = spec.post_install_message
|
106
|
+
end
|
112
107
|
|
113
108
|
# SUDO HAX
|
114
109
|
if Bundler.requires_sudo?
|
@@ -151,7 +146,11 @@ module Bundler
|
|
151
146
|
|
152
147
|
def cached_gem(spec)
|
153
148
|
possibilities = @caches.map { |p| "#{p}/#{spec.file_name}" }
|
154
|
-
possibilities.find { |p| File.exist?(p) }
|
149
|
+
cached_gem = possibilities.find { |p| File.exist?(p) }
|
150
|
+
unless cached_gem
|
151
|
+
raise Bundler::GemNotFound, "Could not find #{spec.file_name} for installation"
|
152
|
+
end
|
153
|
+
cached_gem
|
155
154
|
end
|
156
155
|
|
157
156
|
def normalize_uri(uri)
|
@@ -162,11 +161,11 @@ module Bundler
|
|
162
161
|
uri
|
163
162
|
end
|
164
163
|
|
165
|
-
def fetch_specs
|
164
|
+
def fetch_specs
|
166
165
|
Index.build do |idx|
|
167
166
|
idx.use installed_specs
|
168
167
|
idx.use cached_specs if @allow_cached || @allow_remote
|
169
|
-
idx.use remote_specs
|
168
|
+
idx.use remote_specs if @allow_remote
|
170
169
|
end
|
171
170
|
end
|
172
171
|
|
@@ -206,7 +205,7 @@ module Bundler
|
|
206
205
|
|
207
206
|
path = Bundler.app_cache
|
208
207
|
Dir["#{path}/*.gem"].each do |gemfile|
|
209
|
-
next if gemfile =~
|
208
|
+
next if gemfile =~ /^bundler\-[\d\.]+?\.gem/
|
210
209
|
|
211
210
|
begin
|
212
211
|
s ||= Bundler.rubygems.spec_from_gem(gemfile)
|
@@ -222,28 +221,17 @@ module Bundler
|
|
222
221
|
idx
|
223
222
|
end
|
224
223
|
|
225
|
-
def remote_specs
|
224
|
+
def remote_specs
|
226
225
|
@remote_specs ||= begin
|
227
226
|
idx = Index.new
|
228
227
|
old = Bundler.rubygems.sources
|
229
228
|
|
230
229
|
remotes.each do |uri|
|
231
|
-
Bundler.ui.info "Fetching source index for #{uri}"
|
232
230
|
|
233
231
|
@fetchers[uri] = Bundler::Fetcher.new(uri)
|
234
|
-
gem_names =
|
235
|
-
|
236
|
-
|
237
|
-
end
|
238
|
-
@fetchers[uri].fetch_remote_specs(gem_names) do |n,v|
|
239
|
-
v.each do |name, version, platform|
|
240
|
-
next if name == 'bundler'
|
241
|
-
spec = RemoteSpecification.new(name, version, platform, @fetchers[uri])
|
242
|
-
spec.source = self
|
243
|
-
@spec_fetch_map[spec.full_name] = [spec, uri]
|
244
|
-
idx << spec
|
245
|
-
end
|
246
|
-
end
|
232
|
+
gem_names = dependencies && dependencies.map{|d| d.name }
|
233
|
+
|
234
|
+
idx.use @fetchers[uri].specs(gem_names, self, @spec_fetch_map)
|
247
235
|
end
|
248
236
|
idx
|
249
237
|
ensure
|
@@ -603,6 +591,19 @@ module Bundler
|
|
603
591
|
Digest::SHA1.hexdigest(input)
|
604
592
|
end
|
605
593
|
|
594
|
+
# Escape the URI for git commands
|
595
|
+
def uri_escaped
|
596
|
+
if Bundler::WINDOWS
|
597
|
+
# Windows quoting requires double quotes only, with double quotes
|
598
|
+
# inside the string escaped by being doubled.
|
599
|
+
'"' + uri.gsub('"') {|s| '""'} + '"'
|
600
|
+
else
|
601
|
+
# Bash requires single quoted strings, with the single quotes escaped
|
602
|
+
# by ending the string, escaping the quote, and restarting the string.
|
603
|
+
"'" + uri.gsub("'") {|s| "'\\''"} + "'"
|
604
|
+
end
|
605
|
+
end
|
606
|
+
|
606
607
|
def cache_path
|
607
608
|
@cache_path ||= begin
|
608
609
|
git_scope = "#{base_name}-#{uri_hash}"
|
@@ -620,12 +621,12 @@ module Bundler
|
|
620
621
|
return if has_revision_cached?
|
621
622
|
Bundler.ui.info "Updating #{uri}"
|
622
623
|
in_cache do
|
623
|
-
git %|fetch --force --quiet --tags
|
624
|
+
git %|fetch --force --quiet --tags #{uri_escaped} "refs/heads/*:refs/heads/*"|
|
624
625
|
end
|
625
626
|
else
|
626
627
|
Bundler.ui.info "Fetching #{uri}"
|
627
628
|
FileUtils.mkdir_p(cache_path.dirname)
|
628
|
-
git %|clone
|
629
|
+
git %|clone #{uri_escaped} "#{cache_path}" --bare --no-hardlinks|
|
629
630
|
end
|
630
631
|
end
|
631
632
|
|
@@ -634,6 +635,7 @@ module Bundler
|
|
634
635
|
FileUtils.mkdir_p(path.dirname)
|
635
636
|
FileUtils.rm_rf(path)
|
636
637
|
git %|clone --no-checkout "#{cache_path}" "#{path}"|
|
638
|
+
File.chmod((0777 & ~File.umask), path)
|
637
639
|
end
|
638
640
|
Dir.chdir(path) do
|
639
641
|
git %|fetch --force --quiet --tags "#{cache_path}"|
|
data/lib/bundler/spec_set.rb
CHANGED
@@ -80,6 +80,7 @@ module Bundler
|
|
80
80
|
materialized = self.for(deps, [], false, true).to_a
|
81
81
|
materialized.map! do |s|
|
82
82
|
next s unless s.is_a?(LazySpecification)
|
83
|
+
s.source.dependencies = deps if s.source.respond_to?(:dependencies=)
|
83
84
|
spec = s.__materialize__
|
84
85
|
if missing_specs
|
85
86
|
missing_specs << s unless spec
|
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require 'bundler/gem_tasks'
|