bowline-bundler 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/LICENSE +20 -0
  2. data/README.markdown +291 -0
  3. data/Rakefile +45 -0
  4. data/VERSION +1 -0
  5. data/bin/bowline-bundle +59 -0
  6. data/lib/bowline/bundler/bundle.rb +323 -0
  7. data/lib/bowline/bundler/cli.rb +87 -0
  8. data/lib/bowline/bundler/dependency.rb +62 -0
  9. data/lib/bowline/bundler/dsl.rb +182 -0
  10. data/lib/bowline/bundler/environment.rb +87 -0
  11. data/lib/bowline/bundler/finder.rb +51 -0
  12. data/lib/bowline/bundler/gem_bundle.rb +11 -0
  13. data/lib/bowline/bundler/gem_ext.rb +34 -0
  14. data/lib/bowline/bundler/remote_specification.rb +53 -0
  15. data/lib/bowline/bundler/resolver.rb +250 -0
  16. data/lib/bowline/bundler/runtime.rb +2 -0
  17. data/lib/bowline/bundler/source.rb +361 -0
  18. data/lib/bowline/bundler/templates/app_script.erb +3 -0
  19. data/lib/bowline/bundler/templates/environment.erb +156 -0
  20. data/lib/bowline/bundler/templates/environment_picker.erb +4 -0
  21. data/lib/bowline/bundler.rb +35 -0
  22. data/spec/bundler/cli_spec.rb +558 -0
  23. data/spec/bundler/directory_spec.rb +255 -0
  24. data/spec/bundler/dsl_spec.rb +126 -0
  25. data/spec/bundler/fetcher_spec.rb +138 -0
  26. data/spec/bundler/git_spec.rb +266 -0
  27. data/spec/bundler/installer_spec.rb +155 -0
  28. data/spec/bundler/manifest_file_spec.rb +105 -0
  29. data/spec/bundler/manifest_spec.rb +257 -0
  30. data/spec/bundler/runtime_spec.rb +141 -0
  31. data/spec/bundler/system_gems_spec.rb +42 -0
  32. data/spec/quality_spec.rb +57 -0
  33. data/spec/resolver/engine_spec.rb +112 -0
  34. data/spec/resolver/error_spec.rb +50 -0
  35. data/spec/resolver/fake_source_index_spec.rb +43 -0
  36. data/spec/resolver/prerelease_spec.rb +113 -0
  37. data/spec/spec_helper.rb +46 -0
  38. data/spec/support/builders.rb +257 -0
  39. data/spec/support/core_ext.rb +18 -0
  40. data/spec/support/helpers.rb +126 -0
  41. data/spec/support/matchers.rb +201 -0
  42. data/spec/support/path_utils.rb +63 -0
  43. metadata +126 -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,291 @@
1
+ ## bowline-bundler
2
+
3
+ This is a version of Bundler for Bowline apps.
4
+
5
+ Below is the original Bundler README.
6
+
7
+
8
+ ## Bundler : A gem to bundle gems
9
+
10
+ Github: http://github.com/wycats/bundler
11
+ Mailing list: http://groups.google.com/group/ruby-bundler
12
+ IRC: #carlhuda on freenode
13
+
14
+ ## Intro
15
+
16
+ Bundler is a tool that manages gem dependencies for your ruby application. It
17
+ takes a gem manifest file and is able to fetch, download, and install the gems
18
+ and all child dependencies specified in this manifest. It can manage any update
19
+ to the gem manifest file and update the bundled gems accordingly. It also lets
20
+ you run any ruby code in context of the bundled gem environment.
21
+
22
+ ## Installation
23
+
24
+ Bundler has no dependencies. Just clone the git repository and install the gem
25
+ with the following rake task:
26
+
27
+ rake install
28
+
29
+ You can also install the gem with
30
+
31
+ gem install bundler
32
+
33
+ ## Usage
34
+
35
+ Bundler requires a gem manifest file to be created. This should be a file named
36
+ `Gemfile` located in the root directory of your application. After the manifest
37
+ has been created, in your shell, cd into your application's directory and run
38
+ `gem bundle`. This will start the bundling process.
39
+
40
+ ### Manifest file
41
+
42
+ This is where you specify all of your application's dependencies. By default
43
+ this should be in a file named `Gemfile` located in your application's root
44
+ directory. The following is an example of a potential `Gemfile`. For more
45
+ information, please refer to Bundler::ManifestBuilder.
46
+
47
+ # Specify a dependency on rails. When the bundler downloads gems,
48
+ # it will download rails as well as all of rails' dependencies (such as
49
+ # activerecord, actionpack, etc...)
50
+ #
51
+ # At least one dependency must be specified
52
+ gem "rails"
53
+
54
+ # Specify a dependency on rack v.1.0.0. The version is optional. If present,
55
+ # it can be specified the same way as with rubygems' #gem method.
56
+ gem "rack", "1.0.0"
57
+
58
+ # Specify a dependency rspec, but only require that gem in the "testing"
59
+ # environment. :except is also a valid option to specify environment
60
+ # restrictions.
61
+ gem "rspec", :only => :testing
62
+
63
+ # Specify a dependency, but specify that it is already present and expanded
64
+ # at vendor/rspec. Bundler will treat rspec as though it was the rspec gem
65
+ # for the purpose of gem resolution: if another gem depends on a version
66
+ # of rspec satisfied by "1.1.6", it will be used.
67
+ #
68
+ # If a gemspec is found in the directory, it will be used to specify load
69
+ # paths and supply additional dependencies.
70
+ #
71
+ # Bundler will also recursively search for *.gemspec, and assume that
72
+ # gemspecs it finds represent gems that are rooted in the same directory
73
+ # the gemspec is found in.
74
+ gem "rspec", "1.1.6", :vendored_at => "vendor/rspec"
75
+
76
+ # You can also control what will happen when you run Bundler.require_env
77
+ # by using the :require_as option, as per the next two examples.
78
+
79
+ # Don't auto-require this gem.
80
+ gem "rspec-rails", "1.2.9", :require_as => nil
81
+
82
+ # Require something other than the default.
83
+ gem "yajl-ruby", "0.6.7", :require_as => "yajl/json_gem"
84
+
85
+ # Works exactly like :vendored_at, but first downloads the repo from
86
+ # git and handles stashing the files for you. As with :vendored_at,
87
+ # Bundler will automatically use *.gemspec files in the root or anywhere
88
+ # in the repository.
89
+ gem "rails", "3.0.pre", :git => "git://github.com/rails/rails.git"
90
+
91
+ # Add http://gems.github.com as a source that the bundler will use
92
+ # to find gems listed in the manifest. By default,
93
+ # http://gems.rubyforge.org is already added to the list.
94
+ #
95
+ # This is an optional setting.
96
+ source "http://gems.github.com"
97
+
98
+ # Specify where the bundled gems should be stashed. This directory will
99
+ # be a gem repository where all gems are downloaded to and installed to.
100
+ #
101
+ # This is an optional setting.
102
+ # The default is: vendor/gems
103
+ bundle_path "my/bundled/gems"
104
+
105
+ # Specify where gem executables should be copied to.
106
+ #
107
+ # This is an optional setting.
108
+ # The default is: bin
109
+ bin_path "my/executables"
110
+
111
+ # Specify that rubygems should be completely disabled. This means that it
112
+ # will be impossible to require it and that available gems will be
113
+ # limited exclusively to gems that have been bundled.
114
+ #
115
+ # The default is to automatically require rubygems. There is also a
116
+ # `disable_system_gems` option that will limit available rubygems to
117
+ # the ones that have been bundled.
118
+ disable_rubygems
119
+
120
+ ### Gem Resolution
121
+
122
+ One of the most important things that the bundler does is do a
123
+ dependency resolution on the full list of gems that you specify, all
124
+ at once. This differs from the one-at-a-time dependency resolution that
125
+ Rubygems does, which can result in the following problem:
126
+
127
+ # On my system:
128
+ # activesupport 3.0.pre
129
+ # activesupport 2.3.4
130
+ # activemerchant 1.4.2
131
+ # rails 2.3.4
132
+ #
133
+ # activemerchant 1.4.2 depends on activesupport >= 2.3.2
134
+
135
+ gem "activemerchant", "1.4.2"
136
+ # results in activating activemerchant, as well as
137
+ # activesupport 3.0.pre, since it is >= 2.3.2
138
+
139
+ gem "rails", "2.3.4"
140
+ # results in:
141
+ # can't activate activesupport (= 2.3.4, runtime)
142
+ # for ["rails-2.3.4"], already activated
143
+ # activesupport-3.0.pre for ["activemerchant-1.4.2"]
144
+
145
+ This is because activemerchant has a broader dependency, which results
146
+ in the activation of a version of activesupport that does not satisfy
147
+ a more narrow dependency.
148
+
149
+ Bundler solves this problem by evaluating all dependencies at once,
150
+ so it can detect that all gems *together* require activesupport "2.3.4".
151
+
152
+ ### Running Bundler
153
+
154
+ Once a manifest file has been created, the only thing that needs to be done
155
+ is to run the `gem bundle` command anywhere in your application. The script
156
+ will load the manifest file, resolve all the dependencies, download all
157
+ needed gems, and install them into the specified directory.
158
+
159
+ Every time an update is made to the manifest file, run `gem bundle` again to
160
+ get the changes installed. This will only check the remote sources if your
161
+ currently installed gems do not satisfy the `Gemfile`. If you want to force
162
+ checking for updates on the remote sources, use the `--update` option.
163
+
164
+ ### Remote deploys
165
+
166
+ When you run `gem bundle`, the following steps occur:
167
+
168
+ 1. Gemfile is read in
169
+ 2. The gems specified in the Gemfile are resolved against the gems
170
+ already in your bundle. If the dependencies resolve, skip to step 5.
171
+ 3. If the dependencies in your Gemfile cannot be fully resolved
172
+ against the gems already in the bundle, the metadata for each
173
+ source is fetched.
174
+ 4. The gems in the Gemfile are resolved against the full list of
175
+ available gems in all sources, and the resulting gems are downloaded
176
+ 5. Each gem that has been downloaded but not yet expanded is expanded
177
+ into the local directory. This expansion process also installs
178
+ native gems.
179
+
180
+ As you can see, if you run gem bundle twice in a row, it will do nothing the
181
+ second time, since the gems obviously resolve against the installed gems,
182
+ and they are all expanded.
183
+
184
+ This also means that if you run `gem bundle`, and .gitignore the expanded
185
+ copies, leaving only the cached `.gem` files, you can run `gem bundle` again
186
+ on the remote system, and it will only expand out the gems (but not
187
+ resolve or download `.gem` files). This also means that native gems
188
+ will be compiled for the target platform without requiring that the
189
+ `.gem` file itself be downloaded from a remote gem server.
190
+
191
+ Assuming a Rails app with Bundler's standard setup, add something like
192
+ this to your top-level `.gitignore` to only keep the cache:
193
+
194
+ bin/*
195
+ vendor/gems/*
196
+ !vendor/gems/cache/
197
+
198
+ Make sure that you explicitly `git add vendor/gems/cache` before you commit.
199
+
200
+ ### Gems with compile-time options
201
+
202
+ Some gems require you to pass compile-time options to the gem install command.
203
+ For instance, to install mysql, you might do:
204
+
205
+ gem install mysql -- --with-mysql-config=/usr/local/lib/mysql
206
+
207
+ You can pass these options to the bundler by creating a YAML file containing
208
+ the options in question:
209
+
210
+ mysql:
211
+ mysql-config: /usr/local/lib/mysql
212
+
213
+ You can then point the bundler at the file:
214
+
215
+ gem bundle --build-options build_options.yml
216
+
217
+ In general, you will want to keep the build options YAML out of version control,
218
+ and provide the appropriate options for the system in question.
219
+
220
+ ### Running your application
221
+
222
+ The easiest way to run your application is to start it with an executable
223
+ copied to the specified bin directory (by default, simply bin). For example,
224
+ if the application in question is a rack app, start it with `bin/rackup`.
225
+ This will automatically set the gem environment correctly.
226
+
227
+ Another way to run arbitrary ruby code in context of the bundled gems is to
228
+ run it with the `gem exec` command. For example:
229
+
230
+ gem exec ruby my_ruby_script.rb
231
+
232
+ You can use `gem exec bash` to enter a shell that will run all binaries in
233
+ the current context.
234
+
235
+ Yet another way is to manually require the environment file first. This is
236
+ located in `[bundle_path]/gems/environment.rb`. For example:
237
+
238
+ ruby -r vendor/gems/environment.rb my_ruby_script.rb
239
+
240
+ ### Using Bundler with Rails today
241
+
242
+ It should be possible to use Bundler with Rails today. Here are the steps
243
+ to follow.
244
+
245
+ * In your rails app, create a Gemfile and specify the gems that your
246
+ application depends on. Make sure to specify rails as well:
247
+
248
+ gem "rails", "2.1.2"
249
+ gem "will_paginate"
250
+
251
+ # Optionally, you can disable system gems all together and only
252
+ # use bundled gems.
253
+ disable_system_gems
254
+
255
+ * Run `gem bundle`
256
+
257
+ * You can now use rails if you prepend `gem exec` to every call to `script/*`
258
+ but that isn't fun.
259
+
260
+ * At the top of `config/preinitializer.rb`, add the following line:
261
+
262
+ require "#{RAILS_ROOT}/vendor/gems/environment"
263
+
264
+ In theory, this should be enough to get going.
265
+
266
+ ## To require rubygems or not
267
+
268
+ Ideally, no gem would assume the presence of rubygems at runtime. Rubygems provides
269
+ enough features so that this isn't necessary. However, there are a number of gems
270
+ that require specific rubygems features.
271
+
272
+ If the `disable_rubygems` option is used, Bundler will stub out the most common
273
+ of these features, but it is possible that things will not go as intended quite
274
+ yet. So, if you are brave, try your code without rubygems at runtime.
275
+
276
+ This is different from the `disable_system_gems` option, which uses the rubygems
277
+ library, but prevents system gems from being loaded; only gems that are bundled
278
+ will be available to your application. This option guarantees that dependencies
279
+ of your application will be available to a remote system.
280
+
281
+ ## Known Issues
282
+
283
+ * When a gem points to a git repository, the git repository will be cloned
284
+ every time Bundler does a gem dependency resolve.
285
+
286
+ ## Reporting bugs
287
+
288
+ Please report all bugs on the github issue tracker for the project located
289
+ at:
290
+
291
+ http://github.com/wycats/bundler/issues/
data/Rakefile ADDED
@@ -0,0 +1,45 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), 'lib')
2
+ require 'bowline/bundler'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gemspec|
7
+ gemspec.name = "bowline-bundler"
8
+ gemspec.summary = "An easy way to vendor gem dependencies for Bowline apps"
9
+ gemspec.email = "alex@leadthinking.com"
10
+ gemspec.homepage = "http://github.com/maccman/bowline-bundler"
11
+ gemspec.authors = ["Alex MacCaw"]
12
+ gemspec.required_rubygems_version = ">= 1.3.5"
13
+ gemspec.files = FileList["[A-Z]*", "{bin,generators,lib,spec}/**/*"]
14
+ end
15
+ rescue LoadError
16
+ puts "Jeweler not available. Install it with: sudo gem install jeweler"
17
+ end
18
+
19
+ task :default => :spec
20
+
21
+ begin
22
+ require 'spec/rake/spectask'
23
+ rescue LoadError
24
+ task(:spec) { $stderr.puts '`gem install rspec` to run specs' }
25
+ else
26
+ desc "Run specs"
27
+ Spec::Rake::SpecTask.new do |t|
28
+ t.spec_files = FileList['spec/**/*_spec.rb'] - FileList['spec/fixtures/**/*_spec.rb']
29
+ t.spec_opts = %w(-fs --color)
30
+ t.warning = true
31
+ end
32
+ end
33
+
34
+ namespace :spec do
35
+ file "tmp/rg_deps" do
36
+ repo = File.dirname(__FILE__) + '/tmp/rg_deps'
37
+ FileUtils.mkdir_p(repo)
38
+ p repo
39
+ ENV['GEM_HOME'], ENV['GEM_PATH'] = repo, repo
40
+ system "gem install builder --no-rdoc --no-ri"
41
+ end
42
+
43
+ desc "Do all setup needed to run the specs"
44
+ task :setup => "tmp/rg_deps"
45
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require File.join(File.dirname(__FILE__), *%w[.. lib bowline bundler])
5
+
6
+ options = {}
7
+
8
+ OptionParser.new do |opts|
9
+ opts.on('-m', '--manifest MANIFEST', "Specify the path to the manifest file") do |manifest, options|
10
+ options[:manifest] = manifest
11
+ end
12
+
13
+ opts.on('-u', '--update', "Force a remote check for newer gems") do
14
+ options[:update] = true
15
+ end
16
+
17
+ opts.on('--cached', "Only use cached gems when expanding the bundle") do
18
+ options[:cached] = true
19
+ end
20
+
21
+ opts.on('--cache GEM', "Specify a path to a .gem file to add to the bundled gem cache") do |gem, options|
22
+ options[:cache] = gem
23
+ end
24
+
25
+ opts.on('--prune-cache', "Removes all .gem files that are not a part of the bundle from the cache") do
26
+ options[:prune] = true
27
+ end
28
+
29
+ opts.on('--list', "List all gems that are part of the active bundle") do
30
+ options[:list] = true
31
+ end
32
+
33
+ opts.on('--list-outdated', "List all outdated gems that are part of the active bundle") do
34
+ options[:list_outdated] = true
35
+ end
36
+
37
+ opts.on('-b', '--build-options OPTION_FILE', "Specify a path to a yml file with build options for binary gems") do |option_file, options|
38
+ if File.exist?(option_file)
39
+ options[:build_options] = YAML.load_file(option_file)
40
+ end
41
+ end
42
+
43
+ opts.on('--only ENV', "Only expand the given environment. To specify multiple environments, use --only multiple times.") do |env, options|
44
+ options[:only] ||= []
45
+ options[:only] << env
46
+ end
47
+ end.parse!
48
+
49
+ if options[:cache]
50
+ Bundler::CLI.run(:cache, options)
51
+ elsif options[:prune]
52
+ Bundler::CLI.run(:prune, options)
53
+ elsif options[:list]
54
+ Bundler::CLI.run(:list, options)
55
+ elsif options[:list_outdated]
56
+ Bundler::CLI.run(:list_outdated, options)
57
+ else
58
+ Bundler::CLI.run(:bundle, options)
59
+ end