bundler 1.0.0.rc.1 → 1.0.0.rc.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 +48 -0
- data/lib/bundler.rb +12 -7
- data/lib/bundler/cli.rb +55 -4
- data/lib/bundler/definition.rb +75 -10
- data/lib/bundler/dsl.rb +2 -4
- data/lib/bundler/resolver.rb +0 -3
- data/lib/bundler/settings.rb +5 -0
- data/lib/bundler/vendor/thor/shell/html.rb +1 -1
- data/lib/bundler/version.rb +1 -1
- metadata +4 -11
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,51 @@
|
|
1
|
+
## 1.0.0.rc.2 (July 29, 2010)
|
2
|
+
|
3
|
+
- `bundle install path` was causing confusion, so we now print
|
4
|
+
a clarifying warning. The preferred way to install to a path
|
5
|
+
(which will not print the warning) is
|
6
|
+
`bundle install --path path/to/install`.
|
7
|
+
- `bundle install --system` installs to the default system
|
8
|
+
location ($BUNDLE_PATH or $GEM_HOME) even if you previously
|
9
|
+
used `bundle install --path`
|
10
|
+
- completely remove `--disable-shared-gems`. If you install to
|
11
|
+
system, you will not be isolated, while if you install to
|
12
|
+
another path, you will be isolated from gems installed to
|
13
|
+
the system. This was mostly an internal option whose naming
|
14
|
+
and semantics were extremely confusing.
|
15
|
+
- Add a `--production` option to `bundle install`:
|
16
|
+
- by default, installs to `vendor/bundle`. This can be
|
17
|
+
overridden with the `--path` option
|
18
|
+
- uses `--local` if `vendor/cache` is found. This will
|
19
|
+
guarantee that Bundler does not attempt to connect to
|
20
|
+
Rubygems and will use the gems cached in `vendor/cache`
|
21
|
+
instead
|
22
|
+
- Raises an exception if a Gemfile.lock is not found
|
23
|
+
- Raises an exception if you modify your Gemfile in development
|
24
|
+
but do not check in an updated Gemfile.lock
|
25
|
+
- Fixes a bug where switching a source from Rubygems to git
|
26
|
+
would always say "the git source is not checked out" when
|
27
|
+
running `bundle install`
|
28
|
+
|
29
|
+
NOTE: We received several reports of "the git source has not
|
30
|
+
been checked out. Please run bundle install". As far as we
|
31
|
+
can tell, these problems have two possible causes:
|
32
|
+
|
33
|
+
1. `bundle install ~/.bundle` in one user, but actually running
|
34
|
+
the application as another user. Never install gems to a
|
35
|
+
directory scoped to a user (`~` or `$HOME`) in deployment.
|
36
|
+
2. A bug that happened when changing a gem to a git source.
|
37
|
+
|
38
|
+
To mitigate several common causes of `(1)`, please use the
|
39
|
+
new `--production` flag. This flag is simply a roll-up of
|
40
|
+
the best practices we have been encouraging people to use
|
41
|
+
for deployment.
|
42
|
+
|
43
|
+
If you want to share gems across deployments, and you use
|
44
|
+
Capistrano, symlink release_path/current/vendor/bundle to
|
45
|
+
release_path/shared/bundled_gems. This will keep deployments
|
46
|
+
snappy while maintaining the benefits of clean, deploy-time
|
47
|
+
isolation.
|
48
|
+
|
1
49
|
## 1.0.0.rc.1 (July 26, 2010)
|
2
50
|
|
3
51
|
- Fixed a bug with `bundle install` on multiple machines and git
|
data/lib/bundler.rb
CHANGED
@@ -28,12 +28,7 @@ module Bundler
|
|
28
28
|
|
29
29
|
class BundlerError < StandardError
|
30
30
|
def self.status_code(code = nil)
|
31
|
-
|
32
|
-
@code = code
|
33
|
-
end
|
34
|
-
|
35
|
-
def status_code
|
36
|
-
self.class.status_code
|
31
|
+
define_method(:status_code) { code }
|
37
32
|
end
|
38
33
|
end
|
39
34
|
|
@@ -45,7 +40,9 @@ module Bundler
|
|
45
40
|
class GemspecError < BundlerError; status_code(14) ; end
|
46
41
|
class DeprecatedError < BundlerError; status_code(12) ; end
|
47
42
|
class GemspecError < BundlerError; status_code(14) ; end
|
48
|
-
class
|
43
|
+
class DslError < BundlerError; status_code(15) ; end
|
44
|
+
class ProductionError < BundlerError; status_code(16) ; end
|
45
|
+
class InvalidOption < DslError ; end
|
49
46
|
|
50
47
|
class VersionConflict < BundlerError
|
51
48
|
attr_reader :conflicts
|
@@ -71,6 +68,14 @@ module Bundler
|
|
71
68
|
end
|
72
69
|
end
|
73
70
|
|
71
|
+
def production?
|
72
|
+
@production
|
73
|
+
end
|
74
|
+
|
75
|
+
def production=(value)
|
76
|
+
@production = value
|
77
|
+
end
|
78
|
+
|
74
79
|
def ui
|
75
80
|
@ui ||= UI.new
|
76
81
|
end
|
data/lib/bundler/cli.rb
CHANGED
@@ -86,7 +86,7 @@ module Bundler
|
|
86
86
|
method_option "without", :type => :array, :banner =>
|
87
87
|
"Exclude gems that are part of the specified named group."
|
88
88
|
method_option "disable-shared-gems", :type => :boolean, :banner =>
|
89
|
-
"
|
89
|
+
"This option is deprecated. Please do not use it."
|
90
90
|
method_option "gemfile", :type => :string, :banner =>
|
91
91
|
"Use the specified gemfile instead of Gemfile"
|
92
92
|
method_option "no-prune", :type => :boolean, :banner =>
|
@@ -99,16 +99,61 @@ module Bundler
|
|
99
99
|
"Do not attempt to fetch gems remotely and use the gem cache instead"
|
100
100
|
method_option "binstubs", :type => :string, :lazy_default => "bin", :banner =>
|
101
101
|
"Generate bin stubs for bundled gems to ./bin"
|
102
|
+
method_option "path", :type => :string, :banner =>
|
103
|
+
"Specify a different path than the system default ($BUNDLE_PATH or $GEM_HOME). Bundler will remember this value for future installs on this machine"
|
104
|
+
method_option "system", :type => :boolean, :banner =>
|
105
|
+
"Install to the system location ($BUNDLE_PATH or $GEM_HOME) even if the bundle was previously installed somewhere else for this application"
|
106
|
+
method_option "production", :type => :boolean, :banner =>
|
107
|
+
"Install using defaults tuned for deployment environments"
|
102
108
|
def install(path = nil)
|
103
109
|
opts = options.dup
|
104
110
|
opts[:without] ||= []
|
105
111
|
opts[:without].map! { |g| g.to_sym }
|
106
112
|
|
113
|
+
if (path || options[:path] || options[:production]) && options[:system]
|
114
|
+
Bundler.ui.error "You have specified both a path to install your gems to, \n" \
|
115
|
+
"as well as --system. Please choose."
|
116
|
+
exit 1
|
117
|
+
end
|
118
|
+
|
119
|
+
if path && options[:path]
|
120
|
+
Bundler.ui.error "You have specified a path via `bundle install #{path}` as well as\n" \
|
121
|
+
"by `bundle install --path #{options[:path]}`. These options are\n" \
|
122
|
+
"equivalent, so please use one or the other."
|
123
|
+
exit 1
|
124
|
+
end
|
125
|
+
|
126
|
+
if opts["disable-shared-gems"]
|
127
|
+
Bundler.ui.error "The disable-shared-gem option is no longer available.\n\n" \
|
128
|
+
"Instead, use `bundle install` to install to your system,\n" \
|
129
|
+
"or `bundle install --path path/to/gems` to install to an isolated\n" \
|
130
|
+
"location. Bundler will resolve relative paths relative to\n" \
|
131
|
+
"your `Gemfile`."
|
132
|
+
exit 1
|
133
|
+
end
|
134
|
+
|
135
|
+
if opts[:production]
|
136
|
+
Bundler.production = true
|
137
|
+
|
138
|
+
unless Bundler.root.join("Gemfile.lock").exist?
|
139
|
+
raise ProductionError, "The --production flag requires a Gemfile.lock. Please\n" \
|
140
|
+
"make sure you have checked your Gemfile.lock into version\n" \
|
141
|
+
"control before deploying."
|
142
|
+
end
|
143
|
+
|
144
|
+
if Bundler.root.join("vendor/cache").exist?
|
145
|
+
opts["local"] = true
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
107
149
|
# Can't use Bundler.settings for this because settings needs gemfile.dirname
|
108
150
|
ENV['BUNDLE_GEMFILE'] = opts[:gemfile] if opts[:gemfile]
|
151
|
+
Bundler.settings[:path] = nil if options[:system]
|
152
|
+
Bundler.settings[:path] = "vendor/bundle" if options[:production]
|
109
153
|
Bundler.settings[:path] = path if path
|
154
|
+
Bundler.settings[:path] = options[:path] if options[:path]
|
110
155
|
Bundler.settings[:bin] = opts["binstubs"] if opts[:binstubs]
|
111
|
-
Bundler.settings[:disable_shared_gems] = '1' if
|
156
|
+
Bundler.settings[:disable_shared_gems] = '1' if Bundler.settings[:path]
|
112
157
|
Bundler.settings.without = opts[:without]
|
113
158
|
Bundler.ui.be_quiet! if opts[:quiet]
|
114
159
|
|
@@ -116,6 +161,13 @@ module Bundler
|
|
116
161
|
Bundler.load.cache if Bundler.root.join("vendor/cache").exist?
|
117
162
|
Bundler.ui.confirm "Your bundle is complete! " +
|
118
163
|
"Use `bundle show [gemname]` to see where a bundled gem is installed."
|
164
|
+
|
165
|
+
Bundler.ui.confirm "\nYour bundle was installed to `#{Bundler.settings[:path]}`" if Bundler.settings[:path]
|
166
|
+
|
167
|
+
if path
|
168
|
+
Bundler.ui.warn "\nIf you meant to install it to your system, please remove the\n" \
|
169
|
+
"`#{path}` directory and run `bundle install --system`"
|
170
|
+
end
|
119
171
|
rescue GemNotFound => e
|
120
172
|
if Bundler.definition.no_sources?
|
121
173
|
Bundler.ui.warn "Your Gemfile doesn't have any sources. You can add one with a line like 'source :gemcutter'"
|
@@ -231,8 +283,7 @@ module Bundler
|
|
231
283
|
existing value with the newly provided one.
|
232
284
|
|
233
285
|
By default, setting a configuration value sets it for all projects
|
234
|
-
on the machine.
|
235
|
-
project, use the --local flag.
|
286
|
+
on the machine.
|
236
287
|
|
237
288
|
If a global setting is superceded by local configuration, this command
|
238
289
|
will show the current value, as well as any superceded values and
|
data/lib/bundler/definition.rb
CHANGED
@@ -67,7 +67,12 @@ module Bundler
|
|
67
67
|
current_platform = Gem.platforms.map { |p| generic(p) }.compact.last
|
68
68
|
@platforms |= [current_platform]
|
69
69
|
|
70
|
-
|
70
|
+
if Bundler.production?
|
71
|
+
ensure_equivalent_gemfile_and_lockfile
|
72
|
+
end
|
73
|
+
|
74
|
+
converge_sources
|
75
|
+
converge_dependencies
|
71
76
|
end
|
72
77
|
|
73
78
|
def resolve_with_cache!
|
@@ -122,6 +127,7 @@ module Bundler
|
|
122
127
|
|
123
128
|
def resolve
|
124
129
|
@resolve ||= begin
|
130
|
+
converge_locked_specs
|
125
131
|
if @last_resolve.valid_for?(expanded_dependencies)
|
126
132
|
@last_resolve
|
127
133
|
else
|
@@ -202,17 +208,74 @@ module Bundler
|
|
202
208
|
end
|
203
209
|
|
204
210
|
private
|
211
|
+
def ensure_equivalent_gemfile_and_lockfile
|
212
|
+
changes = false
|
205
213
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
214
|
+
msg = "You have modified your Gemfile in development but did not check\n" \
|
215
|
+
"the resulting snapshot (Gemfile.lock) into version control"
|
216
|
+
|
217
|
+
added = []
|
218
|
+
deleted = []
|
219
|
+
changed = []
|
220
|
+
|
221
|
+
if @locked_sources != @sources
|
222
|
+
new_sources = @sources - @locked_sources
|
223
|
+
deleted_sources = @locked_sources - @sources
|
224
|
+
|
225
|
+
if new_sources.any?
|
226
|
+
added.concat new_sources.map { |source| "* source: #{source}" }
|
227
|
+
end
|
228
|
+
|
229
|
+
if deleted_sources.any?
|
230
|
+
deleted.concat deleted_sources.map { |source| "* source: #{source}" }
|
231
|
+
end
|
232
|
+
|
233
|
+
changes = true
|
234
|
+
end
|
235
|
+
|
236
|
+
both_sources = Hash.new { |h,k| h[k] = ["no specified source", "no specified source"] }
|
237
|
+
@dependencies.each { |d| both_sources[d.name][0] = d.source if d.source }
|
238
|
+
@locked_deps.each { |d| both_sources[d.name][1] = d.source if d.source }
|
239
|
+
both_sources.delete_if { |k,v| v[0] == v[1] }
|
240
|
+
|
241
|
+
if @dependencies != @locked_deps
|
242
|
+
new_deps = @dependencies - @locked_deps
|
243
|
+
deleted_deps = @locked_deps - @dependencies
|
244
|
+
|
245
|
+
if new_deps.any?
|
246
|
+
added.concat new_deps.map { |d| "* #{pretty_dep(d)}" }
|
247
|
+
end
|
248
|
+
|
249
|
+
if deleted_deps.any?
|
250
|
+
deleted.concat deleted_deps.map { |d| "* #{pretty_dep(d)}" }
|
251
|
+
end
|
252
|
+
|
253
|
+
both_sources.each do |name, sources|
|
254
|
+
changed << "* #{name} from `#{sources[0]}` to `#{sources[1]}`"
|
255
|
+
end
|
256
|
+
|
257
|
+
changes = true
|
258
|
+
end
|
259
|
+
|
260
|
+
msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any?
|
261
|
+
msg << "\n\nYou have deleted from the Gemfile:\n" << deleted.join("\n") if deleted.any?
|
262
|
+
msg << "\n\nYou have changed in the Gemfile:\n" << changed.join("\n") if changed.any?
|
263
|
+
|
264
|
+
raise ProductionError, msg if added.any? || deleted.any? || changed.any?
|
265
|
+
end
|
266
|
+
|
267
|
+
def pretty_dep(dep, source = false)
|
268
|
+
msg = "#{dep.name}"
|
269
|
+
msg << " (#{dep.requirement})" unless dep.requirement == Gem::Requirement.default
|
270
|
+
msg << " from the `#{dep.source}` source" if source && dep.source
|
271
|
+
msg
|
210
272
|
end
|
211
273
|
|
212
274
|
def converge_sources
|
213
275
|
@sources.map! do |source|
|
214
276
|
@locked_sources.find { |s| s == source } || source
|
215
277
|
end
|
278
|
+
|
216
279
|
@sources.each do |source|
|
217
280
|
source.unlock! if source.respond_to?(:unlock!) && @unlock[:sources].include?(source.name)
|
218
281
|
end
|
@@ -237,8 +300,12 @@ module Bundler
|
|
237
300
|
# the gem in the Gemfile.lock still satisfies it, this is fine
|
238
301
|
# too.
|
239
302
|
@dependencies.each do |dep|
|
240
|
-
|
303
|
+
locked_dep = @locked_deps.find { |d| dep == d }
|
304
|
+
|
305
|
+
if in_locked_deps?(dep, locked_dep) || satisfies_locked_spec?(dep)
|
241
306
|
deps << dep
|
307
|
+
elsif dep.source.is_a?(Source::Path) && (!locked_dep || dep.source != locked_dep.source)
|
308
|
+
dep.source.specs.each { |s| @unlock[:gems] << s.name }
|
242
309
|
end
|
243
310
|
end
|
244
311
|
|
@@ -271,10 +338,8 @@ module Bundler
|
|
271
338
|
@last_resolve = resolve
|
272
339
|
end
|
273
340
|
|
274
|
-
def in_locked_deps?(dep)
|
275
|
-
|
276
|
-
dep == d && dep.source == d.source
|
277
|
-
end
|
341
|
+
def in_locked_deps?(dep, d)
|
342
|
+
d && dep.source == d.source
|
278
343
|
end
|
279
344
|
|
280
345
|
def satisfies_locked_spec?(dep)
|
data/lib/bundler/dsl.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
module Bundler
|
2
|
-
class DslError < StandardError; end
|
3
|
-
|
4
2
|
class Dsl
|
5
3
|
def self.evaluate(gemfile)
|
6
4
|
builder = new
|
@@ -8,7 +6,7 @@ module Bundler
|
|
8
6
|
builder.to_definition
|
9
7
|
end
|
10
8
|
|
11
|
-
VALID_PLATFORMS = [:ruby, :ruby_18, :ruby_19, :mri, :mri_18, :
|
9
|
+
VALID_PLATFORMS = [:ruby, :ruby_18, :ruby_19, :mri, :mri_18, :mri_19, :jruby, :mswin]
|
12
10
|
|
13
11
|
def initialize
|
14
12
|
@rubygems_source = Source::Rubygems.new
|
@@ -190,7 +188,7 @@ module Bundler
|
|
190
188
|
def _normalize_options(name, version, opts)
|
191
189
|
_normalize_hash(opts)
|
192
190
|
|
193
|
-
invalid_keys = opts.keys - %w(group git path name branch ref tag require submodules)
|
191
|
+
invalid_keys = opts.keys - %w(group git path name branch ref tag require submodules platforms)
|
194
192
|
if invalid_keys.any?
|
195
193
|
plural = invalid_keys.size > 1
|
196
194
|
message = "You passed #{invalid_keys.map{|k| ':'+k }.join(", ")} "
|
data/lib/bundler/resolver.rb
CHANGED
@@ -232,9 +232,6 @@ module Bundler
|
|
232
232
|
# to keep a list of every spot a failure happened.
|
233
233
|
debug { " -> Jumping to: #{parent.name}" }
|
234
234
|
if parent
|
235
|
-
p [parent, parent.name]
|
236
|
-
p current
|
237
|
-
throw parent.name, nil if !existing.respond_to?(:required_by) || !existing.required_by.last
|
238
235
|
throw parent.name, existing.respond_to?(:required_by) && existing.required_by.last.name
|
239
236
|
else
|
240
237
|
# The original set of dependencies conflict with the base set of specs
|
data/lib/bundler/settings.rb
CHANGED
@@ -15,6 +15,10 @@ module Bundler
|
|
15
15
|
set_key(key, value, @local_config, local_config_file)
|
16
16
|
end
|
17
17
|
|
18
|
+
def delete(key)
|
19
|
+
@local_config
|
20
|
+
end
|
21
|
+
|
18
22
|
def set_global(key, value)
|
19
23
|
set_key(key, value, @global_config, global_config_file)
|
20
24
|
end
|
@@ -90,6 +94,7 @@ module Bundler
|
|
90
94
|
|
91
95
|
unless hash[key] == value
|
92
96
|
hash[key] = value
|
97
|
+
hash.delete(key) if value.nil?
|
93
98
|
FileUtils.mkdir_p(file.dirname)
|
94
99
|
File.open(file, "w") { |f| f.puts hash.to_yaml }
|
95
100
|
end
|
data/lib/bundler/version.rb
CHANGED
@@ -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.0.0.rc.
|
5
|
+
VERSION = "1.0.0.rc.2" unless defined?(::Bundler::VERSION)
|
6
6
|
end
|
metadata
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bundler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 15424055
|
5
4
|
prerelease: true
|
6
5
|
segments:
|
7
6
|
- 1
|
8
7
|
- 0
|
9
8
|
- 0
|
10
9
|
- rc
|
11
|
-
-
|
12
|
-
version: 1.0.0.rc.
|
10
|
+
- 2
|
11
|
+
version: 1.0.0.rc.2
|
13
12
|
platform: ruby
|
14
13
|
authors:
|
15
14
|
- Carl Lerche
|
@@ -19,18 +18,16 @@ autorequire:
|
|
19
18
|
bindir: bin
|
20
19
|
cert_chain: []
|
21
20
|
|
22
|
-
date: 2010-07-
|
21
|
+
date: 2010-07-29 00:00:00 -07:00
|
23
22
|
default_executable:
|
24
23
|
dependencies:
|
25
24
|
- !ruby/object:Gem::Dependency
|
26
25
|
name: rspec
|
27
26
|
prerelease: false
|
28
27
|
requirement: &id001 !ruby/object:Gem::Requirement
|
29
|
-
none: false
|
30
28
|
requirements:
|
31
29
|
- - ">="
|
32
30
|
- !ruby/object:Gem::Version
|
33
|
-
hash: 3
|
34
31
|
segments:
|
35
32
|
- 0
|
36
33
|
version: "0"
|
@@ -105,20 +102,16 @@ rdoc_options: []
|
|
105
102
|
require_paths:
|
106
103
|
- lib
|
107
104
|
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
-
none: false
|
109
105
|
requirements:
|
110
106
|
- - ">="
|
111
107
|
- !ruby/object:Gem::Version
|
112
|
-
hash: 3
|
113
108
|
segments:
|
114
109
|
- 0
|
115
110
|
version: "0"
|
116
111
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
|
-
none: false
|
118
112
|
requirements:
|
119
113
|
- - ">="
|
120
114
|
- !ruby/object:Gem::Version
|
121
|
-
hash: 23
|
122
115
|
segments:
|
123
116
|
- 1
|
124
117
|
- 3
|
@@ -127,7 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
120
|
requirements: []
|
128
121
|
|
129
122
|
rubyforge_project: bundler
|
130
|
-
rubygems_version: 1.3.
|
123
|
+
rubygems_version: 1.3.6
|
131
124
|
signing_key:
|
132
125
|
specification_version: 3
|
133
126
|
summary: The best way to manage your application's dependencies
|