moneypools-bundler 0.7.1.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.markdown +275 -0
- data/Rakefile +60 -0
- data/lib/bundler.rb +35 -0
- data/lib/bundler/cli.rb +69 -0
- data/lib/bundler/commands/bundle_command.rb +72 -0
- data/lib/bundler/commands/exec_command.rb +36 -0
- data/lib/bundler/dependency.rb +64 -0
- data/lib/bundler/dsl.rb +173 -0
- data/lib/bundler/environment.rb +181 -0
- data/lib/bundler/finder.rb +51 -0
- data/lib/bundler/gem_bundle.rb +11 -0
- data/lib/bundler/gem_ext.rb +33 -0
- data/lib/bundler/remote_specification.rb +50 -0
- data/lib/bundler/repository.rb +256 -0
- data/lib/bundler/resolver.rb +234 -0
- data/lib/bundler/runtime.rb +2 -0
- data/lib/bundler/source.rb +326 -0
- data/lib/bundler/templates/app_script.erb +3 -0
- data/lib/bundler/templates/environment.erb +142 -0
- data/lib/rubygems_plugin.rb +6 -0
- metadata +79 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Engine Yard
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,275 @@
|
|
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
|
+
# Works exactly like :vendored_at, but first downloads the repo from
|
70
|
+
# git and handles stashing the files for you. As with :vendored_at,
|
71
|
+
# Bundler will automatically use *.gemspec files in the root or anywhere
|
72
|
+
# in the repository.
|
73
|
+
gem "rails", "3.0.pre", :git => "git://github.com/rails/rails.git"
|
74
|
+
|
75
|
+
# Add http://gems.github.com as a source that the bundler will use
|
76
|
+
# to find gems listed in the manifest. By default,
|
77
|
+
# http://gems.rubyforge.org is already added to the list.
|
78
|
+
#
|
79
|
+
# This is an optional setting.
|
80
|
+
source "http://gems.github.com"
|
81
|
+
|
82
|
+
# Specify where the bundled gems should be stashed. This directory will
|
83
|
+
# be a gem repository where all gems are downloaded to and installed to.
|
84
|
+
#
|
85
|
+
# This is an optional setting.
|
86
|
+
# The default is: vendor/gems
|
87
|
+
bundle_path "my/bundled/gems"
|
88
|
+
|
89
|
+
# Specify where gem executables should be copied to.
|
90
|
+
#
|
91
|
+
# This is an optional setting.
|
92
|
+
# The default is: bin
|
93
|
+
bin_path "my/executables"
|
94
|
+
|
95
|
+
# Specify that rubygems should be completely disabled. This means that it
|
96
|
+
# will be impossible to require it and that available gems will be
|
97
|
+
# limited exclusively to gems that have been bundled.
|
98
|
+
#
|
99
|
+
# The default is to automatically require rubygems. There is also a
|
100
|
+
# `disable_system_gems` option that will limit available rubygems to
|
101
|
+
# the ones that have been bundled.
|
102
|
+
disable_rubygems
|
103
|
+
|
104
|
+
### Gem Resolution
|
105
|
+
|
106
|
+
One of the most important things that the bundler does is do a
|
107
|
+
dependency resolution on the full list of gems that you specify, all
|
108
|
+
at once. This differs from the one-at-a-time dependency resolution that
|
109
|
+
Rubygems does, which can result in the following problem:
|
110
|
+
|
111
|
+
# On my system:
|
112
|
+
# activesupport 3.0.pre
|
113
|
+
# activesupport 2.3.4
|
114
|
+
# activemerchant 1.4.2
|
115
|
+
# rails 2.3.4
|
116
|
+
#
|
117
|
+
# activemerchant 1.4.2 depends on activesupport >= 2.3.2
|
118
|
+
|
119
|
+
gem "activemerchant", "1.4.2"
|
120
|
+
# results in activating activemerchant, as well as
|
121
|
+
# activesupport 3.0.pre, since it is >= 2.3.2
|
122
|
+
|
123
|
+
gem "rails", "2.3.4"
|
124
|
+
# results in:
|
125
|
+
# can't activate activesupport (= 2.3.4, runtime)
|
126
|
+
# for ["rails-2.3.4"], already activated
|
127
|
+
# activesupport-3.0.pre for ["activemerchant-1.4.2"]
|
128
|
+
|
129
|
+
This is because activemerchant has a broader dependency, which results
|
130
|
+
in the activation of a version of activesupport that does not satisfy
|
131
|
+
a more narrow dependency.
|
132
|
+
|
133
|
+
Bundler solves this problem by evaluating all dependencies at once,
|
134
|
+
so it can detect that all gems *together* require activesupport "2.3.4".
|
135
|
+
|
136
|
+
### Running Bundler
|
137
|
+
|
138
|
+
Once a manifest file has been created, the only thing that needs to be done
|
139
|
+
is to run the `gem bundle` command anywhere in your application. The script
|
140
|
+
will load the manifest file, resolve all the dependencies, download all
|
141
|
+
needed gems, and install them into the specified directory.
|
142
|
+
|
143
|
+
Every time an update is made to the manifest file, run `gem bundle` again to
|
144
|
+
get the changes installed. This will only check the remote sources if your
|
145
|
+
currently installed gems do not satisfy the `Gemfile`. If you want to force
|
146
|
+
checking for updates on the remote sources, use the `--update` option.
|
147
|
+
|
148
|
+
### Remote deploys
|
149
|
+
|
150
|
+
When you run `gem bundle`, the following steps occur:
|
151
|
+
|
152
|
+
1. Gemfile is read in
|
153
|
+
2. The gems specified in the Gemfile are resolved against the gems
|
154
|
+
already in your bundle. If the dependencies resolve, skip to step 5.
|
155
|
+
3. If the dependencies in your Gemfile cannot be fully resolved
|
156
|
+
against the gems already in the bundle, the metadata for each
|
157
|
+
source is fetched.
|
158
|
+
4. The gems in the Gemfile are resolved against the full list of
|
159
|
+
available gems in all sources, and the resulting gems are downloaded
|
160
|
+
5. Each gem that has been downloaded but not yet expanded is expanded
|
161
|
+
into the local directory. This expansion process also installs
|
162
|
+
native gems.
|
163
|
+
|
164
|
+
As you can see, if you run gem bundle twice in a row, it will do nothing the
|
165
|
+
second time, since the gems obviously resolve against the installed gems,
|
166
|
+
and they are all expanded.
|
167
|
+
|
168
|
+
This also means that if you run `gem bundle`, and .gitignore the expanded
|
169
|
+
copies, leaving only the cached `.gem` files, you can run `gem bundle` again
|
170
|
+
on the remote system, and it will only expand out the gems (but not
|
171
|
+
resolve or download `.gem` files). This also means that native gems
|
172
|
+
will be compiled for the target platform without requiring that the
|
173
|
+
`.gem` file itself be downloaded from a remote gem server.
|
174
|
+
|
175
|
+
Assuming a Rails app with Bundler's standard setup, add something like
|
176
|
+
this to your top-level `.gitignore` to only keep the cache:
|
177
|
+
|
178
|
+
bin/*
|
179
|
+
vendor/gems/*
|
180
|
+
!vendor/gems/cache/
|
181
|
+
|
182
|
+
Make sure that you explicitly `git add vendor/gems/cache` before you commit.
|
183
|
+
|
184
|
+
### Gems with compile-time options
|
185
|
+
|
186
|
+
Some gems require you to pass compile-time options to the gem install command.
|
187
|
+
For instance, to install mysql, you might do:
|
188
|
+
|
189
|
+
gem install mysql -- --with-mysql-config=/usr/local/lib/mysql
|
190
|
+
|
191
|
+
You can pass these options to the bundler by creating a YAML file containing
|
192
|
+
the options in question:
|
193
|
+
|
194
|
+
mysql:
|
195
|
+
mysql-config: /usr/local/lib/mysql
|
196
|
+
|
197
|
+
You can then point the bundler at the file:
|
198
|
+
|
199
|
+
gem bundle --build-options build_options.yml
|
200
|
+
|
201
|
+
In general, you will want to keep the build options YAML out of version control,
|
202
|
+
and provide the appropriate options for the system in question.
|
203
|
+
|
204
|
+
### Running your application
|
205
|
+
|
206
|
+
The easiest way to run your application is to start it with an executable
|
207
|
+
copied to the specified bin directory (by default, simply bin). For example,
|
208
|
+
if the application in question is a rack app, start it with `bin/rackup`.
|
209
|
+
This will automatically set the gem environment correctly.
|
210
|
+
|
211
|
+
Another way to run arbitrary ruby code in context of the bundled gems is to
|
212
|
+
run it with the `gem exec` command. For example:
|
213
|
+
|
214
|
+
gem exec ruby my_ruby_script.rb
|
215
|
+
|
216
|
+
You can use `gem exec bash` to enter a shell that will run all binaries in
|
217
|
+
the current context.
|
218
|
+
|
219
|
+
Yet another way is to manually require the environment file first. This is
|
220
|
+
located in `[bundle_path]/gems/environment.rb`. For example:
|
221
|
+
|
222
|
+
ruby -r vendor/gems/environment.rb my_ruby_script.rb
|
223
|
+
|
224
|
+
### Using Bundler with Rails today
|
225
|
+
|
226
|
+
It should be possible to use Bundler with Rails today. Here are the steps
|
227
|
+
to follow.
|
228
|
+
|
229
|
+
* In your rails app, create a Gemfile and specify the gems that your
|
230
|
+
application depends on. Make sure to specify rails as well:
|
231
|
+
|
232
|
+
gem "rails", "2.1.2"
|
233
|
+
gem "will_paginate"
|
234
|
+
|
235
|
+
# Optionally, you can disable system gems all together and only
|
236
|
+
# use bundled gems.
|
237
|
+
disable_system_gems
|
238
|
+
|
239
|
+
* Run `gem bundle`
|
240
|
+
|
241
|
+
* You can now use rails if you prepend `gem exec` to every call to `script/*`
|
242
|
+
but that isn't fun.
|
243
|
+
|
244
|
+
* At the top of `config/preinitializer.rb`, add the following line:
|
245
|
+
|
246
|
+
require "#{RAILS_ROOT}/vendor/gems/environment"
|
247
|
+
|
248
|
+
In theory, this should be enough to get going.
|
249
|
+
|
250
|
+
## To require rubygems or not
|
251
|
+
|
252
|
+
Ideally, no gem would assume the presence of rubygems at runtime. Rubygems provides
|
253
|
+
enough features so that this isn't necessary. However, there are a number of gems
|
254
|
+
that require specific rubygems features.
|
255
|
+
|
256
|
+
If the `disable_rubygems` option is used, Bundler will stub out the most common
|
257
|
+
of these features, but it is possible that things will not go as intended quite
|
258
|
+
yet. So, if you are brave, try your code without rubygems at runtime.
|
259
|
+
|
260
|
+
This is different from the `disable_system_gems` option, which uses the rubygems
|
261
|
+
library, but prevents system gems from being loaded; only gems that are bundled
|
262
|
+
will be available to your application. This option guarantees that dependencies
|
263
|
+
of your application will be available to a remote system.
|
264
|
+
|
265
|
+
## Known Issues
|
266
|
+
|
267
|
+
* When a gem points to a git repository, the git repository will be cloned
|
268
|
+
every time Bundler does a gem dependency resolve.
|
269
|
+
|
270
|
+
## Reporting bugs
|
271
|
+
|
272
|
+
Please report all bugs on the github issue tracker for the project located
|
273
|
+
at:
|
274
|
+
|
275
|
+
http://github.com/wycats/bundler/issues/
|
data/Rakefile
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), 'lib')
|
2
|
+
require 'rubygems' unless ENV['NO_RUBYGEMS']
|
3
|
+
require 'rubygems/specification'
|
4
|
+
require 'bundler'
|
5
|
+
require 'date'
|
6
|
+
|
7
|
+
spec = Gem::Specification.new do |s|
|
8
|
+
s.name = "moneypools-bundler"
|
9
|
+
s.version = Bundler::VERSION
|
10
|
+
s.authors = ["Yehuda Katz", "Carl Lerche"]
|
11
|
+
s.email = ["wycats@gmail.com", "clerche@engineyard.com"]
|
12
|
+
s.homepage = "http://github.com/wycats/bundler"
|
13
|
+
s.description = s.summary = "An easy way to vendor gem dependencies"
|
14
|
+
|
15
|
+
s.platform = Gem::Platform::RUBY
|
16
|
+
s.has_rdoc = true
|
17
|
+
s.extra_rdoc_files = ["README.markdown", "LICENSE"]
|
18
|
+
|
19
|
+
s.required_rubygems_version = ">= 1.3.5"
|
20
|
+
|
21
|
+
s.require_path = 'lib'
|
22
|
+
s.files = %w(LICENSE README.markdown Rakefile) + Dir.glob("lib/**/*")
|
23
|
+
end
|
24
|
+
|
25
|
+
task :default => :spec
|
26
|
+
|
27
|
+
begin
|
28
|
+
require 'spec/rake/spectask'
|
29
|
+
rescue LoadError
|
30
|
+
task(:spec) { $stderr.puts '`gem install rspec` to run specs' }
|
31
|
+
else
|
32
|
+
desc "Run specs"
|
33
|
+
Spec::Rake::SpecTask.new do |t|
|
34
|
+
t.spec_files = FileList['spec/**/*_spec.rb'] - FileList['spec/fixtures/**/*_spec.rb']
|
35
|
+
t.spec_opts = %w(-fs --color)
|
36
|
+
t.warning = true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
begin
|
41
|
+
require 'rake/gempackagetask'
|
42
|
+
rescue LoadError
|
43
|
+
task(:gem) { $stderr.puts '`gem install rake` to package gems' }
|
44
|
+
else
|
45
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
46
|
+
pkg.gem_spec = spec
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
desc "install the gem locally"
|
51
|
+
task :install => [:package] do
|
52
|
+
sh %{gem install pkg/#{spec.name}-#{spec.version}}
|
53
|
+
end
|
54
|
+
|
55
|
+
desc "create a gemspec file"
|
56
|
+
task :make_spec do
|
57
|
+
File.open("#{spec.name}.gemspec", "w") do |file|
|
58
|
+
file.puts spec.to_ruby
|
59
|
+
end
|
60
|
+
end
|
data/lib/bundler.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'logger'
|
3
|
+
require 'set'
|
4
|
+
require 'erb'
|
5
|
+
# Required elements of rubygems
|
6
|
+
require "rubygems/remote_fetcher"
|
7
|
+
require "rubygems/installer"
|
8
|
+
|
9
|
+
require "bundler/gem_bundle"
|
10
|
+
require "bundler/source"
|
11
|
+
require "bundler/finder"
|
12
|
+
require "bundler/gem_ext"
|
13
|
+
require "bundler/resolver"
|
14
|
+
require "bundler/environment"
|
15
|
+
require "bundler/dsl"
|
16
|
+
require "bundler/cli"
|
17
|
+
require "bundler/repository"
|
18
|
+
require "bundler/dependency"
|
19
|
+
require "bundler/remote_specification"
|
20
|
+
|
21
|
+
module Bundler
|
22
|
+
VERSION = "0.7.1.pre"
|
23
|
+
|
24
|
+
class << self
|
25
|
+
attr_writer :logger
|
26
|
+
|
27
|
+
def logger
|
28
|
+
@logger ||= begin
|
29
|
+
logger = Logger.new(STDOUT, Logger::INFO)
|
30
|
+
logger.formatter = proc {|_,_,_,msg| "#{msg}\n" }
|
31
|
+
logger
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/bundler/cli.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
require "optparse"
|
2
|
+
|
3
|
+
module Bundler
|
4
|
+
class CLI
|
5
|
+
def self.run(command, options = {})
|
6
|
+
new(options).run(command)
|
7
|
+
rescue DefaultManifestNotFound => e
|
8
|
+
Bundler.logger.error "Could not find a Gemfile to use"
|
9
|
+
exit 3
|
10
|
+
rescue InvalidEnvironmentName => e
|
11
|
+
Bundler.logger.error "Gemfile error: #{e.message}"
|
12
|
+
exit 4
|
13
|
+
rescue InvalidRepository => e
|
14
|
+
Bundler.logger.error e.message
|
15
|
+
exit 5
|
16
|
+
rescue VersionConflict => e
|
17
|
+
Bundler.logger.error e.message
|
18
|
+
exit 6
|
19
|
+
rescue GemNotFound => e
|
20
|
+
Bundler.logger.error e.message
|
21
|
+
exit 7
|
22
|
+
rescue InvalidCacheArgument => e
|
23
|
+
Bundler.logger.error e.message
|
24
|
+
exit 8
|
25
|
+
rescue SourceNotCached => e
|
26
|
+
Bundler.logger.error e.message
|
27
|
+
exit 9
|
28
|
+
rescue ManifestFileNotFound => e
|
29
|
+
Bundler.logger.error e.message
|
30
|
+
exit 10
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(options)
|
34
|
+
@options = options
|
35
|
+
@environment = Bundler::Environment.load(@options[:manifest])
|
36
|
+
end
|
37
|
+
|
38
|
+
def bundle
|
39
|
+
@environment.install(@options)
|
40
|
+
end
|
41
|
+
|
42
|
+
def cache
|
43
|
+
@environment.cache(@options)
|
44
|
+
end
|
45
|
+
|
46
|
+
def prune
|
47
|
+
@environment.prune(@options)
|
48
|
+
end
|
49
|
+
|
50
|
+
def list
|
51
|
+
@environment.list(@options)
|
52
|
+
end
|
53
|
+
|
54
|
+
def list_outdated
|
55
|
+
@environment.list_outdated(@options)
|
56
|
+
end
|
57
|
+
|
58
|
+
def exec
|
59
|
+
@environment.setup_environment
|
60
|
+
# w0t?
|
61
|
+
super(*$command)
|
62
|
+
end
|
63
|
+
|
64
|
+
def run(command)
|
65
|
+
send(command)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|