bundler 1.1.pre.1 → 1.1.pre.2
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/CHANGELOG.md +46 -0
- data/Rakefile +20 -3
- data/bin/bundle +5 -0
- data/bundler.gemspec +3 -4
- data/lib/bundler.rb +11 -8
- data/lib/bundler/capistrano.rb +1 -1
- data/lib/bundler/cli.rb +12 -7
- data/lib/bundler/definition.rb +19 -6
- data/lib/bundler/dependency.rb +2 -1
- data/lib/bundler/dsl.rb +14 -10
- data/lib/bundler/index.rb +23 -12
- data/lib/bundler/installer.rb +10 -9
- data/lib/bundler/lazy_specification.rb +1 -1
- data/lib/bundler/resolver.rb +1 -1
- data/lib/bundler/rubygems_ext.rb +4 -17
- data/lib/bundler/rubygems_integration.rb +301 -0
- data/lib/bundler/runtime.rb +5 -5
- data/lib/bundler/settings.rb +3 -3
- data/lib/bundler/shared_helpers.rb +5 -99
- data/lib/bundler/source.rb +31 -27
- data/lib/bundler/version.rb +1 -1
- data/man/bundle-install.ronn +3 -0
- data/spec/install/deploy_spec.rb +7 -7
- data/spec/install/git_spec.rb +1 -1
- data/spec/install/invalid_spec.rb +18 -0
- data/spec/install/path_spec.rb +52 -0
- data/spec/lock/git_spec.rb +1 -1
- data/spec/lock/lockfile_spec.rb +23 -0
- data/spec/other/exec_spec.rb +2 -1
- data/spec/other/ext_spec.rb +21 -0
- data/spec/runtime/setup_spec.rb +2 -2
- data/spec/support/builders.rb +6 -0
- data/spec/support/matchers.rb +3 -15
- metadata +12 -13
data/lib/bundler/installer.rb
CHANGED
@@ -10,8 +10,16 @@ module Bundler
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def run(options)
|
13
|
+
# Create the BUNDLE_PATH directory
|
14
|
+
begin
|
15
|
+
Bundler.bundle_path.mkpath unless Bundler.bundle_path.exist?
|
16
|
+
rescue Errno::EEXIST
|
17
|
+
raise PathError, "Could not install to path `#{Bundler.settings[:path]}` " +
|
18
|
+
"because of an invalid symlink. Remove the symlink so the directory can be created."
|
19
|
+
end
|
20
|
+
|
13
21
|
if Bundler.settings[:frozen]
|
14
|
-
@definition.ensure_equivalent_gemfile_and_lockfile
|
22
|
+
@definition.ensure_equivalent_gemfile_and_lockfile(options[:deployment])
|
15
23
|
end
|
16
24
|
|
17
25
|
if dependencies.empty?
|
@@ -35,9 +43,6 @@ module Bundler
|
|
35
43
|
@definition.resolve_remotely!
|
36
44
|
end
|
37
45
|
|
38
|
-
# Ensure that BUNDLE_PATH exists
|
39
|
-
Bundler.mkdir_p(Bundler.bundle_path) unless File.exist?(Bundler.bundle_path)
|
40
|
-
|
41
46
|
# Must install gems in the order that the resolver provides
|
42
47
|
# as dependencies might actually affect the installation of
|
43
48
|
# the gem.
|
@@ -49,13 +54,9 @@ module Bundler
|
|
49
54
|
# next
|
50
55
|
# end
|
51
56
|
|
52
|
-
|
53
|
-
old_args = Gem::Command.build_args
|
54
|
-
Gem::Command.build_args = [Bundler.settings["build.#{spec.name}"]]
|
57
|
+
Bundler.rubygems.with_build_args [Bundler.settings["build.#{spec.name}"]] do
|
55
58
|
spec.source.install(spec)
|
56
59
|
Bundler.ui.debug "from #{spec.loaded_from} "
|
57
|
-
ensure
|
58
|
-
Gem::Command.build_args = old_args
|
59
60
|
end
|
60
61
|
|
61
62
|
Bundler.ui.info ""
|
data/lib/bundler/resolver.rb
CHANGED
@@ -271,7 +271,7 @@ module Bundler
|
|
271
271
|
end
|
272
272
|
else
|
273
273
|
message = "Could not find gem '#{current}' "
|
274
|
-
if @index.
|
274
|
+
if @index.source_types.include?(Bundler::Source::Rubygems)
|
275
275
|
message << "in any of the gem sources listed in your Gemfile."
|
276
276
|
else
|
277
277
|
message << "in the gems available on this machine."
|
data/lib/bundler/rubygems_ext.rb
CHANGED
@@ -64,22 +64,6 @@ module Gem
|
|
64
64
|
dependencies - development_dependencies
|
65
65
|
end
|
66
66
|
|
67
|
-
def add_bundler_dependencies(*groups)
|
68
|
-
Bundler.ui.warn "#add_bundler_dependencies is deprecated and will " \
|
69
|
-
"be removed in Bundler 1.0. Instead, please use the #gemspec method " \
|
70
|
-
"in your Gemfile, which will pull in any dependencies specified in " \
|
71
|
-
"your gemspec"
|
72
|
-
|
73
|
-
groups = [:default] if groups.empty?
|
74
|
-
Bundler.definition.dependencies.each do |dep|
|
75
|
-
if dep.groups.include?(:development)
|
76
|
-
self.add_development_dependency(dep.name, dep.requirement.to_s)
|
77
|
-
elsif (dep.groups & groups).any?
|
78
|
-
self.add_dependency(dep.name, dep.requirement.to_s)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
67
|
private
|
84
68
|
|
85
69
|
def dependencies_to_gemfile(dependencies, group = nil)
|
@@ -118,11 +102,13 @@ module Gem
|
|
118
102
|
def to_lock
|
119
103
|
out = " #{name}"
|
120
104
|
unless requirement == Gem::Requirement.default
|
121
|
-
|
105
|
+
reqs = requirement.requirements.map{|o,v| "#{o} #{v}" }
|
106
|
+
out << " (#{reqs.join(', ')})"
|
122
107
|
end
|
123
108
|
out
|
124
109
|
end
|
125
110
|
|
111
|
+
# Backport of performance enhancement added to Rubygems 1.4
|
126
112
|
def matches_spec?(spec)
|
127
113
|
# name can be a Regexp, so use ===
|
128
114
|
return false unless name === spec.name
|
@@ -133,6 +119,7 @@ module Gem
|
|
133
119
|
end
|
134
120
|
|
135
121
|
class Requirement
|
122
|
+
# Backport of performance enhancement added to Rubygems 1.4
|
136
123
|
def none?
|
137
124
|
@none ||= (to_s == ">= 0")
|
138
125
|
end unless allocate.respond_to?(:none?)
|
@@ -0,0 +1,301 @@
|
|
1
|
+
module Bundler
|
2
|
+
class RubygemsIntegration
|
3
|
+
def initialize
|
4
|
+
# Work around a RubyGems bug
|
5
|
+
configuration
|
6
|
+
end
|
7
|
+
|
8
|
+
def is_19?
|
9
|
+
false
|
10
|
+
end
|
11
|
+
|
12
|
+
# Make sure that rubygems has fully loaded (1.9 partially loads
|
13
|
+
# sometimes)
|
14
|
+
def fully_load!
|
15
|
+
Gem.source_index if is_19?
|
16
|
+
end
|
17
|
+
|
18
|
+
def loaded_specs(name)
|
19
|
+
Gem.loaded_specs[name]
|
20
|
+
end
|
21
|
+
|
22
|
+
def mark_loaded(spec)
|
23
|
+
Gem.loaded_specs[spec.name] = spec
|
24
|
+
end
|
25
|
+
|
26
|
+
def path(obj)
|
27
|
+
Gem::Path.path(obj)
|
28
|
+
end
|
29
|
+
|
30
|
+
def platforms
|
31
|
+
Gem.platforms
|
32
|
+
end
|
33
|
+
|
34
|
+
def configuration
|
35
|
+
Gem.configuration
|
36
|
+
end
|
37
|
+
|
38
|
+
def ruby_engine
|
39
|
+
Gem.ruby_engine
|
40
|
+
end
|
41
|
+
|
42
|
+
def read_binary(path)
|
43
|
+
Gem.read_binary(path)
|
44
|
+
end
|
45
|
+
|
46
|
+
def inflate(obj)
|
47
|
+
Gem.inflate(obj)
|
48
|
+
end
|
49
|
+
|
50
|
+
def sources=(val)
|
51
|
+
Gem.sources = val
|
52
|
+
end
|
53
|
+
|
54
|
+
def sources
|
55
|
+
Gem.sources
|
56
|
+
end
|
57
|
+
|
58
|
+
def gem_dir
|
59
|
+
Gem.dir.to_s
|
60
|
+
end
|
61
|
+
|
62
|
+
def gem_bindir
|
63
|
+
Gem.bindir
|
64
|
+
end
|
65
|
+
|
66
|
+
def user_home
|
67
|
+
Gem.user_home
|
68
|
+
end
|
69
|
+
|
70
|
+
def gem_path
|
71
|
+
Gem.path.to_s
|
72
|
+
end
|
73
|
+
|
74
|
+
def marshal_spec_dir
|
75
|
+
Gem::MARSHAL_SPEC_DIR
|
76
|
+
end
|
77
|
+
|
78
|
+
def clear_paths
|
79
|
+
Gem.clear_paths
|
80
|
+
end
|
81
|
+
|
82
|
+
def bin_path(gem, bin, ver)
|
83
|
+
Gem.bin_path(gem, bin, ver)
|
84
|
+
end
|
85
|
+
|
86
|
+
def ui=(obj)
|
87
|
+
Gem::DefaultUserInteraction.ui = obj
|
88
|
+
end
|
89
|
+
|
90
|
+
def fetch_specs(all, pre, &blk)
|
91
|
+
Gem::SpecFetcher.new.list(all, pre).each(&blk)
|
92
|
+
end
|
93
|
+
|
94
|
+
def with_build_args(args)
|
95
|
+
old_args = Gem::Command.build_args
|
96
|
+
begin
|
97
|
+
Gem::Command.build_args = args
|
98
|
+
yield
|
99
|
+
ensure
|
100
|
+
Gem::Command.build_args = old_args
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def spec_from_gem(path)
|
105
|
+
Gem::Format.from_file_by_path(path).spec
|
106
|
+
end
|
107
|
+
|
108
|
+
def download_gem(spec, uri, path)
|
109
|
+
Gem::RemoteFetcher.fetcher.download(spec, uri, path)
|
110
|
+
end
|
111
|
+
|
112
|
+
def reverse_rubygems_kernel_mixin
|
113
|
+
# Disable rubygems' gem activation system
|
114
|
+
::Kernel.class_eval do
|
115
|
+
if private_method_defined?(:gem_original_require)
|
116
|
+
alias rubygems_require require
|
117
|
+
alias require gem_original_require
|
118
|
+
end
|
119
|
+
|
120
|
+
undef gem
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def replace_gem(specs)
|
125
|
+
executables = specs.map { |s| s.executables }.flatten
|
126
|
+
|
127
|
+
::Kernel.send(:define_method, :gem) do |dep, *reqs|
|
128
|
+
if executables.include? File.basename(caller.first.split(':').first)
|
129
|
+
return
|
130
|
+
end
|
131
|
+
opts = reqs.last.is_a?(Hash) ? reqs.pop : {}
|
132
|
+
|
133
|
+
unless dep.respond_to?(:name) && dep.respond_to?(:requirement)
|
134
|
+
dep = Gem::Dependency.new(dep, reqs)
|
135
|
+
end
|
136
|
+
|
137
|
+
spec = specs.find { |s| s.name == dep.name }
|
138
|
+
|
139
|
+
if spec.nil?
|
140
|
+
|
141
|
+
e = Gem::LoadError.new "#{dep.name} is not part of the bundle. Add it to Gemfile."
|
142
|
+
e.name = dep.name
|
143
|
+
if e.respond_to?(:requirement=)
|
144
|
+
e.requirement = dep.requirement
|
145
|
+
else
|
146
|
+
e.version_requirement = dep.requirement
|
147
|
+
end
|
148
|
+
raise e
|
149
|
+
elsif dep !~ spec
|
150
|
+
e = Gem::LoadError.new "can't activate #{dep}, already activated #{spec.full_name}. " \
|
151
|
+
"Make sure all dependencies are added to Gemfile."
|
152
|
+
e.name = dep.name
|
153
|
+
if e.respond_to?(:requirement=)
|
154
|
+
e.requirement = dep.requirement
|
155
|
+
else
|
156
|
+
e.version_requirement = dep.requirement
|
157
|
+
end
|
158
|
+
raise e
|
159
|
+
end
|
160
|
+
|
161
|
+
true
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def stub_source_index137(specs)
|
166
|
+
# Rubygems versions lower than 1.7 use SourceIndex#from_gems_in
|
167
|
+
source_index_class = (class << Gem::SourceIndex ; self ; end)
|
168
|
+
source_index_class.send(:remove_method, :from_gems_in)
|
169
|
+
source_index_class.send(:define_method, :from_gems_in) do |*args|
|
170
|
+
source_index = Gem::SourceIndex.new
|
171
|
+
source_index.spec_dirs = *args
|
172
|
+
source_index.add_specs(*specs)
|
173
|
+
source_index
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def stub_source_index170(specs)
|
178
|
+
Gem::SourceIndex.send(:define_method, :initialize) do |*args|
|
179
|
+
@gems = {}
|
180
|
+
self.spec_dirs = *args
|
181
|
+
add_specs(*specs)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
# Used to make bin stubs that are not created by bundler work
|
186
|
+
# under bundler. The new Gem.bin_path only considers gems in
|
187
|
+
# +specs+
|
188
|
+
def replace_bin_path(specs)
|
189
|
+
gem_class = (class << Gem ; self ; end)
|
190
|
+
gem_class.send(:remove_method, :bin_path)
|
191
|
+
gem_class.send(:define_method, :bin_path) do |name, *args|
|
192
|
+
exec_name, *reqs = args
|
193
|
+
|
194
|
+
if exec_name == 'bundle'
|
195
|
+
return ENV['BUNDLE_BIN_PATH']
|
196
|
+
end
|
197
|
+
|
198
|
+
spec = nil
|
199
|
+
|
200
|
+
if exec_name
|
201
|
+
spec = specs.find { |s| s.executables.include?(exec_name) }
|
202
|
+
spec or raise Gem::Exception, "can't find executable #{exec_name}"
|
203
|
+
else
|
204
|
+
spec = specs.find { |s| s.name == name }
|
205
|
+
exec_name = spec.default_executable or raise Gem::Exception, "no default executable for #{spec.full_name}"
|
206
|
+
end
|
207
|
+
|
208
|
+
gem_bin = File.join(spec.full_gem_path, spec.bindir, exec_name)
|
209
|
+
gem_from_path_bin = File.join(File.dirname(spec.loaded_from), spec.bindir, exec_name)
|
210
|
+
File.exist?(gem_bin) ? gem_bin : gem_from_path_bin
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
# Because Bundler has a static view of what specs are available,
|
215
|
+
# we don't #reflesh, so stub it out.
|
216
|
+
def replace_refresh
|
217
|
+
gem_class = (class << Gem ; self ; end)
|
218
|
+
gem_class.send(:remove_method, :refresh)
|
219
|
+
gem_class.send(:define_method, :refresh) { }
|
220
|
+
end
|
221
|
+
|
222
|
+
# Replace or hook into Rubygems to provide a bundlerized view
|
223
|
+
# of the world.
|
224
|
+
def replace_entrypoints(specs)
|
225
|
+
reverse_rubygems_kernel_mixin
|
226
|
+
|
227
|
+
replace_gem(specs)
|
228
|
+
|
229
|
+
stub_rubygems(specs)
|
230
|
+
|
231
|
+
replace_bin_path(specs)
|
232
|
+
replace_refresh
|
233
|
+
|
234
|
+
Gem.clear_paths
|
235
|
+
end
|
236
|
+
|
237
|
+
class Modern < RubygemsIntegration
|
238
|
+
def stub_rubygems(specs)
|
239
|
+
Gem::Specification.all = specs
|
240
|
+
|
241
|
+
Gem.post_reset {
|
242
|
+
Gem::Specification.all = specs
|
243
|
+
}
|
244
|
+
|
245
|
+
stub_source_index170(specs)
|
246
|
+
end
|
247
|
+
|
248
|
+
def all_specs
|
249
|
+
Gem::Specification.to_a
|
250
|
+
end
|
251
|
+
|
252
|
+
def find_name(name)
|
253
|
+
Gem::Specification.find_all_by_name name
|
254
|
+
end
|
255
|
+
|
256
|
+
end
|
257
|
+
|
258
|
+
class Legacy < RubygemsIntegration
|
259
|
+
def stub_rubygems(specs)
|
260
|
+
stub_source_index137(specs)
|
261
|
+
end
|
262
|
+
|
263
|
+
def path(obj)
|
264
|
+
obj.to_s
|
265
|
+
end
|
266
|
+
|
267
|
+
def all_specs
|
268
|
+
Gem.source_index.all_gems.values
|
269
|
+
end
|
270
|
+
|
271
|
+
def find_name(name)
|
272
|
+
Gem.source_index.find_name(name)
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
class Transitional < Legacy
|
277
|
+
def stub_rubygems(specs)
|
278
|
+
stub_source_index170(specs)
|
279
|
+
end
|
280
|
+
|
281
|
+
def path(obj)
|
282
|
+
obj.to_s
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
end
|
287
|
+
|
288
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.7.0')
|
289
|
+
if Gem::Specification.respond_to? :all=
|
290
|
+
@rubygems = RubygemsIntegration::Modern.new
|
291
|
+
else
|
292
|
+
@rubygems = RubygemsIntegration::Transitional.new
|
293
|
+
end
|
294
|
+
else
|
295
|
+
@rubygems = RubygemsIntegration::Legacy.new
|
296
|
+
end
|
297
|
+
|
298
|
+
class << self
|
299
|
+
attr_reader :rubygems
|
300
|
+
end
|
301
|
+
end
|
data/lib/bundler/runtime.rb
CHANGED
@@ -11,7 +11,7 @@ module Bundler
|
|
11
11
|
specs = groups.any? ? @definition.specs_for(groups) : requested_specs
|
12
12
|
|
13
13
|
setup_environment
|
14
|
-
|
14
|
+
Bundler.rubygems.replace_entrypoints(specs)
|
15
15
|
|
16
16
|
# Activate the specs
|
17
17
|
specs.each do |spec|
|
@@ -19,7 +19,7 @@ module Bundler
|
|
19
19
|
raise GemNotFound, "#{spec.full_name} is missing. Run `bundle` to get it."
|
20
20
|
end
|
21
21
|
|
22
|
-
if activated_spec =
|
22
|
+
if activated_spec = Bundler.rubygems.loaded_specs(spec.name) and activated_spec.version != spec.version
|
23
23
|
e = Gem::LoadError.new "You have already activated #{activated_spec.name} #{activated_spec.version}, " \
|
24
24
|
"but your Gemfile requires #{spec.name} #{spec.version}. Consider using bundle exec."
|
25
25
|
e.name = spec.name
|
@@ -31,7 +31,7 @@ module Bundler
|
|
31
31
|
raise e
|
32
32
|
end
|
33
33
|
|
34
|
-
|
34
|
+
Bundler.rubygems.mark_loaded(spec)
|
35
35
|
load_paths = spec.load_paths.reject {|path| $LOAD_PATH.include?(path)}
|
36
36
|
$LOAD_PATH.unshift(*load_paths)
|
37
37
|
end
|
@@ -102,7 +102,7 @@ module Bundler
|
|
102
102
|
cached = Dir["#{cache_path}/*.gem"]
|
103
103
|
|
104
104
|
cached = cached.delete_if do |path|
|
105
|
-
spec =
|
105
|
+
spec = Bundler.rubygems.spec_from_gem path
|
106
106
|
|
107
107
|
resolve.any? do |s|
|
108
108
|
s.name == spec.name && s.version == spec.version && !s.source.is_a?(Bundler::Source::Git)
|
@@ -176,7 +176,7 @@ module Bundler
|
|
176
176
|
|
177
177
|
def setup_environment
|
178
178
|
begin
|
179
|
-
ENV["BUNDLE_BIN_PATH"] =
|
179
|
+
ENV["BUNDLE_BIN_PATH"] = Bundler.rubygems.bin_path("bundler", "bundle", VERSION)
|
180
180
|
rescue Gem::GemNotFoundException
|
181
181
|
ENV["BUNDLE_BIN_PATH"] = File.expand_path("../../../bin/bundle", __FILE__)
|
182
182
|
end
|