bundler 0.9.26 → 1.0.0.beta.1
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 +7 -0
- data/README.md +3 -1
- data/ROADMAP.md +19 -34
- data/TODO.md +16 -0
- data/lib/bundler.rb +87 -41
- data/lib/bundler/cli.rb +115 -73
- data/lib/bundler/definition.rb +203 -34
- data/lib/bundler/dependency.rb +77 -0
- data/lib/bundler/dsl.rb +57 -16
- data/lib/bundler/environment.rb +13 -109
- data/lib/bundler/graph.rb +130 -0
- data/lib/bundler/index.rb +19 -41
- data/lib/bundler/installer.rb +22 -58
- data/lib/bundler/lazy_specification.rb +67 -0
- data/lib/bundler/lockfile_parser.rb +100 -0
- data/lib/bundler/remote_specification.rb +2 -1
- data/lib/bundler/resolver.rb +185 -45
- data/lib/bundler/rubygems_ext.rb +105 -6
- data/lib/bundler/runtime.rb +24 -82
- data/lib/bundler/settings.rb +9 -5
- data/lib/bundler/setup.rb +6 -14
- data/lib/bundler/shared_helpers.rb +2 -25
- data/lib/bundler/source.rb +306 -132
- data/lib/bundler/spec_set.rb +77 -17
- data/lib/bundler/templates/Executable +28 -0
- data/lib/bundler/vendor/thor.rb +31 -4
- data/lib/bundler/vendor/thor/invocation.rb +1 -1
- data/lib/bundler/vendor/thor/parser/arguments.rb +14 -3
- data/lib/bundler/vendor/thor/parser/options.rb +0 -5
- data/lib/bundler/vendor/thor/shell/basic.rb +28 -0
- data/lib/bundler/vendor/thor/task.rb +6 -6
- data/lib/bundler/vendor/thor/util.rb +13 -14
- data/lib/bundler/vendor/thor/version.rb +1 -1
- data/lib/bundler/version.rb +1 -1
- metadata +11 -5
- data/lib/bundler/templates/environment.erb +0 -91
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## 0.10.0
|
2
|
+
|
3
|
+
- No `bundle lock` command. Locking happens automatically on install or update
|
4
|
+
- No .bundle/environment.rb. Require 'bundler/setup' instead.
|
5
|
+
- $BUNDLE_HOME defaults to $GEM_HOME instead of ~/.bundle
|
6
|
+
- Remove lockfiles generated by 0.9
|
7
|
+
|
1
8
|
## 0.9.26
|
2
9
|
|
3
10
|
Features:
|
data/README.md
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
### Note: the master branch is currently unstable while 0.10 is being worked on.<br>The current stable version of bundler is in the branch named `v0.9`.
|
2
|
+
|
1
3
|
## Bundler : A gem to bundle gems
|
2
4
|
|
3
5
|
Bundler is a tool that manages gem dependencies for your ruby application. It
|
@@ -120,7 +122,7 @@ When deploying to a server that is memory-constrained, like Dreamhost, you shoul
|
|
120
122
|
|
121
123
|
### Other questions
|
122
124
|
|
123
|
-
Any remaining questions may be asked via IRC in [#
|
125
|
+
Any remaining questions may be asked via IRC in [#bundler](irc://irc.freenode.net/bundler) on Freenode, or via email on the [Bundler mailing list](http://groups.google.com/group/ruby-bundler).
|
124
126
|
|
125
127
|
## Reporting bugs
|
126
128
|
|
data/ROADMAP.md
CHANGED
@@ -1,51 +1,36 @@
|
|
1
|
-
|
2
|
-
the following reflects our current thinking, critical bugs may alter it
|
3
|
-
somewhat.
|
4
|
-
|
5
|
-
# 0.10
|
1
|
+
# 1.0
|
6
2
|
|
7
3
|
- No breaking changes to the Gemfile are expected
|
8
4
|
- We expect to modify the format of Gemfile.lock.
|
9
|
-
- This should be the final change
|
10
|
-
-
|
11
|
-
|
12
|
-
|
13
|
-
directly from 0.9 to 1.0.
|
14
|
-
- Bundler 0.10 will automatically generate Gemfile.lock when any
|
5
|
+
- This should be the final change
|
6
|
+
- This means you will not be able to upgrade a locked app
|
7
|
+
directly from 0.9 to 1.0.
|
8
|
+
- Bundler will automatically generate Gemfile.lock when any
|
15
9
|
resolve is successful.
|
16
|
-
|
10
|
+
- This means the bundle lock command will no longer be needed.
|
11
|
+
- Bundler will conservatively update Gemfile.lock from the
|
17
12
|
last successful resolve if the Gemfile has been modified since
|
18
13
|
the last use of bundler.
|
19
14
|
- This means that adding a new gem to the Gemfile that does not
|
20
|
-
|
21
|
-
|
15
|
+
conflict with existing gems will not force an update of other
|
16
|
+
gems.
|
22
17
|
- This also means that we will not force an update to previously
|
23
|
-
|
24
|
-
|
18
|
+
resolved dependencies as long as they are compatible with some
|
19
|
+
valid version of the new dependency.
|
25
20
|
- When removing a gem, bundle install will simply remove it, without
|
26
|
-
|
21
|
+
recalculating all dependencies.
|
27
22
|
- We will be adding `bundle update` for the case where you -do-
|
28
23
|
wish to re-resolve all dependencies and update everything to the
|
29
24
|
latest version.
|
30
25
|
- bundle update will also take a gem name, if you want to force
|
31
|
-
|
32
|
-
-
|
33
|
-
-
|
34
|
-
|
35
|
-
- Some additional features that we have tagged for 0.10. For up
|
36
|
-
to date information, please visit
|
37
|
-
http://github.com/carlhuda/bundler/issues/labels/0.10
|
38
|
-
|
39
|
-
# 1.0
|
40
|
-
|
41
|
-
- No breaking changes to the Gemfile are expected
|
42
|
-
- No breaking changes to the Gemfile.lock are expected
|
43
|
-
- No major changes to the workflow are expected
|
44
|
-
- Reduce open bug count to 0
|
26
|
+
an update to just a single gem (and its dependencies).
|
27
|
+
- There will be a way to install dependencies that require build options
|
28
|
+
- We will add groups that are opt-in at install-time, rather than opt-out.
|
29
|
+
- We will reduce open bug count to 0 for the final 1.0 release.
|
45
30
|
- Some additional features that require more thought. For details,
|
46
31
|
see http://github.com/carlhuda/bundler/issues/labels/1.0
|
47
32
|
|
48
|
-
#
|
33
|
+
# 1.1
|
49
34
|
|
50
|
-
|
51
|
-
|
35
|
+
- Stop upgrading 0.9 lockfiles
|
36
|
+
- Delete vestigial gems installed into ~/.bundle/ by 0.9
|
data/TODO.md
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
## Bundler TODO list
|
2
|
+
|
3
|
+
- Check to make sure ~/.bundler/bin is in $PATH
|
4
|
+
- Cache Git repositories
|
5
|
+
- Interactive mode for bundle (install) to work out conflicts
|
6
|
+
- bundle irb / bundle ruby / bundle [whatever] -> bundle exec
|
7
|
+
- Make bundle (install) work when sudo might be needed
|
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/lib/bundler.rb
CHANGED
@@ -5,12 +5,17 @@ require 'bundler/rubygems_ext'
|
|
5
5
|
require 'bundler/version'
|
6
6
|
|
7
7
|
module Bundler
|
8
|
+
ORIGINAL_ENV = ENV.to_hash
|
9
|
+
|
8
10
|
autoload :Definition, 'bundler/definition'
|
9
11
|
autoload :Dependency, 'bundler/dependency'
|
10
12
|
autoload :Dsl, 'bundler/dsl'
|
11
13
|
autoload :Environment, 'bundler/environment'
|
14
|
+
autoload :Graph, 'bundler/graph'
|
12
15
|
autoload :Index, 'bundler/index'
|
13
16
|
autoload :Installer, 'bundler/installer'
|
17
|
+
autoload :LazySpecification, 'bundler/lazy_specification'
|
18
|
+
autoload :LockfileParser, 'bundler/lockfile_parser'
|
14
19
|
autoload :RemoteSpecification, 'bundler/remote_specification'
|
15
20
|
autoload :Resolver, 'bundler/resolver'
|
16
21
|
autoload :Runtime, 'bundler/runtime'
|
@@ -21,9 +26,6 @@ module Bundler
|
|
21
26
|
autoload :Specification, 'bundler/shared_helpers'
|
22
27
|
autoload :UI, 'bundler/ui'
|
23
28
|
|
24
|
-
GEM_LOADED = true
|
25
|
-
ORIGINAL_ENV = ENV.to_hash
|
26
|
-
|
27
29
|
class BundlerError < StandardError
|
28
30
|
def self.status_code(code = nil)
|
29
31
|
return @code unless code
|
@@ -37,7 +39,6 @@ module Bundler
|
|
37
39
|
|
38
40
|
class GemfileNotFound < BundlerError; status_code(10) ; end
|
39
41
|
class GemNotFound < BundlerError; status_code(7) ; end
|
40
|
-
class VersionConflict < BundlerError; status_code(6) ; end
|
41
42
|
class GemfileError < BundlerError; status_code(4) ; end
|
42
43
|
class GemfileChanged < GemfileError; status_code(4) ; end
|
43
44
|
class PathError < BundlerError; status_code(13) ; end
|
@@ -45,8 +46,23 @@ module Bundler
|
|
45
46
|
class GemspecError < BundlerError; status_code(14) ; end
|
46
47
|
class DeprecatedMethod < BundlerError; status_code(12) ; end
|
47
48
|
class DeprecatedOption < BundlerError; status_code(12) ; end
|
49
|
+
class GemspecError < BundlerError; status_code(14) ; end
|
48
50
|
class InvalidOption < BundlerError; status_code(15) ; end
|
49
51
|
|
52
|
+
class VersionConflict < BundlerError
|
53
|
+
attr_reader :conflicts
|
54
|
+
|
55
|
+
def initialize(conflicts, msg = nil)
|
56
|
+
super(msg)
|
57
|
+
@conflicts = conflicts
|
58
|
+
end
|
59
|
+
|
60
|
+
status_code(6)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Internal errors, should be rescued
|
64
|
+
class InvalidSpecSet < StandardError; end
|
65
|
+
|
50
66
|
class << self
|
51
67
|
attr_writer :ui, :bundle_path
|
52
68
|
|
@@ -63,12 +79,20 @@ module Bundler
|
|
63
79
|
|
64
80
|
def bundle_path
|
65
81
|
@bundle_path ||= begin
|
66
|
-
path = settings[:path] ||
|
82
|
+
path = settings[:path] || Gem.dir
|
67
83
|
Pathname.new(path).expand_path(root)
|
68
84
|
end
|
69
85
|
end
|
70
86
|
|
71
|
-
def
|
87
|
+
def bin_path
|
88
|
+
@bin_path ||= begin
|
89
|
+
path = settings[:bin] || "#{Gem.user_home}/.bundle/bin"
|
90
|
+
FileUtils.mkdir_p(path)
|
91
|
+
Pathname.new(path).expand_path
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def setup(*groups)
|
72
96
|
return @setup if @setup
|
73
97
|
|
74
98
|
if groups.empty?
|
@@ -83,35 +107,26 @@ module Bundler
|
|
83
107
|
unloaded.any? ? load.setup(*unloaded) : load
|
84
108
|
end
|
85
109
|
end
|
86
|
-
alias setup gem_setup unless defined?(Bundler::ENV_LOADED)
|
87
110
|
|
88
|
-
def
|
111
|
+
def require(*groups)
|
89
112
|
setup(*groups).require(*groups)
|
90
113
|
end
|
91
|
-
alias require gem_require unless defined?(Bundler::ENV_LOADED)
|
92
114
|
|
93
115
|
def load
|
94
|
-
@load ||=
|
95
|
-
if !update_env_file?
|
96
|
-
Kernel.require env_file
|
97
|
-
Bundler
|
98
|
-
else
|
99
|
-
runtime
|
100
|
-
end
|
101
|
-
end
|
116
|
+
@load ||= Runtime.new(root, definition)
|
102
117
|
end
|
103
118
|
|
104
|
-
def
|
105
|
-
|
119
|
+
def environment
|
120
|
+
Bundler::Environment.new(root, definition)
|
106
121
|
end
|
107
122
|
|
108
|
-
def definition
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
Definition.
|
123
|
+
def definition(unlock = nil)
|
124
|
+
@definition = nil if unlock
|
125
|
+
@definition ||= begin
|
126
|
+
configure
|
127
|
+
upgrade_lockfile
|
128
|
+
lockfile = root.join("Gemfile.lock")
|
129
|
+
Definition.build(default_gemfile, lockfile, unlock)
|
115
130
|
end
|
116
131
|
end
|
117
132
|
|
@@ -132,15 +147,19 @@ module Bundler
|
|
132
147
|
end
|
133
148
|
|
134
149
|
def root
|
135
|
-
default_gemfile.dirname
|
150
|
+
default_gemfile.dirname.expand_path
|
136
151
|
end
|
137
152
|
|
138
|
-
def
|
139
|
-
|
153
|
+
def app_cache
|
154
|
+
root.join("vendor/cache")
|
155
|
+
end
|
156
|
+
|
157
|
+
def tmp
|
158
|
+
"#{Gem.user_home}/.bundler/tmp"
|
140
159
|
end
|
141
160
|
|
142
|
-
def
|
143
|
-
|
161
|
+
def settings
|
162
|
+
@settings ||= Settings.new(root)
|
144
163
|
end
|
145
164
|
|
146
165
|
def with_clean_env
|
@@ -155,6 +174,22 @@ module Bundler
|
|
155
174
|
SharedHelpers.default_gemfile
|
156
175
|
end
|
157
176
|
|
177
|
+
WINDOWS = Config::CONFIG["host_os"] =~ %r!(msdos|mswin|djgpp|mingw)!
|
178
|
+
NULL = WINDOWS ? "NUL" : "/dev/null"
|
179
|
+
|
180
|
+
def requires_sudo?
|
181
|
+
case
|
182
|
+
when File.writable?(bundle_path) ||
|
183
|
+
`which sudo 2>#{NULL}`.empty? ||
|
184
|
+
File.owned?(bundle_path)
|
185
|
+
false
|
186
|
+
else
|
187
|
+
true
|
188
|
+
end
|
189
|
+
rescue Errno::ENOENT
|
190
|
+
false
|
191
|
+
end
|
192
|
+
|
158
193
|
private
|
159
194
|
|
160
195
|
def configure_gem_home_and_path
|
@@ -170,17 +205,28 @@ module Bundler
|
|
170
205
|
Gem.clear_paths
|
171
206
|
end
|
172
207
|
|
173
|
-
def
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
208
|
+
def upgrade_lockfile
|
209
|
+
lockfile = root.join("Gemfile.lock")
|
210
|
+
if lockfile.exist? && lockfile.read(3) == "---"
|
211
|
+
Bundler.ui.warn "Detected Gemfile.lock generated by 0.9, deleting..."
|
212
|
+
lockfile.rmtree
|
213
|
+
# lock = YAML.load_file(lockfile)
|
214
|
+
#
|
215
|
+
# source_uris = lock["sources"].map{|s| s["Rubygems"]["uri"] }
|
216
|
+
# sources = [Bundler::Source::Rubygems.new({"remotes" => source_uris})]
|
217
|
+
#
|
218
|
+
# deps = lock["dependencies"].map do |name, opts|
|
219
|
+
# version = opts.delete("version")
|
220
|
+
# Bundler::Dependency.new(name, version, opts)
|
221
|
+
# end
|
222
|
+
#
|
223
|
+
# definition = Bundler::Definition.new(nil, deps, sources, {})
|
224
|
+
#
|
225
|
+
# File.open(lockfile, 'w') do |f|
|
226
|
+
# f.write definition.to_lock
|
227
|
+
# end
|
183
228
|
end
|
184
229
|
end
|
230
|
+
|
185
231
|
end
|
186
232
|
end
|
data/lib/bundler/cli.rb
CHANGED
@@ -7,9 +7,22 @@ Gem.configuration
|
|
7
7
|
|
8
8
|
module Bundler
|
9
9
|
class CLI < Thor
|
10
|
+
def initialize(*)
|
11
|
+
super
|
12
|
+
Bundler.ui = UI::Shell.new(shell)
|
13
|
+
Gem::DefaultUserInteraction.ui = UI::RGProxy.new(Bundler.ui)
|
14
|
+
end
|
15
|
+
|
10
16
|
check_unknown_options! unless ARGV.include?("exec")
|
11
17
|
|
18
|
+
default_task :install
|
19
|
+
|
12
20
|
desc "init", "Generates a Gemfile into the current working directory"
|
21
|
+
long_desc <<-D
|
22
|
+
Init generates a default Gemfile in the current working directory. When adding a
|
23
|
+
Gemfile to a gem with a gemspec, the --gemspec option will automatically add each
|
24
|
+
dependency listed in the gemspec file to the newly created Gemfile.
|
25
|
+
D
|
13
26
|
method_option "gemspec", :type => :string, :banner => "Use the specified .gemspec to create the Gemfile"
|
14
27
|
def init
|
15
28
|
opts = options.dup
|
@@ -36,44 +49,46 @@ module Bundler
|
|
36
49
|
end
|
37
50
|
end
|
38
51
|
|
39
|
-
def initialize(*)
|
40
|
-
super
|
41
|
-
Bundler.ui = UI::Shell.new(shell)
|
42
|
-
Gem::DefaultUserInteraction.ui = UI::RGProxy.new(Bundler.ui)
|
43
|
-
end
|
44
|
-
|
45
52
|
desc "check", "Checks if the dependencies listed in Gemfile are satisfied by currently installed gems"
|
53
|
+
long_desc <<-D
|
54
|
+
Check searches the local machine for each of the gems requested in the Gemfile. If
|
55
|
+
all gems are found, Bundler prints a success message and exits with a status of 0.
|
56
|
+
If not, the first missing gem is listed and Bundler exits status 1.
|
57
|
+
D
|
46
58
|
def check
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
Bundler.ui.error "
|
52
|
-
missing.each do |d|
|
53
|
-
Bundler.ui.error " * #{d}"
|
54
|
-
end
|
59
|
+
not_installed = Bundler.definition.missing_specs
|
60
|
+
|
61
|
+
if not_installed.any?
|
62
|
+
Bundler.ui.error "The following gems are missing"
|
63
|
+
not_installed.each { |s| Bundler.ui.error " * #{s.name} (#{s.version})" }
|
55
64
|
Bundler.ui.warn "Install missing gems with `bundle install`"
|
56
65
|
exit 1
|
57
66
|
else
|
58
|
-
|
59
|
-
|
60
|
-
if not_installed.any?
|
61
|
-
not_installed.each { |s| Bundler.ui.error "#{s.name} (#{s.version}) is cached, but not installed" }
|
62
|
-
Bundler.ui.warn "Install missing gems with `bundle install`"
|
63
|
-
exit 1
|
64
|
-
else
|
65
|
-
Bundler.ui.info "The Gemfile's dependencies are satisfied"
|
66
|
-
end
|
67
|
+
Bundler.ui.info "The Gemfile's dependencies are satisfied"
|
67
68
|
end
|
68
69
|
end
|
69
70
|
|
70
71
|
desc "install", "Install the current environment to the system"
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
72
|
+
long_desc <<-D
|
73
|
+
Install will install all of the gems in the current bundle, making them available
|
74
|
+
for use. In a freshly checked out repository, this command will give you the same
|
75
|
+
gem versions as the last person who updated the Gemfile and ran `bundle update`.
|
76
|
+
|
77
|
+
Passing [DIR] to install (e.g. vendor) will cause the unpacked gems to be installed
|
78
|
+
into the [DIR] directory rather than into system gems.
|
79
|
+
|
80
|
+
If the bundle has already been installed, bundler will tell you so and then exit.
|
81
|
+
D
|
82
|
+
method_option "without", :type => :array, :banner =>
|
83
|
+
"Exclude gems that are part of the specified named group."
|
84
|
+
method_option "disable-shared-gems", :type => :boolean, :banner =>
|
85
|
+
"Do not use any shared gems, such as the system gem repository."
|
86
|
+
method_option "gemfile", :type => :string, :banner =>
|
87
|
+
"Use the specified gemfile instead of Gemfile"
|
88
|
+
method_option "no-prune", :type => :boolean, :banner =>
|
89
|
+
"Don't remove stale gems from the cache."
|
90
|
+
method_option "no-cache", :type => :boolean, :banner =>
|
91
|
+
"Don't update the existing gem cache."
|
77
92
|
def install(path = nil)
|
78
93
|
opts = options.dup
|
79
94
|
opts[:without] ||= []
|
@@ -82,62 +97,61 @@ module Bundler
|
|
82
97
|
# Can't use Bundler.settings for this because settings needs gemfile.dirname
|
83
98
|
ENV['BUNDLE_GEMFILE'] = opts[:gemfile] if opts[:gemfile]
|
84
99
|
Bundler.settings[:path] = path if path
|
85
|
-
Bundler.settings[:disable_shared_gems] = '1' if options["disable-shared-gems"]
|
100
|
+
Bundler.settings[:disable_shared_gems] = '1' if options["disable-shared-gems"] || path
|
86
101
|
Bundler.settings.without = opts[:without]
|
87
102
|
|
88
|
-
|
89
|
-
|
90
|
-
begin
|
91
|
-
Installer.install(Bundler.root, Bundler.definition, opts)
|
92
|
-
rescue GemfileChanged
|
93
|
-
raise GemfileChanged, "You changed your Gemfile after locking. " +
|
94
|
-
"Please run `bundle install --relock`."
|
95
|
-
end
|
96
|
-
|
97
|
-
lock if options[:relock]
|
98
|
-
cache if Bundler.root.join("vendor/cache").exist? && !options[:no_cache]
|
103
|
+
Installer.install(Bundler.root, Bundler.definition, opts)
|
104
|
+
cache if Bundler.root.join("vendor/cache").exist?
|
99
105
|
Bundler.ui.confirm "Your bundle is complete! " +
|
100
106
|
"Use `bundle show [gemname]` to see where a bundled gem is installed."
|
101
107
|
rescue GemNotFound => e
|
102
|
-
if Bundler.definition.
|
108
|
+
if Bundler.definition.no_sources?
|
103
109
|
Bundler.ui.warn "Your Gemfile doesn't have any sources. You can add one with a line like 'source :gemcutter'"
|
104
110
|
end
|
105
111
|
raise e
|
106
112
|
end
|
107
113
|
|
108
|
-
desc "
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
114
|
+
desc "update", "update the current environment"
|
115
|
+
long_desc <<-D
|
116
|
+
Update will install the newest versions of the gems listed in the Gemfile. Use
|
117
|
+
update when you have changed the Gemfile, or if you want to get the newest
|
118
|
+
possible versions of the gems in the bundle.
|
119
|
+
D
|
120
|
+
method_option "source", :type => :array, :banner => "Update a specific source (and all gems associated with it)"
|
121
|
+
def update(*gems)
|
122
|
+
sources = Array(options[:source])
|
123
|
+
|
124
|
+
if gems.empty? && sources.empty?
|
125
|
+
# We're doing a full update
|
126
|
+
FileUtils.rm Bundler.root.join("Gemfile.lock")
|
127
|
+
else
|
128
|
+
Bundler.definition(:gems => gems, :sources => sources)
|
113
129
|
end
|
114
130
|
|
115
|
-
Bundler.
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
Bundler.ui.warn "
|
121
|
-
exit 128
|
131
|
+
Installer.install Bundler.root, Bundler.definition
|
132
|
+
end
|
133
|
+
|
134
|
+
desc "lock", "Locks the bundle to the current set of dependencies, including all child dependencies."
|
135
|
+
def lock
|
136
|
+
Bundler.ui.warn "Lock is deprecated. Your bundle is now locked whenever you run `bundle install`."
|
122
137
|
end
|
123
138
|
|
124
139
|
desc "unlock", "Unlock the bundle. This allows gem versions to be changed."
|
125
140
|
def unlock
|
126
|
-
|
127
|
-
remove_lockfiles
|
128
|
-
Bundler.ui.info("Your bundle is now unlocked. The dependencies may be changed.")
|
129
|
-
else
|
130
|
-
Bundler.ui.info("Your bundle is not currently locked.")
|
131
|
-
end
|
141
|
+
Bundler.ui.warn "Unlock is deprecated. To update to newer gem versions, use `bundle update`."
|
132
142
|
end
|
133
143
|
|
134
144
|
desc "show [GEM]", "Shows all gems that are part of the bundle, or the path to a given gem"
|
145
|
+
long_desc <<-D
|
146
|
+
Show lists the names and versions of all gems that are required by your Gemfile.
|
147
|
+
Calling show with [GEM] will list the exact location of that gem on your machine.
|
148
|
+
D
|
135
149
|
def show(gem_name = nil)
|
136
150
|
if gem_name
|
137
151
|
Bundler.ui.info locate_gem(gem_name)
|
138
152
|
else
|
139
153
|
Bundler.ui.info "Gems included by the bundle:"
|
140
|
-
Bundler.
|
154
|
+
Bundler.load.specs.sort_by { |s| s.name }.each do |s|
|
141
155
|
Bundler.ui.info " * #{s.name} (#{s.version}#{s.git_version})"
|
142
156
|
end
|
143
157
|
end
|
@@ -147,8 +161,8 @@ module Bundler
|
|
147
161
|
desc "cache", "Cache all the gems to vendor/cache"
|
148
162
|
method_option "no-prune", :type => :boolean, :banner => "Don't remove stale gems from the cache."
|
149
163
|
def cache
|
150
|
-
Bundler.
|
151
|
-
Bundler.
|
164
|
+
Bundler.load.cache
|
165
|
+
Bundler.load.prune_cache unless options[:no_prune]
|
152
166
|
rescue GemNotFound => e
|
153
167
|
Bundler.ui.error(e.message)
|
154
168
|
Bundler.ui.warn "Run `bundle install` to install missing gems."
|
@@ -157,13 +171,25 @@ module Bundler
|
|
157
171
|
|
158
172
|
desc "package", "Locks and then caches all of the gems into vendor/cache"
|
159
173
|
method_option "no-prune", :type => :boolean, :banner => "Don't remove stale gems from the cache."
|
174
|
+
long_desc <<-D
|
175
|
+
The package command will copy the .gem files for every gem in the bundle into the
|
176
|
+
directory ./vendor/cache. If you then check that directory into your source
|
177
|
+
control repository, others who check out your source will be able to install the
|
178
|
+
bundle without having to download any additional gems.
|
179
|
+
D
|
160
180
|
def package
|
161
|
-
|
181
|
+
install
|
182
|
+
# TODO: move cache contents here now that all bundles are locked
|
162
183
|
cache
|
163
184
|
end
|
164
185
|
map %w(pack) => :package
|
165
186
|
|
166
187
|
desc "exec", "Run the command in context of the bundle"
|
188
|
+
long_desc <<-D
|
189
|
+
Exec runs a command, providing it access to the gems in the bundle. While using
|
190
|
+
bundle exec you can require and call the bundled gems as if they were installed
|
191
|
+
into the systemwide Rubygems repository.
|
192
|
+
D
|
167
193
|
def exec(*)
|
168
194
|
ARGV.delete("exec")
|
169
195
|
|
@@ -185,7 +211,7 @@ module Bundler
|
|
185
211
|
|
186
212
|
begin
|
187
213
|
# Run
|
188
|
-
Kernel.exec
|
214
|
+
Kernel.exec(*ARGV)
|
189
215
|
rescue Errno::EACCES
|
190
216
|
Bundler.ui.error "bundler: not executable: #{ARGV.first}"
|
191
217
|
rescue Errno::ENOENT
|
@@ -222,19 +248,35 @@ module Bundler
|
|
222
248
|
end
|
223
249
|
map %w(-v --version) => :version
|
224
250
|
|
225
|
-
|
251
|
+
desc 'viz', "Generates a visual dependency graph"
|
252
|
+
method_option :file, :type => :string, :default => 'gem_graph.png', :aliases => '-f', :banner => "Show the version with each gem name."
|
253
|
+
method_option :version, :type => :boolean, :default => false, :aliases => '-v', :banner => "Show the version with each gem name."
|
254
|
+
method_option :requirements, :type => :boolean, :default => false, :aliases => '-r', :banner => "Show the requirement for each dependency."
|
255
|
+
def viz
|
256
|
+
output_file = File.expand_path(options[:file])
|
257
|
+
graph = Graph.new( Bundler.load )
|
226
258
|
|
227
|
-
|
228
|
-
|
259
|
+
begin
|
260
|
+
graph.viz(output_file, options[:version], options[:requirements])
|
261
|
+
Bundler.ui.info output_file
|
262
|
+
rescue LoadError => e
|
263
|
+
Bundler.ui.error e.inspect
|
264
|
+
Bundler.ui.warn "Make sure you have the graphviz ruby gem. You can install it with:"
|
265
|
+
Bundler.ui.warn "`gem install ruby-graphviz`"
|
266
|
+
rescue StandardError => e
|
267
|
+
if e.message =~ /GraphViz not installed or dot not in PATH/
|
268
|
+
Bundler.ui.error e.message
|
269
|
+
Bundler.ui.warn "The ruby graphviz gem requires GraphViz to be installed"
|
270
|
+
else
|
271
|
+
raise
|
272
|
+
end
|
273
|
+
end
|
229
274
|
end
|
230
275
|
|
231
|
-
|
232
|
-
FileUtils.rm_f "#{Bundler.root}/Gemfile.lock"
|
233
|
-
FileUtils.rm_f "#{Bundler.root}/.bundle/environment.rb"
|
234
|
-
end
|
276
|
+
private
|
235
277
|
|
236
278
|
def locate_gem(name)
|
237
|
-
spec = Bundler.
|
279
|
+
spec = Bundler.load.specs.find{|s| s.name == name }
|
238
280
|
raise GemNotFound, "Could not find gem '#{name}' in the current bundle." unless spec
|
239
281
|
spec.full_gem_path
|
240
282
|
end
|