summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYehuda Katz + Carl Lerche <ykatz+clerche@engineyard.com>2009-07-29 17:29:34 -0700
committerYehuda Katz + Carl Lerche <ykatz+clerche@engineyard.com>2009-07-29 17:29:34 -0700
commit59d238b4f5063749b4f7d2aa425074897ff27829 (patch)
tree5e8ac2ed0b74a113c2cc6572c4deed404534b7d3
parent4eaf065c6944ba385cbd57a874c3c0767bb269a4 (diff)
downloadbundler-59d238b4f5063749b4f7d2aa425074897ff27829.tar.gz
Switch from gem_bundler to gem bundle and gem exec
-rw-r--r--README.markdown156
-rw-r--r--README.rdoc168
-rw-r--r--Rakefile4
-rwxr-xr-xbin/gem_bundler4
-rw-r--r--lib/bundler/cli.rb49
-rw-r--r--lib/bundler/commands/bundle_command.rb29
-rw-r--r--lib/bundler/commands/exec_command.rb29
-rw-r--r--lib/rubygems_plugin.rb7
-rw-r--r--spec/bundler/cli_spec.rb36
-rw-r--r--spec/bundler/manifest_spec.rb2
-rw-r--r--spec/spec_helper.rb6
11 files changed, 261 insertions, 229 deletions
diff --git a/README.markdown b/README.markdown
new file mode 100644
index 0000000000..b9178d5a5d
--- /dev/null
+++ b/README.markdown
@@ -0,0 +1,156 @@
+## Bundler : A gem to bundle gems
+
+ Github: http://github.com/wycats/bundler
+ Mailing list: http://groups.google.com/group/ruby-bundler
+
+## Intro
+
+Bundler is a tool that manages gem dependencies for your ruby application. It
+takes a gem manifest file and is able to fetch, download, and install the gems
+and all child dependencies specified in this manifest. It can manage any update
+to the gem manifest file and update the bundled gems accordingly. It also lets
+you run any ruby code in context of the bundled gem environment.
+
+## Disclaimer
+
+This project is under rapid development. It is usable today, but there will be
+many changes in the near future, including to the Gemfile DSL. We will bump up
+versions with changes though. We greatly appreciate feedback.
+
+## Installation
+
+Bundler has no dependencies. Just clone the git repository and install the gem
+with the following rake task:
+
+ rake install
+
+## Usage
+
+Bundler requires a gem manifest file to be created. This should be a file named
+`Gemfile` located in the root directory of your application. After the manifest
+has been created, in your shell, cd into your application's directory and run
+`gem bundle`. This will start the bundling process.
+
+### Manifest file
+
+This is where you specify all of your application's dependencies. By default
+this should be in a file named `Gemfile` located in your application's root
+directory. The following is an example of a potential `Gemfile`. For more
+information, please refer to Bundler::ManifestBuilder.
+
+ # Specify a dependency on rails. When the bundler downloads gems,
+ # it will download rails as well as all of rails' dependencies (such as
+ # activerecord, actionpack, etc...)
+ #
+ # At least one dependency must be specified
+ gem "rails"
+
+ # Specify a dependency on rack v.1.0.0. The version is optional. If present,
+ # it can be specified the same way as with rubygems' #gem method.
+ gem "rack", "1.0.0"
+
+ # Specify a dependency rspec, but only activate that gem in the "testing"
+ # environment (read more about environments later). :except is also a valid
+ # option to specify environment restrictions.
+ gem "rspec", :only => :testing
+
+ # Add http://gems.github.com as a source that the bundler will use
+ # to find gems listed in the manifest. By default,
+ # http://gems.rubyforge.org is already added to the list.
+ #
+ # This is an optional setting.
+ source "http://gems.github.com"
+
+ # Specify where the bundled gems should be stashed. This directory will
+ # be a gem repository where all gems are downloaded to and installed to.
+ #
+ # This is an optional setting.
+ # The default is: vendor/gems
+ bundle_path "my/bundled/gems"
+
+ # Specify where gem executables should be copied to.
+ #
+ # This is an optional setting.
+ # The default is: bin
+ bin_path "my/executables"
+
+ # Specify that rubygems should be completely disabled. This means that it
+ # will be impossible to require it and that available gems will be
+ # limited exclusively to gems that have been bundled.
+ #
+ # The default is to automatically require rubygems. There is also a
+ # `disable_system_gems` option that will limit available rubygems to
+ # the ones that have been bundled.
+ disable_rubygems
+
+### Running Bundler
+
+Once a manifest file has been created, the only thing that needs to be done
+is to run the `gem bundle` command anywhere in your application. The script
+will load the manifest file, resole all the dependencies, download all
+needed gems, and install them into the specified directory.
+
+Every time an update is made to the manifest file, run `gem bundle` again to
+get the changes installed. This will only check the remote sources if your
+currently installed gems do not satisfy the `Gemfile`. If you want to force
+checking for updates on the remote sources, use the `--update` option.
+
+### Running your application
+
+The easiest way to run your application is to start it with an executable
+copied to the specified bin directory (by default, simply bin). For example,
+if the application in question is a rack app, start it with `bin/rackup`.
+This will automatically set the gem environment correctly.
+
+Another way to run arbitrary ruby code in context of the bundled gems is to
+run it with the `gem exec` command. For example:
+
+ gem exec ruby my_ruby_script.rb
+
+Yet another way is to manually require the environment file first. This is
+located in `[bundle_path]/environments/default.rb`. For example:
+
+ ruby -r vendor/gems/environments/default.rb my_ruby_script.rb
+
+### Using Bundler with Rails today
+
+It should be possible to use Bundler with Rails today. Here are the steps
+to follow.
+
+* In your rails app, create a Gemfile and specify the gems that your
+ application depends on. Make sure to specify rails as well:
+
+ gem "rails", "2.1.2"
+ gem "will_paginate"
+
+ # Optionally, you can disable system gems all together and only
+ # use bundled gems.
+ disable_system_gems
+
+* Run `gem bundle`
+
+* You can now use rails if you prepend `gem exec` to every call to `script/*`
+ but that isn't fun.
+
+* At the top of `config/boot.rb`, add the following line:
+
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'vendor', 'gems', 'environments', 'default'))
+
+In theory, this should be enough to get going.
+
+## To require rubygems or not
+
+Ideally, no gem would assume the presence of rubygems at runtime. Rubygems provides
+enough features so that this isn't necessary. However, there are a number of gems
+that require specific rubygem features.
+
+If the `disable_rubygems` option is used, Bundler will stub out the most common
+of these features, but it is possible that things will not go as intended quite
+yet. So, if you are brave, try your code without rubygems at runtime.
+
+## Reporting bugs
+
+Please report all bugs on the github issue tracker for the project located
+at:
+
+ http://github.com/wycats/bundler/issues/ \ No newline at end of file
diff --git a/README.rdoc b/README.rdoc
deleted file mode 100644
index fe53386994..0000000000
--- a/README.rdoc
+++ /dev/null
@@ -1,168 +0,0 @@
-== Bundler : A gem to bundle gems
-
- Github: http://github.com/wycats/bundler
-
-== Intro
-
-Bundler is a tool that manages gem dependencies for your ruby application. It
-takes a gem manifest file and is able to fetch, download, and install the gems
-and all child dependencies specified in this manifest. It can manage any update
-to the gem manifest file and update the bundled gems accordingly. It also lets
-you run any ruby code in context of the bundled gem environment.
-
-== Disclaimer
-
-This project is under rapid development. It is usable today, but there will be
-many changes in the near future, including to the Gemfile DSL. We will bump up
-versions with changes though. We greatly appreciate feedback.
-
-== Installation
-
-Bundler has no dependencies. Just clone the git repository and install the gem
-with the following rake task:
-
- rake install
-
-== Usage
-
-Bundler requires a gem manifest file to be created. This should be a file named
-'Gemfile' located in the root directory of your application. After the manifest
-has been created, in your shell, cd into your application's directory and run
-'gem_bundler'. This will start the bundling process.
-
-=== Manifest file
-
-This is where you specify all of your application's dependencies. By default
-this should be in a file named Gemfile located in your application's root
-directory. The following is an example of a potential Gemfile. For more
-information, please refer to Bundler::ManifestBuilder.
-
- # Specify a dependency on rails. When the bundler downloads gems,
- # it will download rails as well as all of rails' dependencies (such as
- # activerecord, actionpack, etc...)
- #
- # At least one dependency must be specified
- gem "rails"
-
- # Specify a dependency on rack v.1.0.0. The version is optional. If present,
- # it can be specified the same way as with rubygems' #gem method.
- gem "rack", "1.0.0"
-
- # Specify a dependency rspec, but only activate that gem in the "testing"
- # environment (read more about environments later). :except is also a valid
- # option to specify environment restrictions.
- gem "rspec", :only => :testing
-
- # Add http://gems.github.com as a source that the bundler will use
- # to find gems listed in the manifest. By default,
- # http://gems.rubyforge.org is already added to the list.
- #
- # This is an optional setting.
- source "http://gems.github.com"
-
- # Specify where the bundled gems should be stashed. This directory will
- # be a gem repository where all gems are downloaded to and installed to.
- #
- # This is an optional setting.
- # The default is: vendor/gems
- bundle_path "my/bundled/gems"
-
- # Specify where gem executables should be copied to.
- #
- # This is an optional setting.
- # The default is: bin
- bin_path "my/executables"
-
- # Specify that rubygems should be completely disabled. This means that it
- # will be impossible to require it and that available gems will be
- # limited exclusively to gems that have been bundled.
- #
- # The default is to not require rubygems automatically (bundled gems are
- # available without rubygems), but rubygems can still be required and it
- # behaves normally.
- disable_rubygems
-
-=== Running Bundler
-
-Once a manifest file has been created, the only thing that needs to be done
-is to run the "gem_bundler" command anywhere in your application. The script
-will load the manifest file, resole all the dependencies, download all
-needed gems, and install them into the specified directory.
-
-Every time an update is made to the manifest file, run "gem_bundler" again to
-get the changes installed.
-
-=== Running your application
-
-The easiest way to run your application is to start it with an executable
-copied to the specified bin directory (by default, simply bin). For example,
-if the application in question is a rack app, start it with bin/rackup. This
-will automatically set the gem environment correctly.
-
-Another way to run arbitrary ruby code in context of the bundled gems is to
-run it with the gem_bundler command. For example:
-
- gem_bundler ruby my_ruby_script.rb
-
-Yet another way is to manually require the environment file first. This is
-located in [bundle_path]/environments/[environment_name].rb. The default
-environment file is default.rb. For example:
-
- ruby -r vendor/gems/environments/default.rb my_ruby_script.rb
-
-=== Using Bundler with Rails today
-
-It should be possible to use Bundler with Rails today. Here are the steps
-to follow.
-
-* In your rails app, create a Gemfile and specify the gems that your
- application depends on. Make sure to specify rails as well:
-
- gem "rails", "2.1.2"
- gem "will_paginate"
-
- # Requiring rubygems seems to be the safest way to go currently.
- require_rubygems
-
- # Optionally, you can disable system gems all together and only
- # use bundled gems.
- disable_system_gems
-
-I would suggest to require_rubygems as of now.
-
-* Run gem_bundler
-
-* You can now use rails if you append "gem_bundler" to every call to script/*
- but that isn't fun.
-
-* At the top of config/boot.rb, add the following line:
-
- require File.expand_path(File.join(File.dirname(__FILE__), '..', 'vendor', 'gems', 'environments', 'default'))
-
-In theory, this should be enough to get going.
-
-== To require rubygems or not
-
-Ideally, no gem would assume the presence of rubygems at runtime. Rubygems provides
-enough features so that this isn't necessary. However, there are a number of gems
-that require specific rubygem features.
-
-Bundler will mock out the most common of these features, but it is possible that things
-will not go as intended quite yet. So, if you are brave, try your code without rubygems
-at runtime. Otherwise, add "require_rubygems" to your Gemfile.
-
-== Environments
-
-More to come...
-
-== Reporting bugs
-
-Please report all bugs on the github issue tracker for the project located
-at:
-
- http://github.com/wycats/bundler/issues/
-
-== Known issues
-
-* Running ruby code with 'gem_bundler ruby my_ruby_script.rb' will require
- the entire Bundler source code which also requires rubygems. \ No newline at end of file
diff --git a/Rakefile b/Rakefile
index 6933e2569c..b629d5e0c2 100644
--- a/Rakefile
+++ b/Rakefile
@@ -16,10 +16,8 @@ spec = Gem::Specification.new do |s|
s.has_rdoc = true
s.extra_rdoc_files = ["README.rdoc", "LICENSE"]
- s.bindir = "bin"
- s.executables = %w( gem_bundler )
s.require_path = 'lib'
- s.files = %w(LICENSE README.rdoc Rakefile) + Dir.glob("{bin,lib,spec}/**/*")
+ s.files = %w(LICENSE README.rdoc Rakefile) + Dir.glob("lib/**/*")
end
task :default => :spec
diff --git a/bin/gem_bundler b/bin/gem_bundler
deleted file mode 100755
index f4e5777423..0000000000
--- a/bin/gem_bundler
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/usr/bin/env ruby
-
-require "bundler"
-Bundler::CLI.run
diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb
index 092a63d80f..2ff3847289 100644
--- a/lib/bundler/cli.rb
+++ b/lib/bundler/cli.rb
@@ -2,24 +2,29 @@ require "optparse"
module Bundler
class CLI
- def self.run(args = ARGV)
- new(args).run
+ def self.run(command, options = {})
+ new(options).run(command)
end
- def initialize(args)
- @args = args
+ def initialize(options)
+ @options = options
+ @manifest_file = Bundler::ManifestFile.load(@options[:manifest])
end
- def run
- parser.parse!(@args)
+ def bundle
+ @manifest_file.install(@options[:update])
+ end
+
+ def exec
+ @manifest_file.setup_environment
+ # w0t?
+ super(*@options[:args])
+ end
+
+ def run(command)
+
+ send(command)
- manifest_file = Bundler::ManifestFile.load(@manifest)
- if @args.empty?
- manifest_file.install(@update)
- else
- manifest_file.setup_environment
- exec(*@args)
- end
rescue DefaultManifestNotFound => e
Bundler.logger.error "Could not find a Gemfile to use"
exit 2
@@ -34,23 +39,5 @@ module Bundler
exit
end
- def parser
- @parser ||= OptionParser.new do |op|
- op.banner = "Usage: gem_bundler [OPTIONS] [PATH]"
-
- op.on("-m", "--manifest MANIFEST") do |manifest|
- @manifest = Pathname.new(manifest)
- end
-
- op.on("-u", "--update", "Force a remote check for newer gems") do
- @update = true
- end
-
- op.on_tail("-h", "--help", "Show this message") do
- puts op
- exit
- end
- end
- end
end
end
diff --git a/lib/bundler/commands/bundle_command.rb b/lib/bundler/commands/bundle_command.rb
new file mode 100644
index 0000000000..cbfd9cf99e
--- /dev/null
+++ b/lib/bundler/commands/bundle_command.rb
@@ -0,0 +1,29 @@
+class Gem::Commands::BundleCommand < Gem::Command
+
+ def initialize
+ super('bundle', 'Create a gem bundle based on your Gemfile', {:manifest => nil, :update => false})
+
+ add_option('-m', '--manifest MANIFEST', "Specify the path to the manifest file") do |manifest, options|
+ options[:manifest] = Pathname.new(manifest)
+ end
+
+ add_option('-u', '--update', "Force a remote check for newer gems") do
+ options[:update] = true
+ end
+ end
+
+ def usage
+ "#{program_name}"
+ end
+
+ def description # :nodoc:
+ <<-EOF
+Bundle stuff
+ EOF
+ end
+
+ def execute
+ Bundler::CLI.run(:bundle, options)
+ end
+
+end \ No newline at end of file
diff --git a/lib/bundler/commands/exec_command.rb b/lib/bundler/commands/exec_command.rb
new file mode 100644
index 0000000000..433b54a1ff
--- /dev/null
+++ b/lib/bundler/commands/exec_command.rb
@@ -0,0 +1,29 @@
+class Gem::Commands::ExecCommand < Gem::Command
+
+ def initialize
+ super('exec', 'Run a command in context of a gem bundle', {:manifest => nil})
+
+ add_option('-m', '--manifest MANIFEST', "Specify the path to the manifest file") do |manifest, options|
+ options[:manifest] = Pathname.new(manifest)
+ end
+ end
+
+ def usage
+ "#{program_name} COMMAND"
+ end
+
+ def arguments # :nodoc:
+ "COMMAND command to run in context of the gem bundle"
+ end
+
+ def description # :nodoc:
+ <<-EOF.gsub(' ', '')
+ Run in context of a bundle
+ EOF
+ end
+
+ def execute
+ Bundler::CLI.run(:exec, options)
+ end
+
+end \ No newline at end of file
diff --git a/lib/rubygems_plugin.rb b/lib/rubygems_plugin.rb
new file mode 100644
index 0000000000..09aa2b8512
--- /dev/null
+++ b/lib/rubygems_plugin.rb
@@ -0,0 +1,7 @@
+require 'rubygems/command_manager'
+require 'bundler'
+require 'bundler/commands/bundle_command'
+require 'bundler/commands/exec_command'
+
+Gem::CommandManager.instance.register_command :bundle
+Gem::CommandManager.instance.register_command :exec \ No newline at end of file
diff --git a/spec/bundler/cli_spec.rb b/spec/bundler/cli_spec.rb
index 4e2add24a6..25dc6646d2 100644
--- a/spec/bundler/cli_spec.rb
+++ b/spec/bundler/cli_spec.rb
@@ -12,11 +12,8 @@ describe "Bundler::CLI" do
gem "rack", :only => :web
Gemfile
- lib = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib'))
- bin = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'bin', 'gem_bundler'))
-
Dir.chdir(tmp_dir) do
- @output = `#{Gem.ruby} -I #{lib} #{bin}`
+ @output = gem_command :bundle
end
end
@@ -42,7 +39,7 @@ describe "Bundler::CLI" do
end
it "creates an executable for rake in ./bin" do
- out = `#{tmp_file('bin', 'rake')} -e 'puts $:'`
+ out = run_in_context "puts $:"
out.should include(tmp_file("vendor", "gems", "gems", "rake-0.8.7", "lib").to_s)
out.should include(tmp_file("vendor", "gems", "gems", "rake-0.8.7", "bin").to_s)
out.should include(tmp_file("vendor", "gems", "gems", "extlib-0.9.12", "lib").to_s)
@@ -98,7 +95,7 @@ describe "Bundler::CLI" do
Gemfile
Dir.chdir(tmp_file)
- Bundler::CLI.run(["-m", tmp_file('manifest.rb').to_s])
+ gem_command :bundle, "-m #{tmp_file('manifest.rb')}"
tmp_file("gems").should have_cached_gems("rake-0.8.7")
end
@@ -111,7 +108,7 @@ describe "Bundler::CLI" do
Gemfile
Dir.chdir(tmp_file)
- Bundler::CLI.run(["-m", tmp_file('config', 'manifest.rb').to_s])
+ gem_command :bundle, "-m #{tmp_file('config', 'manifest.rb')}"
tmp_file("gems").should have_cached_gems("rake-0.8.7")
end
end
@@ -128,32 +125,29 @@ describe "Bundler::CLI" do
disable_rubygems
Gemfile
- lib = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib'))
- bin = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'bin', 'gem_bundler'))
-
Dir.chdir(tmp_dir) do
- @output = `#{Gem.ruby} -I #{lib} #{bin}`
+ @output = gem_command :bundle
end
end
it "does not load rubygems when required" do
- out = `#{tmp_file('bin', 'rake')} -e 'require "rubygems" ; puts Gem.respond_to?(:sources)'`
- out.should =~ /false/
+ out = run_in_context 'require "rubygems" ; puts Gem.respond_to?(:sources)'
+ out.should == "false"
end
it "does not blow up if #gem is used" do
- out = `#{tmp_file('bin', 'rake')} -e 'gem("merb-core") ; puts "Win!"'`
- out.should =~ /Win!/
+ out = run_in_context 'gem("merb-core") ; puts "Win!"'
+ out.should == "Win!"
end
it "does not blow up if Gem errors are referred to" do
- out = `#{tmp_file('bin', 'rake')} -e 'Gem::LoadError ; Gem::Exception ; puts "Win!"'`
- out.should =~ /Win!/
+ out = run_in_context 'Gem::LoadError ; Gem::Exception ; puts "Win!"'
+ out.should == "Win!"
end
it "stubs out Gem.ruby" do
- out = `#{tmp_file("bin", "rake")} -e 'puts Gem.ruby'`
- out.should == "#{Gem.ruby}\n"
+ out = run_in_context "puts Gem.ruby"
+ out.should == Gem.ruby
end
end
@@ -174,10 +168,8 @@ describe "Bundler::CLI" do
gem "rack"
Gemfile
- lib = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib'))
- bin = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'bin', 'gem_bundler'))
Dir.chdir(tmp_dir) do
- `#{Gem.ruby} -I #{lib} #{bin} --update`
+ gem_command :bundle, "--update"
end
tmp_file("vendor", "gems").should have_cached_gems("rack-1.0.0")
tmp_file("vendor", "gems").should have_installed_gems("rack-1.0.0")
diff --git a/spec/bundler/manifest_spec.rb b/spec/bundler/manifest_spec.rb
index c2bf8977f4..b843e5262e 100644
--- a/spec/bundler/manifest_spec.rb
+++ b/spec/bundler/manifest_spec.rb
@@ -132,7 +132,7 @@ describe "Bundler::Manifest" do
Dir.chdir(tmp_dir)
lambda do
- Bundler::CLI.run([])
+ Bundler::CLI.run(:bundle)
end.should raise_error(SystemExit)
@log_output.should have_log_message(/rails \(= 2\.3\.2.*rack \(= 0\.9\.1.*active_support \(= 2\.0/m)
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 5f771d6f6c..a4cd2df389 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -74,6 +74,12 @@ module Spec
%x{#{Gem.ruby} -r #{env} -e "#{cmd}"}.strip
end
+ def gem_command(command, args = "")
+ args = args.gsub(/(?=")/, "\\")
+ lib = File.join(File.dirname(__FILE__), '..', 'lib')
+ %x{#{Gem.ruby} -I#{lib} -rubygems -S gem #{command} #{args}}
+ end
+
def build_manifest_file(*args)
path = tmp_file("Gemfile")
path = args.shift if args.first.is_a?(Pathname)