bundler 1.0.0.beta.5 → 1.0.0.beta.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.
- data/TODO.md +2 -10
- data/bin/bundle +2 -1
- data/lib/bundler/cli.rb +59 -16
- data/lib/bundler/definition.rb +12 -7
- data/lib/bundler/dsl.rb +20 -3
- data/lib/bundler/environment.rb +3 -3
- data/lib/bundler/lockfile_parser.rb +5 -4
- data/lib/bundler/rubygems_ext.rb +5 -0
- data/lib/bundler/runtime.rb +34 -16
- data/lib/bundler/settings.rb +38 -16
- data/lib/bundler/source.rb +31 -8
- data/lib/bundler/spec_set.rb +1 -1
- data/lib/bundler/vendor/thor.rb +40 -18
- data/lib/bundler/vendor/thor/base.rb +7 -7
- data/lib/bundler/vendor/thor/invocation.rb +1 -1
- data/lib/bundler/vendor/thor/parser/argument.rb +15 -15
- data/lib/bundler/vendor/thor/parser/option.rb +38 -46
- data/lib/bundler/vendor/thor/parser/options.rb +1 -1
- data/lib/bundler/vendor/thor/shell.rb +7 -2
- data/lib/bundler/vendor/thor/shell/basic.rb +9 -5
- data/lib/bundler/vendor/thor/shell/html.rb +121 -0
- data/lib/bundler/vendor/thor/task.rb +58 -46
- data/lib/bundler/vendor/thor/version.rb +1 -1
- data/lib/bundler/version.rb +2 -2
- metadata +8 -4
data/TODO.md
CHANGED
@@ -1,16 +1,8 @@
|
|
1
1
|
## Bundler TODO list
|
2
2
|
|
3
|
-
- Check to make sure ~/.bundler/bin is in $PATH
|
4
3
|
- Cache Git repositories
|
4
|
+
- Build options
|
5
|
+
- A gem shit list
|
5
6
|
- Interactive mode for bundle (install) to work out conflicts
|
6
7
|
- bundle irb / bundle ruby / bundle [whatever] -> bundle exec
|
7
|
-
- Make bundle (install) work when sudo might be needed
|
8
8
|
- Generate a bundle stub into the application
|
9
|
-
- Handle the following case (no remote fetching):
|
10
|
-
1) Depend on nokogiri, nokogiri is installed locally (ruby platform)
|
11
|
-
2) Run bundle package. nokogiri-1.4.2.gem is cached
|
12
|
-
3) Clone on jruby
|
13
|
-
4) Run `bundle install`
|
14
|
-
Bundler will happily install the RUBY platform nokogiri because it
|
15
|
-
is cached and bundler has not hit the remote source once so it does
|
16
|
-
not know that there is a nokogiri-1.4.2-java.gem available
|
data/bin/bundle
CHANGED
@@ -13,8 +13,9 @@ begin
|
|
13
13
|
Bundler::CLI.start
|
14
14
|
rescue Bundler::BundlerError => e
|
15
15
|
Bundler.ui.error e.message
|
16
|
+
Bundler.ui.error e.backtrace.join("\n") if ENV["BUNDLE_DEBUG"]
|
16
17
|
exit e.status_code
|
17
18
|
rescue Interrupt
|
18
19
|
Bundler.ui.error "\nQuitting..."
|
19
20
|
exit 1
|
20
|
-
end
|
21
|
+
end
|
data/lib/bundler/cli.rb
CHANGED
@@ -15,7 +15,7 @@ module Bundler
|
|
15
15
|
Gem::DefaultUserInteraction.ui = UI::RGProxy.new(Bundler.ui)
|
16
16
|
end
|
17
17
|
|
18
|
-
check_unknown_options! unless ARGV.include?("exec")
|
18
|
+
check_unknown_options! unless ARGV.include?("exec") || ARGV.include?("config")
|
19
19
|
|
20
20
|
default_task :install
|
21
21
|
class_option "no-color", :type => :boolean, :banner => "Disable colorization in output"
|
@@ -67,6 +67,7 @@ module Bundler
|
|
67
67
|
Bundler.ui.warn "Install missing gems with `bundle install`"
|
68
68
|
exit 1
|
69
69
|
else
|
70
|
+
Bundler.load.lock
|
70
71
|
Bundler.ui.info "The Gemfile's dependencies are satisfied"
|
71
72
|
end
|
72
73
|
end
|
@@ -96,7 +97,7 @@ module Bundler
|
|
96
97
|
"Only output warnings and errors."
|
97
98
|
method_option "local", :type => :boolean, :banner =>
|
98
99
|
"Do not attempt to fetch gems remotely and use the gem cache instead"
|
99
|
-
method_option "binstubs", :type => :
|
100
|
+
method_option "binstubs", :type => :string, :lazy_default => "bin", :banner =>
|
100
101
|
"Generate bin stubs for bundled gems to ./bin"
|
101
102
|
def install(path = nil)
|
102
103
|
opts = options.dup
|
@@ -106,13 +107,13 @@ module Bundler
|
|
106
107
|
# Can't use Bundler.settings for this because settings needs gemfile.dirname
|
107
108
|
ENV['BUNDLE_GEMFILE'] = opts[:gemfile] if opts[:gemfile]
|
108
109
|
Bundler.settings[:path] = path if path
|
109
|
-
Bundler.settings[:bin] =
|
110
|
+
Bundler.settings[:bin] = opts["binstubs"] if opts[:binstubs]
|
110
111
|
Bundler.settings[:disable_shared_gems] = '1' if options["disable-shared-gems"] || path
|
111
112
|
Bundler.settings.without = opts[:without]
|
112
113
|
Bundler.ui.be_quiet! if opts[:quiet]
|
113
114
|
|
114
115
|
Installer.install(Bundler.root, Bundler.definition, opts)
|
115
|
-
cache if Bundler.root.join("vendor/cache").exist?
|
116
|
+
Bundler.load.cache if Bundler.root.join("vendor/cache").exist?
|
116
117
|
Bundler.ui.confirm "Your bundle is complete! " +
|
117
118
|
"Use `bundle show [gemname]` to see where a bundled gem is installed."
|
118
119
|
rescue GemNotFound => e
|
@@ -134,13 +135,13 @@ module Bundler
|
|
134
135
|
|
135
136
|
if gems.empty? && sources.empty?
|
136
137
|
# We're doing a full update
|
137
|
-
|
138
|
+
Bundler.definition(true)
|
138
139
|
else
|
139
140
|
Bundler.definition(:gems => gems, :sources => sources)
|
140
141
|
end
|
141
142
|
|
142
143
|
Installer.install Bundler.root, Bundler.definition, "update" => true
|
143
|
-
cache if Bundler.root.join("vendor/cache").exist?
|
144
|
+
Bundler.load.cache if Bundler.root.join("vendor/cache").exist?
|
144
145
|
Bundler.ui.confirm "Your bundle is updated! " +
|
145
146
|
"Use `bundle show [gemname]` to see where a bundled gem is installed."
|
146
147
|
end
|
@@ -161,6 +162,8 @@ module Bundler
|
|
161
162
|
Calling show with [GEM] will list the exact location of that gem on your machine.
|
162
163
|
D
|
163
164
|
def show(gem_name = nil)
|
165
|
+
Bundler.load.lock
|
166
|
+
|
164
167
|
if gem_name
|
165
168
|
Bundler.ui.info locate_gem(gem_name)
|
166
169
|
else
|
@@ -172,11 +175,13 @@ module Bundler
|
|
172
175
|
end
|
173
176
|
map %w(list) => "show"
|
174
177
|
|
175
|
-
desc "cache", "Cache all the gems to vendor/cache"
|
178
|
+
desc "cache", "Cache all the gems to vendor/cache", :hide => true
|
176
179
|
method_option "no-prune", :type => :boolean, :banner => "Don't remove stale gems from the cache."
|
177
180
|
def cache
|
181
|
+
Bundler.definition.resolve_with_cache!
|
178
182
|
Bundler.load.cache
|
179
|
-
Bundler.
|
183
|
+
Bundler.settings[:no_prune] = true if options[:no_prune]
|
184
|
+
Bundler.load.lock
|
180
185
|
rescue GemNotFound => e
|
181
186
|
Bundler.ui.error(e.message)
|
182
187
|
Bundler.ui.warn "Run `bundle install` to install missing gems."
|
@@ -194,7 +199,7 @@ module Bundler
|
|
194
199
|
def package
|
195
200
|
install
|
196
201
|
# TODO: move cache contents here now that all bundles are locked
|
197
|
-
cache
|
202
|
+
Bundler.load.cache
|
198
203
|
end
|
199
204
|
map %w(pack) => :package
|
200
205
|
|
@@ -234,6 +239,48 @@ module Bundler
|
|
234
239
|
end
|
235
240
|
end
|
236
241
|
|
242
|
+
desc "config NAME [VALUE]", "retrieve or set a configuration value"
|
243
|
+
long_desc <<-D
|
244
|
+
Retrieves or sets a configuration value. If only parameter is provided, retrieve the value. If two parameters are provided, replace the
|
245
|
+
existing value with the newly provided one.
|
246
|
+
|
247
|
+
By default, setting a configuration value sets it for all projects
|
248
|
+
on the machine. If you want to set the configuration for a specific
|
249
|
+
project, use the --local flag.
|
250
|
+
|
251
|
+
If a global setting is superceded by local configuration, this command
|
252
|
+
will show the current value, as well as any superceded values and
|
253
|
+
where they were specified.
|
254
|
+
D
|
255
|
+
def config(name, *values)
|
256
|
+
locations = Bundler.settings.locations(name)
|
257
|
+
|
258
|
+
if values.empty?
|
259
|
+
# TODO: Say something more useful here
|
260
|
+
locations.each do |location, value|
|
261
|
+
if value
|
262
|
+
Bundler.ui.info "#{location}: #{value}"
|
263
|
+
end
|
264
|
+
end
|
265
|
+
else
|
266
|
+
if local = locations[:local]
|
267
|
+
Bundler.ui.info "Your application has set #{name} to #{local.inspect}. This will override the " \
|
268
|
+
"system value you are currently setting"
|
269
|
+
end
|
270
|
+
|
271
|
+
if global = locations[:global]
|
272
|
+
Bundler.ui.info "You are replacing the current system value of #{name}, which is currently #{global}"
|
273
|
+
end
|
274
|
+
|
275
|
+
if env = locations[:env]
|
276
|
+
Bundler.ui.info "You have set a bundler environment variable for #{env}. This will take precedence " \
|
277
|
+
"over the system value you are setting"
|
278
|
+
end
|
279
|
+
|
280
|
+
Bundler.settings.set_global(name, values.join(" "))
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
237
284
|
desc "open GEM", "Opens the source directory of the given bundled gem"
|
238
285
|
def open(name)
|
239
286
|
editor = [ENV['BUNDLER_EDITOR'], ENV['VISUAL'], ENV['EDITOR']].find{|e| !e.nil? && !e.empty? }
|
@@ -297,14 +344,10 @@ module Bundler
|
|
297
344
|
def locate_gem(name)
|
298
345
|
spec = Bundler.load.specs.find{|s| s.name == name }
|
299
346
|
raise GemNotFound, "Could not find gem '#{name}' in the current bundle." unless spec
|
347
|
+
if spec.name == 'bundler'
|
348
|
+
return File.expand_path('../../../', __FILE__)
|
349
|
+
end
|
300
350
|
spec.full_gem_path
|
301
351
|
end
|
302
|
-
|
303
|
-
def self.printable_tasks
|
304
|
-
tasks = super.dup
|
305
|
-
nodoc = /^bundle (cache)/
|
306
|
-
tasks.reject!{|t| t.first =~ nodoc }
|
307
|
-
tasks
|
308
|
-
end
|
309
352
|
end
|
310
353
|
end
|
data/lib/bundler/definition.rb
CHANGED
@@ -34,22 +34,24 @@ module Bundler
|
|
34
34
|
@dependencies, @sources, @unlock = dependencies, sources, unlock
|
35
35
|
@remote = false
|
36
36
|
@specs = nil
|
37
|
-
@unlock[:gems] ||= []
|
38
|
-
@unlock[:sources] ||= []
|
39
37
|
|
40
|
-
if lockfile && File.exists?(lockfile)
|
38
|
+
if lockfile && File.exists?(lockfile) && unlock != true
|
41
39
|
locked = LockfileParser.new(File.read(lockfile))
|
42
40
|
@platforms = locked.platforms
|
43
41
|
@locked_deps = locked.dependencies
|
44
42
|
@last_resolve = SpecSet.new(locked.specs)
|
45
43
|
@locked_sources = locked.sources
|
46
44
|
else
|
45
|
+
@unlock = {}
|
47
46
|
@platforms = []
|
48
47
|
@locked_deps = []
|
49
48
|
@last_resolve = SpecSet.new([])
|
50
49
|
@locked_sources = []
|
51
50
|
end
|
52
51
|
|
52
|
+
@unlock[:gems] ||= []
|
53
|
+
@unlock[:sources] ||= []
|
54
|
+
|
53
55
|
current_platform = Gem.platforms.map { |p| p.to_generic }.compact.last
|
54
56
|
@platforms |= [current_platform]
|
55
57
|
|
@@ -165,10 +167,13 @@ module Bundler
|
|
165
167
|
out << "\n"
|
166
168
|
out << "DEPENDENCIES\n"
|
167
169
|
|
170
|
+
handled = []
|
168
171
|
dependencies.
|
169
172
|
sort_by { |d| d.name }.
|
170
173
|
each do |dep|
|
174
|
+
next if handled.include?(dep.name)
|
171
175
|
out << dep.to_lock
|
176
|
+
handled << dep.name
|
172
177
|
end
|
173
178
|
|
174
179
|
out
|
@@ -183,7 +188,9 @@ module Bundler
|
|
183
188
|
end
|
184
189
|
|
185
190
|
def converge_sources
|
186
|
-
@sources
|
191
|
+
@sources.map! do |source|
|
192
|
+
@locked_sources.find { |s| s == source } || source
|
193
|
+
end
|
187
194
|
@sources.each do |source|
|
188
195
|
source.unlock! if source.respond_to?(:unlock!) && @unlock[:sources].include?(source.name)
|
189
196
|
end
|
@@ -192,9 +199,7 @@ module Bundler
|
|
192
199
|
def converge_dependencies
|
193
200
|
(@dependencies + @locked_deps).each do |dep|
|
194
201
|
if dep.source
|
195
|
-
source = @sources.find { |s| dep.source == s }
|
196
|
-
raise "Something went wrong, there is no matching source" unless source
|
197
|
-
dep.source = source
|
202
|
+
dep.source = @sources.find { |s| dep.source == s }
|
198
203
|
end
|
199
204
|
end
|
200
205
|
end
|
data/lib/bundler/dsl.rb
CHANGED
@@ -20,14 +20,16 @@ module Bundler
|
|
20
20
|
@env = nil
|
21
21
|
end
|
22
22
|
|
23
|
-
def gemspec(opts)
|
23
|
+
def gemspec(opts = nil)
|
24
24
|
path = opts && opts[:path] || '.'
|
25
25
|
name = opts && opts[:name] || '*'
|
26
26
|
development_group = opts && opts[:development_group] || :development
|
27
27
|
gemspecs = Dir[File.join(path, "#{name}.gemspec")]
|
28
|
+
|
28
29
|
case gemspecs.size
|
29
30
|
when 1
|
30
31
|
spec = Gem::Specification.load(gemspecs.first)
|
32
|
+
gem spec.name, :path => path
|
31
33
|
spec.runtime_dependencies.each do |dep|
|
32
34
|
gem dep.name, dep.requirement.to_s
|
33
35
|
end
|
@@ -49,7 +51,7 @@ module Bundler
|
|
49
51
|
end
|
50
52
|
|
51
53
|
options = Hash === args.last ? args.pop : {}
|
52
|
-
version = args
|
54
|
+
version = args || [">= 0"]
|
53
55
|
if group = options[:groups] || options[:group]
|
54
56
|
options[:group] = group
|
55
57
|
end
|
@@ -57,6 +59,21 @@ module Bundler
|
|
57
59
|
_deprecated_options(options)
|
58
60
|
_normalize_options(name, version, options)
|
59
61
|
|
62
|
+
dep = Dependency.new(name, version, options)
|
63
|
+
|
64
|
+
if current = @dependencies.find { |d| d.name == dep.name }
|
65
|
+
if current.requirement != dep.requirement
|
66
|
+
raise DslError, "You cannot specify the same gem twice with different version requirements. " \
|
67
|
+
"You specified: #{current.name} (#{current.requirement}) and " \
|
68
|
+
"#{dep.name} (#{dep.requirement})"
|
69
|
+
end
|
70
|
+
|
71
|
+
if current.source != dep.source
|
72
|
+
raise DslError, "You cannot specify the same gem twice coming from different sources. You " \
|
73
|
+
"specified that #{dep.name} (#{dep.requirement}) should come from " \
|
74
|
+
"#{current.source || 'an unspecfied source'} and #{dep.source}"
|
75
|
+
end
|
76
|
+
end
|
60
77
|
@dependencies << Dependency.new(name, version, options)
|
61
78
|
end
|
62
79
|
|
@@ -200,7 +217,7 @@ module Bundler
|
|
200
217
|
# Normalize git and path options
|
201
218
|
["git", "path"].each do |type|
|
202
219
|
if param = opts[type]
|
203
|
-
options = _version?(version) ? opts.merge("name" => name, "version" => version) : opts.dup
|
220
|
+
options = _version?(version.first) ? opts.merge("name" => name, "version" => version.first) : opts.dup
|
204
221
|
source = send(type, param, options, :prepend => true) {}
|
205
222
|
opts["source"] = source
|
206
223
|
end
|
data/lib/bundler/environment.rb
CHANGED
@@ -5,6 +5,9 @@ module Bundler
|
|
5
5
|
def initialize(root, definition)
|
6
6
|
@root = root
|
7
7
|
@definition = definition
|
8
|
+
|
9
|
+
env_file = root.join('.bundle/environment.rb')
|
10
|
+
env_file.rmtree if env_file.exist?
|
8
11
|
end
|
9
12
|
|
10
13
|
def inspect
|
@@ -33,9 +36,6 @@ module Bundler
|
|
33
36
|
end
|
34
37
|
|
35
38
|
def lock
|
36
|
-
env_file = root.join('.bundle/environment.rb')
|
37
|
-
env_file.rmtree if env_file.exist?
|
38
|
-
|
39
39
|
contents = @definition.to_lock
|
40
40
|
|
41
41
|
File.open(root.join('Gemfile.lock'), 'w') do |f|
|
@@ -60,18 +60,19 @@ module Bundler
|
|
60
60
|
|
61
61
|
def parse_dependency(line)
|
62
62
|
if line =~ %r{^ {2}#{NAME_VERSION}(!)?$}
|
63
|
-
name, version, pinned = $1, $2, $
|
63
|
+
name, version, pinned = $1, $2, $4
|
64
|
+
version = version.split(",").map { |d| d.strip } if version
|
64
65
|
|
65
66
|
dep = Bundler::Dependency.new(name, version)
|
66
67
|
|
67
|
-
if pinned
|
68
|
+
if pinned && dep.name != 'bundler'
|
68
69
|
dep.source = @specs.find { |s| s.name == dep.name }.source
|
69
70
|
|
70
71
|
# Path sources need to know what the default name / version
|
71
72
|
# to use in the case that there are no gemspecs present. A fake
|
72
73
|
# gemspec is created based on the version set on the dependency
|
73
74
|
# TODO: Use the version from the spec instead of from the dependency
|
74
|
-
if version =~ /^= (.+)$/ && dep.source.is_a?(Bundler::Source::Path)
|
75
|
+
if version && version.size == 1 && version.first =~ /^= (.+)$/ && dep.source.is_a?(Bundler::Source::Path)
|
75
76
|
dep.source.name = name
|
76
77
|
dep.source.version = $1
|
77
78
|
end
|
@@ -103,4 +104,4 @@ module Bundler
|
|
103
104
|
end
|
104
105
|
|
105
106
|
end
|
106
|
-
end
|
107
|
+
end
|
data/lib/bundler/rubygems_ext.rb
CHANGED
@@ -111,6 +111,11 @@ module Gem
|
|
111
111
|
end
|
112
112
|
|
113
113
|
def add_bundler_dependencies(*groups)
|
114
|
+
Bundler.ui.warn "#add_bundler_dependencies is deprecated and will " \
|
115
|
+
"be removed in Bundler 1.0. Instead, please use the #gemspec method " \
|
116
|
+
"in your Gemfile, which will pull in any dependencies specified in " \
|
117
|
+
"your gemspec"
|
118
|
+
|
114
119
|
groups = [:default] if groups.empty?
|
115
120
|
Bundler.definition.dependencies.each do |dep|
|
116
121
|
if dep.groups.include?(:development)
|
data/lib/bundler/runtime.rb
CHANGED
@@ -4,11 +4,6 @@ module Bundler
|
|
4
4
|
class Runtime < Environment
|
5
5
|
include SharedHelpers
|
6
6
|
|
7
|
-
def initialize(*)
|
8
|
-
super
|
9
|
-
lock
|
10
|
-
end
|
11
|
-
|
12
7
|
def setup(*groups)
|
13
8
|
# Has to happen first
|
14
9
|
clean_load_path
|
@@ -35,9 +30,19 @@ module Bundler
|
|
35
30
|
load_paths = spec.load_paths.reject {|path| $LOAD_PATH.include?(path)}
|
36
31
|
$LOAD_PATH.unshift(*load_paths)
|
37
32
|
end
|
33
|
+
|
34
|
+
lock
|
35
|
+
|
38
36
|
self
|
39
37
|
end
|
40
38
|
|
39
|
+
REGEXPS = [
|
40
|
+
/^no such file to load -- (.+)$/i,
|
41
|
+
/^Missing \w+ (?:file\s*)?([^\s]+.rb)$/i,
|
42
|
+
/^Missing API definition file in (.+)$/i,
|
43
|
+
/^cannot load such file -- (.+)$/i,
|
44
|
+
]
|
45
|
+
|
41
46
|
def require(*groups)
|
42
47
|
groups.map! { |g| g.to_sym }
|
43
48
|
groups = [:default] if groups.empty?
|
@@ -47,17 +52,19 @@ module Bundler
|
|
47
52
|
# groups
|
48
53
|
next unless (dep.groups & groups).any?
|
49
54
|
|
55
|
+
required_file = nil
|
56
|
+
|
50
57
|
begin
|
51
58
|
# Loop through all the specified autorequires for the
|
52
59
|
# dependency. If there are none, use the dependency's name
|
53
60
|
# as the autorequire.
|
54
61
|
Array(dep.autorequire || dep.name).each do |file|
|
62
|
+
required_file = file
|
55
63
|
Kernel.require file
|
56
64
|
end
|
57
|
-
rescue LoadError
|
58
|
-
|
59
|
-
|
60
|
-
raise if dep.autorequire
|
65
|
+
rescue LoadError => e
|
66
|
+
REGEXPS.find { |r| r =~ e.message }
|
67
|
+
raise if dep.autorequire || $1 != required_file
|
61
68
|
end
|
62
69
|
end
|
63
70
|
end
|
@@ -80,18 +87,29 @@ module Bundler
|
|
80
87
|
next if spec.name == 'bundler'
|
81
88
|
spec.source.cache(spec) if spec.source.respond_to?(:cache)
|
82
89
|
end
|
90
|
+
prune_cache unless Bundler.settings[:no_prune]
|
83
91
|
end
|
84
92
|
|
85
93
|
def prune_cache
|
86
94
|
FileUtils.mkdir_p(cache_path)
|
87
95
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
96
|
+
resolve = @definition.resolve
|
97
|
+
cached = Dir["#{cache_path}/*.gem"]
|
98
|
+
|
99
|
+
cached = cached.delete_if do |path|
|
100
|
+
spec = Gem::Format.from_file_by_path(path).spec
|
101
|
+
|
102
|
+
resolve.any? do |s|
|
103
|
+
s.name == spec.name && s.version == spec.version
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
if cached.any?
|
108
|
+
Bundler.ui.info "Removing outdated .gem files from vendor/cache"
|
109
|
+
|
110
|
+
cached.each do |path|
|
111
|
+
Bundler.ui.info " * #{File.basename(path)}"
|
112
|
+
File.delete(path)
|
95
113
|
end
|
96
114
|
end
|
97
115
|
end
|