bowline-bundler 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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