bundler 0.8.1 → 0.9.0.pre1
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/README +7 -0
- data/bin/bundle +3 -0
- data/lib/bundler.rb +72 -37
- data/lib/bundler/cli.rb +64 -68
- data/lib/bundler/definition.rb +78 -0
- data/lib/bundler/dependency.rb +7 -57
- data/lib/bundler/dsl.rb +42 -142
- data/lib/bundler/environment.rb +94 -54
- data/lib/bundler/index.rb +98 -0
- data/lib/bundler/installer.rb +137 -0
- data/lib/bundler/remote_specification.rb +1 -1
- data/lib/bundler/resolver.rb +20 -50
- data/lib/bundler/rubygems.rb +22 -0
- data/lib/bundler/source.rb +185 -295
- data/lib/bundler/specification.rb +22 -0
- data/lib/bundler/templates/Gemfile +4 -0
- data/lib/bundler/templates/environment.erb +3 -153
- data/lib/bundler/ui.rb +51 -0
- data/lib/bundler/vendor/thor.rb +241 -0
- data/lib/bundler/vendor/thor/actions.rb +274 -0
- data/lib/bundler/vendor/thor/actions/create_file.rb +103 -0
- data/lib/bundler/vendor/thor/actions/directory.rb +91 -0
- data/lib/bundler/vendor/thor/actions/empty_directory.rb +134 -0
- data/lib/bundler/vendor/thor/actions/file_manipulation.rb +223 -0
- data/lib/bundler/vendor/thor/actions/inject_into_file.rb +101 -0
- data/lib/bundler/vendor/thor/base.rb +515 -0
- data/lib/bundler/vendor/thor/core_ext/file_binary_read.rb +9 -0
- data/lib/bundler/vendor/thor/core_ext/hash_with_indifferent_access.rb +75 -0
- data/lib/bundler/vendor/thor/core_ext/ordered_hash.rb +100 -0
- data/lib/bundler/vendor/thor/error.rb +27 -0
- data/lib/bundler/vendor/thor/group.rb +267 -0
- data/lib/bundler/vendor/thor/invocation.rb +178 -0
- data/lib/bundler/vendor/thor/parser.rb +4 -0
- data/lib/bundler/vendor/thor/parser/argument.rb +67 -0
- data/lib/bundler/vendor/thor/parser/arguments.rb +145 -0
- data/lib/bundler/vendor/thor/parser/option.rb +132 -0
- data/lib/bundler/vendor/thor/parser/options.rb +142 -0
- data/lib/bundler/vendor/thor/rake_compat.rb +66 -0
- data/lib/bundler/vendor/thor/runner.rb +303 -0
- data/lib/bundler/vendor/thor/shell.rb +78 -0
- data/lib/bundler/vendor/thor/shell/basic.rb +239 -0
- data/lib/bundler/vendor/thor/shell/color.rb +108 -0
- data/lib/bundler/vendor/thor/task.rb +111 -0
- data/lib/bundler/vendor/thor/util.rb +233 -0
- data/lib/bundler/vendor/thor/version.rb +3 -0
- metadata +48 -26
- data/README.markdown +0 -284
- data/Rakefile +0 -81
- data/lib/bundler/bundle.rb +0 -314
- data/lib/bundler/commands/bundle_command.rb +0 -72
- data/lib/bundler/commands/exec_command.rb +0 -36
- data/lib/bundler/finder.rb +0 -51
- data/lib/bundler/gem_bundle.rb +0 -11
- data/lib/bundler/gem_ext.rb +0 -34
- data/lib/bundler/runtime.rb +0 -2
- data/lib/bundler/templates/app_script.erb +0 -3
- data/lib/bundler/templates/environment_picker.erb +0 -4
- data/lib/rubygems_plugin.rb +0 -6
@@ -0,0 +1,233 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
|
3
|
+
class Thor
|
4
|
+
module Sandbox #:nodoc:
|
5
|
+
end
|
6
|
+
|
7
|
+
# This module holds several utilities:
|
8
|
+
#
|
9
|
+
# 1) Methods to convert thor namespaces to constants and vice-versa.
|
10
|
+
#
|
11
|
+
# Thor::Utils.namespace_from_thor_class(Foo::Bar::Baz) #=> "foo:bar:baz"
|
12
|
+
#
|
13
|
+
# 2) Loading thor files and sandboxing:
|
14
|
+
#
|
15
|
+
# Thor::Utils.load_thorfile("~/.thor/foo")
|
16
|
+
#
|
17
|
+
module Util
|
18
|
+
|
19
|
+
# Receives a namespace and search for it in the Thor::Base subclasses.
|
20
|
+
#
|
21
|
+
# ==== Parameters
|
22
|
+
# namespace<String>:: The namespace to search for.
|
23
|
+
#
|
24
|
+
def self.find_by_namespace(namespace)
|
25
|
+
namespace = "default#{namespace}" if namespace.empty? || namespace =~ /^:/
|
26
|
+
|
27
|
+
Thor::Base.subclasses.find do |klass|
|
28
|
+
klass.namespace == namespace
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Receives a constant and converts it to a Thor namespace. Since Thor tasks
|
33
|
+
# can be added to a sandbox, this method is also responsable for removing
|
34
|
+
# the sandbox namespace.
|
35
|
+
#
|
36
|
+
# This method should not be used in general because it's used to deal with
|
37
|
+
# older versions of Thor. On current versions, if you need to get the
|
38
|
+
# namespace from a class, just call namespace on it.
|
39
|
+
#
|
40
|
+
# ==== Parameters
|
41
|
+
# constant<Object>:: The constant to be converted to the thor path.
|
42
|
+
#
|
43
|
+
# ==== Returns
|
44
|
+
# String:: If we receive Foo::Bar::Baz it returns "foo:bar:baz"
|
45
|
+
#
|
46
|
+
def self.namespace_from_thor_class(constant, remove_default=true)
|
47
|
+
constant = constant.to_s.gsub(/^Thor::Sandbox::/, "")
|
48
|
+
constant = snake_case(constant).squeeze(":")
|
49
|
+
constant.gsub!(/^default/, '') if remove_default
|
50
|
+
constant
|
51
|
+
end
|
52
|
+
|
53
|
+
# Given the contents, evaluate it inside the sandbox and returns the
|
54
|
+
# namespaces defined in the sandbox.
|
55
|
+
#
|
56
|
+
# ==== Parameters
|
57
|
+
# contents<String>
|
58
|
+
#
|
59
|
+
# ==== Returns
|
60
|
+
# Array[Object]
|
61
|
+
#
|
62
|
+
def self.namespaces_in_content(contents, file=__FILE__)
|
63
|
+
old_constants = Thor::Base.subclasses.dup
|
64
|
+
Thor::Base.subclasses.clear
|
65
|
+
|
66
|
+
load_thorfile(file, contents)
|
67
|
+
|
68
|
+
new_constants = Thor::Base.subclasses.dup
|
69
|
+
Thor::Base.subclasses.replace(old_constants)
|
70
|
+
|
71
|
+
new_constants.map!{ |c| c.namespace }
|
72
|
+
new_constants.compact!
|
73
|
+
new_constants
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns the thor classes declared inside the given class.
|
77
|
+
#
|
78
|
+
def self.thor_classes_in(klass)
|
79
|
+
stringfied_constants = klass.constants.map { |c| c.to_s }
|
80
|
+
Thor::Base.subclasses.select do |subclass|
|
81
|
+
next unless subclass.name
|
82
|
+
stringfied_constants.include?(subclass.name.gsub("#{klass.name}::", ''))
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Receives a string and convert it to snake case. SnakeCase returns snake_case.
|
87
|
+
#
|
88
|
+
# ==== Parameters
|
89
|
+
# String
|
90
|
+
#
|
91
|
+
# ==== Returns
|
92
|
+
# String
|
93
|
+
#
|
94
|
+
def self.snake_case(str)
|
95
|
+
return str.downcase if str =~ /^[A-Z_]+$/
|
96
|
+
str.gsub(/\B[A-Z]/, '_\&').squeeze('_') =~ /_*(.*)/
|
97
|
+
return $+.downcase
|
98
|
+
end
|
99
|
+
|
100
|
+
# Receives a string and convert it to camel case. camel_case returns CamelCase.
|
101
|
+
#
|
102
|
+
# ==== Parameters
|
103
|
+
# String
|
104
|
+
#
|
105
|
+
# ==== Returns
|
106
|
+
# String
|
107
|
+
#
|
108
|
+
def self.camel_case(str)
|
109
|
+
return str if str !~ /_/ && str =~ /[A-Z]+.*/
|
110
|
+
str.split('_').map { |i| i.capitalize }.join
|
111
|
+
end
|
112
|
+
|
113
|
+
# Receives a namespace and tries to retrieve a Thor or Thor::Group class
|
114
|
+
# from it. It first searches for a class using the all the given namespace,
|
115
|
+
# if it's not found, removes the highest entry and searches for the class
|
116
|
+
# again. If found, returns the highest entry as the class name.
|
117
|
+
#
|
118
|
+
# ==== Examples
|
119
|
+
#
|
120
|
+
# class Foo::Bar < Thor
|
121
|
+
# def baz
|
122
|
+
# end
|
123
|
+
# end
|
124
|
+
#
|
125
|
+
# class Baz::Foo < Thor::Group
|
126
|
+
# end
|
127
|
+
#
|
128
|
+
# Thor::Util.namespace_to_thor_class("foo:bar") #=> Foo::Bar, nil # will invoke default task
|
129
|
+
# Thor::Util.namespace_to_thor_class("baz:foo") #=> Baz::Foo, nil
|
130
|
+
# Thor::Util.namespace_to_thor_class("foo:bar:baz") #=> Foo::Bar, "baz"
|
131
|
+
#
|
132
|
+
# ==== Parameters
|
133
|
+
# namespace<String>
|
134
|
+
#
|
135
|
+
# ==== Errors
|
136
|
+
# Thor::Error:: raised if the namespace cannot be found.
|
137
|
+
#
|
138
|
+
# Thor::Error:: raised if the namespace evals to a class which does not
|
139
|
+
# inherit from Thor or Thor::Group.
|
140
|
+
#
|
141
|
+
def self.namespace_to_thor_class_and_task(namespace, raise_if_nil=true)
|
142
|
+
if namespace.include?(?:)
|
143
|
+
pieces = namespace.split(":")
|
144
|
+
task = pieces.pop
|
145
|
+
klass = Thor::Util.find_by_namespace(pieces.join(":"))
|
146
|
+
end
|
147
|
+
|
148
|
+
unless klass
|
149
|
+
klass, task = Thor::Util.find_by_namespace(namespace), nil
|
150
|
+
end
|
151
|
+
|
152
|
+
raise Error, "could not find Thor class or task '#{namespace}'" if raise_if_nil && klass.nil?
|
153
|
+
return klass, task
|
154
|
+
end
|
155
|
+
|
156
|
+
# Receives a path and load the thor file in the path. The file is evaluated
|
157
|
+
# inside the sandbox to avoid namespacing conflicts.
|
158
|
+
#
|
159
|
+
def self.load_thorfile(path, content=nil)
|
160
|
+
content ||= File.binread(path)
|
161
|
+
|
162
|
+
begin
|
163
|
+
Thor::Sandbox.class_eval(content, path)
|
164
|
+
rescue Exception => e
|
165
|
+
$stderr.puts "WARNING: unable to load thorfile #{path.inspect}: #{e.message}"
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def self.user_home
|
170
|
+
@@user_home ||= if ENV["HOME"]
|
171
|
+
ENV["HOME"]
|
172
|
+
elsif ENV["USERPROFILE"]
|
173
|
+
ENV["USERPROFILE"]
|
174
|
+
elsif ENV["HOMEDRIVE"] && ENV["HOMEPATH"]
|
175
|
+
File.join(ENV["HOMEDRIVE"], ENV["HOMEPATH"])
|
176
|
+
elsif ENV["APPDATA"]
|
177
|
+
ENV["APPDATA"]
|
178
|
+
else
|
179
|
+
begin
|
180
|
+
File.expand_path("~")
|
181
|
+
rescue
|
182
|
+
if File::ALT_SEPARATOR
|
183
|
+
"C:/"
|
184
|
+
else
|
185
|
+
"/"
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
# Returns the root where thor files are located, dependending on the OS.
|
192
|
+
#
|
193
|
+
def self.thor_root
|
194
|
+
File.join(user_home, ".thor").gsub(/\\/, '/')
|
195
|
+
end
|
196
|
+
|
197
|
+
# Returns the files in the thor root. On Windows thor_root will be something
|
198
|
+
# like this:
|
199
|
+
#
|
200
|
+
# C:\Documents and Settings\james\.thor
|
201
|
+
#
|
202
|
+
# If we don't #gsub the \ character, Dir.glob will fail.
|
203
|
+
#
|
204
|
+
def self.thor_root_glob
|
205
|
+
files = Dir["#{thor_root}/*"]
|
206
|
+
|
207
|
+
files.map! do |file|
|
208
|
+
File.directory?(file) ? File.join(file, "main.thor") : file
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
# Where to look for Thor files.
|
213
|
+
#
|
214
|
+
def self.globs_for(path)
|
215
|
+
["#{path}/Thorfile", "#{path}/*.thor", "#{path}/tasks/*.thor", "#{path}/lib/tasks/*.thor"]
|
216
|
+
end
|
217
|
+
|
218
|
+
# Return the path to the ruby interpreter taking into account multiple
|
219
|
+
# installations and windows extensions.
|
220
|
+
#
|
221
|
+
def self.ruby_command
|
222
|
+
@ruby_command ||= begin
|
223
|
+
ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
|
224
|
+
ruby << Config::CONFIG['EXEEXT']
|
225
|
+
|
226
|
+
# escape string in case path to ruby executable contain spaces.
|
227
|
+
ruby.sub!(/.*\s.*/m, '"\&"')
|
228
|
+
ruby
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
end
|
233
|
+
end
|
metadata
CHANGED
@@ -1,55 +1,77 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bundler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0.pre1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Yehuda Katz
|
8
7
|
- Carl Lerche
|
8
|
+
- Yehuda Katz
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2010-01-
|
13
|
+
date: 2010-01-30 00:00:00 -08:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|
17
|
-
description:
|
17
|
+
description:
|
18
18
|
email:
|
19
|
-
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
- carlhuda@engineyard.com
|
20
|
+
executables:
|
21
|
+
- bundle
|
23
22
|
extensions: []
|
24
23
|
|
25
|
-
extra_rdoc_files:
|
26
|
-
|
27
|
-
- LICENSE
|
24
|
+
extra_rdoc_files: []
|
25
|
+
|
28
26
|
files:
|
29
|
-
-
|
30
|
-
- README.markdown
|
31
|
-
- Rakefile
|
32
|
-
- lib/bundler/bundle.rb
|
27
|
+
- bin/bundle
|
33
28
|
- lib/bundler/cli.rb
|
34
|
-
- lib/bundler/
|
35
|
-
- lib/bundler/commands/exec_command.rb
|
29
|
+
- lib/bundler/definition.rb
|
36
30
|
- lib/bundler/dependency.rb
|
37
31
|
- lib/bundler/dsl.rb
|
38
32
|
- lib/bundler/environment.rb
|
39
|
-
- lib/bundler/
|
40
|
-
- lib/bundler/
|
41
|
-
- lib/bundler/gem_ext.rb
|
33
|
+
- lib/bundler/index.rb
|
34
|
+
- lib/bundler/installer.rb
|
42
35
|
- lib/bundler/remote_specification.rb
|
43
36
|
- lib/bundler/resolver.rb
|
44
|
-
- lib/bundler/
|
37
|
+
- lib/bundler/rubygems.rb
|
45
38
|
- lib/bundler/source.rb
|
46
|
-
- lib/bundler/
|
39
|
+
- lib/bundler/specification.rb
|
47
40
|
- lib/bundler/templates/environment.erb
|
48
|
-
- lib/bundler/templates/
|
41
|
+
- lib/bundler/templates/Gemfile
|
42
|
+
- lib/bundler/ui.rb
|
43
|
+
- lib/bundler/vendor/thor/actions/create_file.rb
|
44
|
+
- lib/bundler/vendor/thor/actions/directory.rb
|
45
|
+
- lib/bundler/vendor/thor/actions/empty_directory.rb
|
46
|
+
- lib/bundler/vendor/thor/actions/file_manipulation.rb
|
47
|
+
- lib/bundler/vendor/thor/actions/inject_into_file.rb
|
48
|
+
- lib/bundler/vendor/thor/actions.rb
|
49
|
+
- lib/bundler/vendor/thor/base.rb
|
50
|
+
- lib/bundler/vendor/thor/core_ext/file_binary_read.rb
|
51
|
+
- lib/bundler/vendor/thor/core_ext/hash_with_indifferent_access.rb
|
52
|
+
- lib/bundler/vendor/thor/core_ext/ordered_hash.rb
|
53
|
+
- lib/bundler/vendor/thor/error.rb
|
54
|
+
- lib/bundler/vendor/thor/group.rb
|
55
|
+
- lib/bundler/vendor/thor/invocation.rb
|
56
|
+
- lib/bundler/vendor/thor/parser/argument.rb
|
57
|
+
- lib/bundler/vendor/thor/parser/arguments.rb
|
58
|
+
- lib/bundler/vendor/thor/parser/option.rb
|
59
|
+
- lib/bundler/vendor/thor/parser/options.rb
|
60
|
+
- lib/bundler/vendor/thor/parser.rb
|
61
|
+
- lib/bundler/vendor/thor/rake_compat.rb
|
62
|
+
- lib/bundler/vendor/thor/runner.rb
|
63
|
+
- lib/bundler/vendor/thor/shell/basic.rb
|
64
|
+
- lib/bundler/vendor/thor/shell/color.rb
|
65
|
+
- lib/bundler/vendor/thor/shell.rb
|
66
|
+
- lib/bundler/vendor/thor/task.rb
|
67
|
+
- lib/bundler/vendor/thor/util.rb
|
68
|
+
- lib/bundler/vendor/thor/version.rb
|
69
|
+
- lib/bundler/vendor/thor.rb
|
49
70
|
- lib/bundler.rb
|
50
|
-
-
|
71
|
+
- LICENSE
|
72
|
+
- README
|
51
73
|
has_rdoc: true
|
52
|
-
homepage: http://github.com/
|
74
|
+
homepage: http://github.com/carlhuda/bundler
|
53
75
|
licenses: []
|
54
76
|
|
55
77
|
post_install_message:
|
@@ -75,6 +97,6 @@ rubyforge_project:
|
|
75
97
|
rubygems_version: 1.3.5
|
76
98
|
signing_key:
|
77
99
|
specification_version: 3
|
78
|
-
summary:
|
100
|
+
summary: Bundles are fun
|
79
101
|
test_files: []
|
80
102
|
|
data/README.markdown
DELETED
@@ -1,284 +0,0 @@
|
|
1
|
-
## Bundler : A gem to bundle gems
|
2
|
-
|
3
|
-
Github: http://github.com/wycats/bundler
|
4
|
-
Mailing list: http://groups.google.com/group/ruby-bundler
|
5
|
-
IRC: #carlhuda on freenode
|
6
|
-
|
7
|
-
## Intro
|
8
|
-
|
9
|
-
Bundler is a tool that manages gem dependencies for your ruby application. It
|
10
|
-
takes a gem manifest file and is able to fetch, download, and install the gems
|
11
|
-
and all child dependencies specified in this manifest. It can manage any update
|
12
|
-
to the gem manifest file and update the bundled gems accordingly. It also lets
|
13
|
-
you run any ruby code in context of the bundled gem environment.
|
14
|
-
|
15
|
-
## Installation
|
16
|
-
|
17
|
-
Bundler has no dependencies. Just clone the git repository and install the gem
|
18
|
-
with the following rake task:
|
19
|
-
|
20
|
-
rake install
|
21
|
-
|
22
|
-
You can also install the gem with
|
23
|
-
|
24
|
-
gem install bundler
|
25
|
-
|
26
|
-
## Usage
|
27
|
-
|
28
|
-
Bundler requires a gem manifest file to be created. This should be a file named
|
29
|
-
`Gemfile` located in the root directory of your application. After the manifest
|
30
|
-
has been created, in your shell, cd into your application's directory and run
|
31
|
-
`gem bundle`. This will start the bundling process.
|
32
|
-
|
33
|
-
### Manifest file
|
34
|
-
|
35
|
-
This is where you specify all of your application's dependencies. By default
|
36
|
-
this should be in a file named `Gemfile` located in your application's root
|
37
|
-
directory. The following is an example of a potential `Gemfile`. For more
|
38
|
-
information, please refer to Bundler::ManifestBuilder.
|
39
|
-
|
40
|
-
# Specify a dependency on rails. When the bundler downloads gems,
|
41
|
-
# it will download rails as well as all of rails' dependencies (such as
|
42
|
-
# activerecord, actionpack, etc...)
|
43
|
-
#
|
44
|
-
# At least one dependency must be specified
|
45
|
-
gem "rails"
|
46
|
-
|
47
|
-
# Specify a dependency on rack v.1.0.0. The version is optional. If present,
|
48
|
-
# it can be specified the same way as with rubygems' #gem method.
|
49
|
-
gem "rack", "1.0.0"
|
50
|
-
|
51
|
-
# Specify a dependency rspec, but only require that gem in the "testing"
|
52
|
-
# environment. :except is also a valid option to specify environment
|
53
|
-
# restrictions.
|
54
|
-
gem "rspec", :only => :testing
|
55
|
-
|
56
|
-
# Specify a dependency, but specify that it is already present and expanded
|
57
|
-
# at vendor/rspec. Bundler will treat rspec as though it was the rspec gem
|
58
|
-
# for the purpose of gem resolution: if another gem depends on a version
|
59
|
-
# of rspec satisfied by "1.1.6", it will be used.
|
60
|
-
#
|
61
|
-
# If a gemspec is found in the directory, it will be used to specify load
|
62
|
-
# paths and supply additional dependencies.
|
63
|
-
#
|
64
|
-
# Bundler will also recursively search for *.gemspec, and assume that
|
65
|
-
# gemspecs it finds represent gems that are rooted in the same directory
|
66
|
-
# the gemspec is found in.
|
67
|
-
gem "rspec", "1.1.6", :vendored_at => "vendor/rspec"
|
68
|
-
|
69
|
-
# You can also control what will happen when you run Bundler.require_env
|
70
|
-
# by using the :require_as option, as per the next two examples.
|
71
|
-
|
72
|
-
# Don't auto-require this gem.
|
73
|
-
gem "rspec-rails", "1.2.9", :require_as => nil
|
74
|
-
|
75
|
-
# Require something other than the default.
|
76
|
-
gem "yajl-ruby", "0.6.7", :require_as => "yajl/json_gem"
|
77
|
-
|
78
|
-
# Works exactly like :vendored_at, but first downloads the repo from
|
79
|
-
# git and handles stashing the files for you. As with :vendored_at,
|
80
|
-
# Bundler will automatically use *.gemspec files in the root or anywhere
|
81
|
-
# in the repository.
|
82
|
-
gem "rails", "3.0.pre", :git => "git://github.com/rails/rails.git"
|
83
|
-
|
84
|
-
# Add http://gems.github.com as a source that the bundler will use
|
85
|
-
# to find gems listed in the manifest. By default,
|
86
|
-
# http://gems.rubyforge.org is already added to the list.
|
87
|
-
#
|
88
|
-
# This is an optional setting.
|
89
|
-
source "http://gems.github.com"
|
90
|
-
|
91
|
-
# Specify where the bundled gems should be stashed. This directory will
|
92
|
-
# be a gem repository where all gems are downloaded to and installed to.
|
93
|
-
#
|
94
|
-
# This is an optional setting.
|
95
|
-
# The default is: vendor/gems
|
96
|
-
bundle_path "my/bundled/gems"
|
97
|
-
|
98
|
-
# Specify where gem executables should be copied to.
|
99
|
-
#
|
100
|
-
# This is an optional setting.
|
101
|
-
# The default is: bin
|
102
|
-
bin_path "my/executables"
|
103
|
-
|
104
|
-
# Specify that rubygems should be completely disabled. This means that it
|
105
|
-
# will be impossible to require it and that available gems will be
|
106
|
-
# limited exclusively to gems that have been bundled.
|
107
|
-
#
|
108
|
-
# The default is to automatically require rubygems. There is also a
|
109
|
-
# `disable_system_gems` option that will limit available rubygems to
|
110
|
-
# the ones that have been bundled.
|
111
|
-
disable_rubygems
|
112
|
-
|
113
|
-
### Gem Resolution
|
114
|
-
|
115
|
-
One of the most important things that the bundler does is do a
|
116
|
-
dependency resolution on the full list of gems that you specify, all
|
117
|
-
at once. This differs from the one-at-a-time dependency resolution that
|
118
|
-
Rubygems does, which can result in the following problem:
|
119
|
-
|
120
|
-
# On my system:
|
121
|
-
# activesupport 3.0.pre
|
122
|
-
# activesupport 2.3.4
|
123
|
-
# activemerchant 1.4.2
|
124
|
-
# rails 2.3.4
|
125
|
-
#
|
126
|
-
# activemerchant 1.4.2 depends on activesupport >= 2.3.2
|
127
|
-
|
128
|
-
gem "activemerchant", "1.4.2"
|
129
|
-
# results in activating activemerchant, as well as
|
130
|
-
# activesupport 3.0.pre, since it is >= 2.3.2
|
131
|
-
|
132
|
-
gem "rails", "2.3.4"
|
133
|
-
# results in:
|
134
|
-
# can't activate activesupport (= 2.3.4, runtime)
|
135
|
-
# for ["rails-2.3.4"], already activated
|
136
|
-
# activesupport-3.0.pre for ["activemerchant-1.4.2"]
|
137
|
-
|
138
|
-
This is because activemerchant has a broader dependency, which results
|
139
|
-
in the activation of a version of activesupport that does not satisfy
|
140
|
-
a more narrow dependency.
|
141
|
-
|
142
|
-
Bundler solves this problem by evaluating all dependencies at once,
|
143
|
-
so it can detect that all gems *together* require activesupport "2.3.4".
|
144
|
-
|
145
|
-
### Running Bundler
|
146
|
-
|
147
|
-
Once a manifest file has been created, the only thing that needs to be done
|
148
|
-
is to run the `gem bundle` command anywhere in your application. The script
|
149
|
-
will load the manifest file, resolve all the dependencies, download all
|
150
|
-
needed gems, and install them into the specified directory.
|
151
|
-
|
152
|
-
Every time an update is made to the manifest file, run `gem bundle` again to
|
153
|
-
get the changes installed. This will only check the remote sources if your
|
154
|
-
currently installed gems do not satisfy the `Gemfile`. If you want to force
|
155
|
-
checking for updates on the remote sources, use the `--update` option.
|
156
|
-
|
157
|
-
### Remote deploys
|
158
|
-
|
159
|
-
When you run `gem bundle`, the following steps occur:
|
160
|
-
|
161
|
-
1. Gemfile is read in
|
162
|
-
2. The gems specified in the Gemfile are resolved against the gems
|
163
|
-
already in your bundle. If the dependencies resolve, skip to step 5.
|
164
|
-
3. If the dependencies in your Gemfile cannot be fully resolved
|
165
|
-
against the gems already in the bundle, the metadata for each
|
166
|
-
source is fetched.
|
167
|
-
4. The gems in the Gemfile are resolved against the full list of
|
168
|
-
available gems in all sources, and the resulting gems are downloaded
|
169
|
-
5. Each gem that has been downloaded but not yet expanded is expanded
|
170
|
-
into the local directory. This expansion process also installs
|
171
|
-
native gems.
|
172
|
-
|
173
|
-
As you can see, if you run gem bundle twice in a row, it will do nothing the
|
174
|
-
second time, since the gems obviously resolve against the installed gems,
|
175
|
-
and they are all expanded.
|
176
|
-
|
177
|
-
This also means that if you run `gem bundle`, and .gitignore the expanded
|
178
|
-
copies, leaving only the cached `.gem` files, you can run `gem bundle` again
|
179
|
-
on the remote system, and it will only expand out the gems (but not
|
180
|
-
resolve or download `.gem` files). This also means that native gems
|
181
|
-
will be compiled for the target platform without requiring that the
|
182
|
-
`.gem` file itself be downloaded from a remote gem server.
|
183
|
-
|
184
|
-
Assuming a Rails app with Bundler's standard setup, add something like
|
185
|
-
this to your top-level `.gitignore` to only keep the cache:
|
186
|
-
|
187
|
-
bin/*
|
188
|
-
vendor/gems/*
|
189
|
-
!vendor/gems/cache/
|
190
|
-
|
191
|
-
Make sure that you explicitly `git add vendor/gems/cache` before you commit.
|
192
|
-
|
193
|
-
### Gems with compile-time options
|
194
|
-
|
195
|
-
Some gems require you to pass compile-time options to the gem install command.
|
196
|
-
For instance, to install mysql, you might do:
|
197
|
-
|
198
|
-
gem install mysql -- --with-mysql-config=/usr/local/lib/mysql
|
199
|
-
|
200
|
-
You can pass these options to the bundler by creating a YAML file containing
|
201
|
-
the options in question:
|
202
|
-
|
203
|
-
mysql:
|
204
|
-
mysql-config: /usr/local/lib/mysql
|
205
|
-
|
206
|
-
You can then point the bundler at the file:
|
207
|
-
|
208
|
-
gem bundle --build-options build_options.yml
|
209
|
-
|
210
|
-
In general, you will want to keep the build options YAML out of version control,
|
211
|
-
and provide the appropriate options for the system in question.
|
212
|
-
|
213
|
-
### Running your application
|
214
|
-
|
215
|
-
The easiest way to run your application is to start it with an executable
|
216
|
-
copied to the specified bin directory (by default, simply bin). For example,
|
217
|
-
if the application in question is a rack app, start it with `bin/rackup`.
|
218
|
-
This will automatically set the gem environment correctly.
|
219
|
-
|
220
|
-
Another way to run arbitrary ruby code in context of the bundled gems is to
|
221
|
-
run it with the `gem exec` command. For example:
|
222
|
-
|
223
|
-
gem exec ruby my_ruby_script.rb
|
224
|
-
|
225
|
-
You can use `gem exec bash` to enter a shell that will run all binaries in
|
226
|
-
the current context.
|
227
|
-
|
228
|
-
Yet another way is to manually require the environment file first. This is
|
229
|
-
located in `[bundle_path]/gems/environment.rb`. For example:
|
230
|
-
|
231
|
-
ruby -r vendor/gems/environment.rb my_ruby_script.rb
|
232
|
-
|
233
|
-
### Using Bundler with Rails today
|
234
|
-
|
235
|
-
It should be possible to use Bundler with Rails today. Here are the steps
|
236
|
-
to follow.
|
237
|
-
|
238
|
-
* In your rails app, create a Gemfile and specify the gems that your
|
239
|
-
application depends on. Make sure to specify rails as well:
|
240
|
-
|
241
|
-
gem "rails", "2.1.2"
|
242
|
-
gem "will_paginate"
|
243
|
-
|
244
|
-
# Optionally, you can disable system gems all together and only
|
245
|
-
# use bundled gems.
|
246
|
-
disable_system_gems
|
247
|
-
|
248
|
-
* Run `gem bundle`
|
249
|
-
|
250
|
-
* You can now use rails if you prepend `gem exec` to every call to `script/*`
|
251
|
-
but that isn't fun.
|
252
|
-
|
253
|
-
* At the top of `config/preinitializer.rb`, add the following line:
|
254
|
-
|
255
|
-
require "#{RAILS_ROOT}/vendor/gems/environment"
|
256
|
-
|
257
|
-
In theory, this should be enough to get going.
|
258
|
-
|
259
|
-
## To require rubygems or not
|
260
|
-
|
261
|
-
Ideally, no gem would assume the presence of rubygems at runtime. Rubygems provides
|
262
|
-
enough features so that this isn't necessary. However, there are a number of gems
|
263
|
-
that require specific rubygems features.
|
264
|
-
|
265
|
-
If the `disable_rubygems` option is used, Bundler will stub out the most common
|
266
|
-
of these features, but it is possible that things will not go as intended quite
|
267
|
-
yet. So, if you are brave, try your code without rubygems at runtime.
|
268
|
-
|
269
|
-
This is different from the `disable_system_gems` option, which uses the rubygems
|
270
|
-
library, but prevents system gems from being loaded; only gems that are bundled
|
271
|
-
will be available to your application. This option guarantees that dependencies
|
272
|
-
of your application will be available to a remote system.
|
273
|
-
|
274
|
-
## Known Issues
|
275
|
-
|
276
|
-
* When a gem points to a git repository, the git repository will be cloned
|
277
|
-
every time Bundler does a gem dependency resolve.
|
278
|
-
|
279
|
-
## Reporting bugs
|
280
|
-
|
281
|
-
Please report all bugs on the github issue tracker for the project located
|
282
|
-
at:
|
283
|
-
|
284
|
-
http://github.com/wycats/bundler/issues/
|