diff options
author | Andre Arko <andre@arko.net> | 2010-04-07 13:25:45 -0700 |
---|---|---|
committer | Andre Arko <andre@arko.net> | 2010-04-07 13:25:45 -0700 |
commit | 5252fd7fad7eade354e121728277fd2295f8e4cf (patch) | |
tree | 1681079bf049229e384a4842b70c5fcae5b60db6 | |
parent | bc3450ff34c6eed55ec3a3914ad1c00d76e87342 (diff) | |
parent | 27088807722e2a259ad47716a6e01d6411f8477d (diff) | |
download | bundler-5252fd7fad7eade354e121728277fd2295f8e4cf.tar.gz |
Merge in 0.9.17
28 files changed, 353 insertions, 255 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index bd878e452a..81da60b5af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,38 @@ +## 0.9.16 (April 3, 2010) + +Features: + + - exit gracefully on INT signal + - resolver output now indicates whether remote sources were checked + - print error instead of backtrace when exec cannot find a binary (#241) + +Bugfixes: + + - show, check, and open commands work again while locked (oops) + - show command for git gems + - outputs branch names other than master + - gets the correct sha from the checkout + - doesn't print sha twice if :ref is set + - report errors from bundler/setup.rb without backtraces (#243) + - fix Gem::Spec#git_version to not error on unloaded specs + - improve deprecation, Gemfile, and command error messages (#242) + +## 0.9.15 (April 1, 2010) + +Features: + + - use the env_file if possible instead of doing a runtime resolve + - huge speedup when calling Bundler.setup while locked + - ensures bundle exec is fast while locked + - regenerates env_file if it was generated by an older version + - update cached/packed gems when you update gems via bundle install + +Bugfixes: + + - prep for Rubygems 1.3.7 changes + - install command now pulls git branches correctly (#211) + - raise errors on invalid options in the Gemfile + ## 0.9.14 (March 30, 2010) Features: @@ -6,169 +6,11 @@ and all child dependencies specified in this manifest. It can manage any update to the gem manifest file and update the bundle's gems accordingly. It also lets you run any ruby code in context of the bundle's gem environment. -## Installation +## Installation and usage -If you are upgrading from Bundler 0.8, be sure to read the upgrade notes -located at the bottom of this file. +See [gembundler.com](http://gembundler.com) for up-to-date installation and usage instructions -Bundler has no dependencies besides Ruby and RubyGems. You can install the -latest release via RubyGems: - - gem install bundler - -If you want to contribute, or need a change that hasn't been released yet, -just clone the git repository and install the gem with rake: - - rake install - -## Usage - -The first thing to do is create a gem manifest file named `Gemfile` at the -root directory of your application. This can quickly be done by running -`bundle init` in the directory that you wish the Gemfile to be created in. - -### Gemfile - -This is where you specify all of your application's dependencies. The -following is an example. For more information, refer to Bundler::Dsl. - - # Add :gemcutter as a source that Bundler will use to find gems listed - # in the manifest. At least one source should be listed. URLs may also - # be used, such as http://gems.github.com. - # - source :gemcutter - - # Specify a dependency on rails. When 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" - - # Add a git repository as a source. Valid options include :branch, :tag, - # and :ref. Next, add any gems that you want from that repo. - # - git "git://github.com/indirect/rails3-generators.git" - gem "rails3-generators" - -### Groups - -Applications may have dependencies that are specific to certain environments, -such as testing or deployment. - -You can specify groups of gems in the Gemfile using the following syntax: - - gem "nokogiri", :group => :test - - # or - - group :test do - gem "webrat" - end - -Note that Bundler adds all the gems without an explicit group name to the -`:default` group. - -Groups are involved in a number of scenarios: - -1. When installing gems using bundle install, you can choose to leave - out any group by specifying `--without group1 group2`. This can be - helpful if, for instance, you have a gem that you cannot compile - in certain environments. -2. When setting up load paths using Bundler.setup, Bundler will, by - default, add the load paths for all groups. You can restrict the - groups to add by doing `Bundler.setup(:group, :names)`. If you do - this, you need to specify the `:default` group if you want it - included. -3. When auto-requiring files using Bundler.require, Bundler will, - by default, auto-require just the `:default` group. You can specify - a list of groups to auto-require such as - `Bundler.require(:default, :test)` - -### Installing gems - -Once the Gemfile manifest file has been created, the next step is to install -all the gems needed to satisfy the manifest's dependencies. The command to -do this is `bundle install`. - -This command will load the Gemfile, resolve all the dependencies, download -all gems that are missing, and install them to the bundler's gem repository. -Gems that are already installed into the system RubyGems repository will be -referenced, rather than installed again. Every time an update is made to the -Gemfile, run `bundle install` again to install any newly needed gems. - -If you want to install the gems into the project's folder, like Bundler 0.8 -and earlier did, you can run `bundle install vendor`, and the gems will -be installed into the `vendor` subdirectory of your project. - -### Locking dependencies - -By default, bundler will only ensure that the activated gems satisfy the -Gemfile's dependencies. If you install a newer version of a gem and it -satisfies the dependencies, it will be used instead of the older one. - -The command `bundle lock` will lock the bundle to the current set of -resolved gems. This ensures that, until the lock file is removed, -`bundle install` and `Bundle.setup` will always activate the same gems. - -When you are distributing your application, you should add the Gemfile and -Gemfile.lock files to your source control, so that the set of libraries your -code will run against are fixed. Simply run `bundle install` after checking -out or deploying your code to ensure your libraries are present. - -DO NOT add the .bundle directory to your source control. The files there are -internal to bundler and vary between machines. If you are using git, you can -exclude all machine-specific bundler files by adding a single line to your -.gitignore file containing `.bundle`. - -### Running the application - -Bundler must be required and setup before anything else is required. This -is because it will configure all the load paths and manage gems for you. -To do this, include the following at the beginning of your code. - - begin - # Try to require the preresolved locked set of gems. - require File.expand_path('../.bundle/environment', __FILE__) - rescue LoadError - # Fall back on doing an unlocked resolve at runtime. - require "rubygems" - require "bundler" - Bundler.setup - end - - # Your application's requires come here, e.g. - # require 'date' # a ruby standard library - # require 'rack' # a bundled gem - - # Alternatively, you can require all the bundled libs at once - # Bundler.require - -The `bundle exec` command provides a way to run arbitrary ruby code in -context of the bundle. For example: - - bundle exec ruby my_ruby_script.rb - -To enter a shell that will run all gem executables (such as `rake`, `rails`, -etc... ) use `bundle exec bash` (replacing bash for whatever your favorite -shell is). - -### Packing the bundle's gems - -When sharing or deploying an application, you may want to include -everything necessary to install gem dependencies. `bundle package` will -copy .gem files for all of the bundle's dependencies into vendor/cache. -After that, `bundle install` will always work, since it will install the -local .gem files, and will not contact any of the remote sources. - -## Gem resolution +## Gem dependency resolution One of the most important things that the bundler does is do a dependency resolution on the full list of gems that you specify, all @@ -205,12 +47,6 @@ so it can detect that all gems *together* require activesupport "2.3.4". Upgrading to Bundler 0.9 from Bundler 0.8 requires upgrading several API calls in your Gemfile, and some workarounds if you are using Rails 2.3. -### Rails 2.3 - -Using Bundler 0.9 with Rails 2.3 requires adding a preinitializer, and -making a few changes to boot.rb. A detailed description of the changes -needed can be found in [Bundler 0.9 and Rails 2.3.5](http://andre.arko.net/2010/02/13/using-bundler-09-with-rails-235/). - ### Gemfile Removals Bundler 0.9 removes the following Bundler 0.8 Gemfile APIs: @@ -278,10 +114,6 @@ Bundler 0.9 changes the following Bundler 0.8 Gemfile APIs: For information about future plans and changes that will happen between now and bundler 1.0, see the [ROADMAP](http://github.com/carlhuda/bundler/blob/master/ROADMAP.md). To see what has changed in each version of bundler, starting with 0.9.5, see the [CHANGELOG](http://github.com/carlhuda/bundler/blob/master/CHANGELOG.md). -### Usage - -Explanations of common Bundler use cases can be found in [Using Bundler in Real Life](http://yehudakatz.com/2010/02/09/using-bundler-in-real-life/). The general philosophy behind Bundler 0.9 is explained at some length in [Bundler 0.9: Heading Toward 1.0](http://yehudakatz.com/2010/02/01/bundler-0-9-heading-toward-1-0/). Using Bundler with a Rails 2.3.5 app is explained with more detail in [Bundler 0.9 and Rails 2.3.5](http://andre.arko.net/2010/02/13/using-bundler-09-with-rails-235/). - ### Deploying to memory-constrained servers When deploying to a server that is memory-constrained, like Dreamhost, you should run `bundle package` on your local development machine, and then check in the resulting `Gemfile.lock` file and `vendor/cache` directory. The lockfile and cached gems will mean bundler can just install the gems immediately, without contacting any gem servers or using a lot of memory to resolve the dependency tree. On the server, you only need to run `bundle install` after you update your deployed code. diff --git a/bin/bundle b/bin/bundle index 1877540982..d2e50814b5 100644..100755 --- a/bin/bundle +++ b/bin/bundle @@ -14,4 +14,7 @@ begin rescue Bundler::BundlerError => e Bundler.ui.error e.message exit e.status_code +rescue Interrupt + Bundler.ui.error "\nQuitting..." + exit 1 end
\ No newline at end of file diff --git a/lib/bundler.rb b/lib/bundler.rb index 7f7137e890..471aca719a 100644 --- a/lib/bundler.rb +++ b/lib/bundler.rb @@ -71,11 +71,21 @@ module Bundler end def require(*groups) - load.require(*groups) + setup(*groups).require(*groups) end def load - Runtime.new root, definition + if current_env_file? + SharedHelpers.gem_loaded = true + Kernel.require env_file + Bundler + else + runtime + end + end + + def runtime + Runtime.new(root, definition) end def definition @@ -112,6 +122,10 @@ module Bundler @settings ||= Settings.new(root) end + def env_file + SharedHelpers.env_file + end + def with_clean_env bundled_env = ENV.to_hash ENV.replace(ORIGINAL_ENV) @@ -131,12 +145,16 @@ module Bundler ENV['GEM_HOME'] = File.expand_path(bundle_path, root) ENV['GEM_PATH'] = '' else - paths = [Gem.dir, Gem.path].flatten.compact.reject{|p| p.empty? } + paths = [Gem.dir, Gem.path].flatten.compact.uniq.reject{|p| p.empty? } ENV["GEM_PATH"] = paths.join(File::PATH_SEPARATOR) ENV["GEM_HOME"] = bundle_path.to_s end Gem.clear_paths end + + def current_env_file? + env_file.exist? && (env_file.read(100) =~ /Bundler #{Bundler::VERSION}/) + end end end diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb index bc6e930788..c8e9f01942 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -44,7 +44,7 @@ module Bundler desc "check", "Checks if the dependencies listed in Gemfile are satisfied by currently installed gems" def check - env = Bundler.load + env = Bundler.runtime # Check top level dependencies missing = env.dependencies.select { |d| env.index.search(d).empty? } if missing.any? @@ -52,14 +52,14 @@ module Bundler missing.each do |d| Bundler.ui.error " * #{d}" end - Bundler.ui.error "Try running `bundle install`" + Bundler.ui.warn "Install missing gems with `bundle install`" exit 1 else not_installed = env.requested_specs.select { |spec| !spec.loaded_from } if not_installed.any? not_installed.each { |s| Bundler.ui.error "#{s.name} (#{s.version}) is cached, but not installed" } - Bundler.ui.error "Try running `bundle install`" + Bundler.ui.warn "Install missing gems with `bundle install`" exit 1 else Bundler.ui.info "The Gemfile's dependencies are satisfied" @@ -88,6 +88,7 @@ module Bundler Installer.install(Bundler.root, Bundler.definition, opts) lock if options[:relock] + cache if Bundler.root.join("vendor/cache").exist? rescue GemNotFound => e if Bundler.definition.sources.empty? Bundler.ui.warn "Your Gemfile doesn't have any sources. You can add one with a line like 'source :gemcutter'" @@ -102,15 +103,14 @@ module Bundler remove_lockfiles end - environment = Bundler.load - environment.lock + Bundler.runtime.lock rescue GemNotFound, VersionConflict => e Bundler.ui.error(e.message) - Bundler.ui.info "Run `bundle install` to install missing gems" + Bundler.ui.warn "Run `bundle install` to install missing gems." exit 128 end - desc "unlock", "Unlock the bundle. This allows gem versions to be changed" + desc "unlock", "Unlock the bundle. This allows gem versions to be changed." def unlock if locked? remove_lockfiles @@ -125,9 +125,8 @@ module Bundler if gem_name Bundler.ui.info locate_gem(gem_name) else - environment = Bundler.load Bundler.ui.info "Gems included by the bundle:" - environment.specs.sort_by { |s| s.name }.each do |s| + Bundler.runtime.specs.sort_by { |s| s.name }.each do |s| Bundler.ui.info " * #{s.name} (#{s.version}#{s.git_version})" end end @@ -136,11 +135,10 @@ module Bundler desc "cache", "Cache all the gems to vendor/cache" def cache - environment = Bundler.load - environment.cache + Bundler.runtime.cache rescue GemNotFound => e Bundler.ui.error(e.message) - Bundler.ui.info "Run `bundle install` to install missing gems." + Bundler.ui.warn "Run `bundle install` to install missing gems." exit 128 end @@ -169,8 +167,13 @@ module Bundler rubyopt.unshift "-I#{File.expand_path('../..', __FILE__)}" ENV["RUBYOPT"] = rubyopt.join(' ') - # Run - Kernel.exec *ARGV + begin + # Run + Kernel.exec *ARGV + rescue Errno::ENOENT + Bundler.ui.error "bundler: command not found: #{ARGV.first}" + Bundler.ui.warn "Install missing gem binaries with `bundle install`" + end end desc "open GEM", "Opens the source directory of the given bundled gem" @@ -203,7 +206,7 @@ module Bundler end def locate_gem(name) - spec = Bundler.load.specs.find{|s| s.name == name } + spec = Bundler.runtime.specs.find{|s| s.name == name } raise GemNotFound, "Could not find gem '#{name}' in the current bundle." unless spec spec.full_gem_path end diff --git a/lib/bundler/dsl.rb b/lib/bundler/dsl.rb index 4a70d881b2..b76b1a3738 100644 --- a/lib/bundler/dsl.rb +++ b/lib/bundler/dsl.rb @@ -64,13 +64,20 @@ module Bundler # Deprecated methods - def self.deprecate(name) + def self.deprecate(name, replacement = nil) define_method(name) do |*| - raise DeprecatedMethod, "#{name} is removed. See the README for more information" + message = "'#{name}' has been removed from the Gemfile DSL, " + if replacement + message << "and has been replaced with '#{replacement}'." + else + message << "and is no longer supported." + end + message << "\nSee the README for more information on upgrading from Bundler 0.8." + raise DeprecatedMethod, message end end - deprecate :only + deprecate :only, :group deprecate :except deprecate :disable_system_gems deprecate :disable_rubygems @@ -101,9 +108,13 @@ module Bundler invalid_keys = opts.keys - %w(group git path name branch ref tag require) if invalid_keys.any? plural = invalid_keys.size > 1 - raise InvalidOption, "You passed #{invalid_keys.join(", ")} " \ - "#{plural ? 'as options, but they are' : 'as an option, but it is'}" \ - " invalid" + message = "You passed #{invalid_keys.map{|k| ':'+k }.join(", ")} " + if plural + message << "as options for gem '#{name}', but they are invalid." + else + message << "as an option for gem '#{name}', but it is invalid." + end + raise InvalidOption, message end group = opts.delete("group") || @group diff --git a/lib/bundler/environment.rb b/lib/bundler/environment.rb index 6457bdf68f..5c5dc5338b 100644 --- a/lib/bundler/environment.rb +++ b/lib/bundler/environment.rb @@ -86,16 +86,12 @@ module Bundler shared_helpers = File.read(File.expand_path("../shared_helpers.rb", __FILE__)) template = File.read(File.expand_path("../templates/environment.erb", __FILE__)) erb = ERB.new(template, nil, '-') - FileUtils.mkdir_p(rb_lock_file.dirname) - File.open(rb_lock_file, 'w') do |f| + Bundler.env_file.dirname.mkpath + File.open(Bundler.env_file, 'w') do |f| f.puts erb.result(binding) end end - def rb_lock_file - root.join(".bundle/environment.rb") - end - def gemfile_fingerprint Digest::SHA1.hexdigest(File.read("#{root}/Gemfile")) end diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb index fa9318480b..d92035f86f 100644 --- a/lib/bundler/index.rb +++ b/lib/bundler/index.rb @@ -68,6 +68,12 @@ module Bundler end end + def sources + @specs.values.map do |specs| + specs.map{|s| s.source.class } + end.flatten.uniq + end + alias [] search def <<(spec) diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb index 6259b8cd5a..a1371bd94b 100644 --- a/lib/bundler/resolver.rb +++ b/lib/bundler/resolver.rb @@ -148,18 +148,19 @@ module Bundler versions = @source_requirements[name][name].map { |s| s.version } message = "Could not find gem '#{current}' in #{current.source}.\n" if versions.any? - message << "Source contains '#{current.name}' at: #{versions.join(', ')}" + message << "Source contains '#{name}' at: #{versions.join(', ')}" else message << "Source does not contain any versions of '#{current}'" end - - raise GemNotFound, message else - raise GemNotFound, "Could not find gem '#{current}' in any of the sources." + message = "Could not find gem '#{current}' " + if @index.sources.include?(Bundler::Source::Rubygems) + message << "in any of the gem sources." + else + message << "in the gems available on this machine." + end end - location = current.source ? current.source.to_s : "any of the sources" - raise GemNotFound, "Could not find gem '#{current}' in #{location}.\n" \ - "Source contains fo" + raise GemNotFound, message else @errors[current.name] = [nil, current] end diff --git a/lib/bundler/rubygems_ext.rb b/lib/bundler/rubygems_ext.rb index 4c94b40cf9..647bfe12bb 100644 --- a/lib/bundler/rubygems_ext.rb +++ b/lib/bundler/rubygems_ext.rb @@ -18,11 +18,11 @@ module Gem end def git_version - Dir.chdir(full_gem_path) do - rev = `git rev-parse HEAD`.strip[0...6] - branch = `git show-branch --no-color 2>/dev/null`.strip[/\[(.*?)\]/, 1] - branch.empty? ? " #{rev}" : " #{branch}-#{rev}" - end if File.exist?(File.join(full_gem_path, ".git")) + if @loaded_from && File.exist?(File.join(full_gem_path, ".git")) + sha = Dir.chdir(full_gem_path){ `git rev-parse HEAD`.strip } + branch = full_gem_path.split("-")[3] + (branch && branch != sha) ? " #{branch}-#{sha[0...6]}" : " #{sha[0...6]}" + end end def to_gemfile(path = nil) @@ -31,11 +31,12 @@ module Gem gemfile << dependencies_to_gemfile(development_dependencies, :development) end - def add_bundler_dependencies + def add_bundler_dependencies(*groups) + groups = [:default] if groups.empty? Bundler.definition.dependencies.each do |dep| if dep.groups.include?(:development) self.add_development_dependency(dep.name, dep.requirement.to_s) - else + elsif (dep.groups & groups).any? self.add_dependency(dep.name, dep.requirement.to_s) end end diff --git a/lib/bundler/runtime.rb b/lib/bundler/runtime.rb index eaee01ea20..b037a516d9 100644 --- a/lib/bundler/runtime.rb +++ b/lib/bundler/runtime.rb @@ -15,7 +15,9 @@ module Bundler # Has to happen first clean_load_path - specs = groups.any? ? specs_for(groups) : requested_specs + unloaded = groups - (@loaded_groups || []) + @loaded_groups = groups | (@loaded_groups || []) + specs = unloaded.any? ? specs_for(unloaded) : requested_specs cripple_rubygems(specs) @@ -26,7 +28,9 @@ module Bundler end Gem.loaded_specs[spec.name] = spec - $LOAD_PATH.unshift(*spec.load_paths) + spec.load_paths.each do |path| + $LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path) + end end self end @@ -56,7 +60,7 @@ module Bundler FileUtils.mkdir_p("#{root}/.bundle") write_yml_lock write_rb_lock - Bundler.ui.info("The bundle is now locked. Use `bundle show` to list the gems in the environment.") + Bundler.ui.confirm("The bundle is now locked. Use `bundle show` to list the gems in the environment.") end def dependencies_for(*groups) diff --git a/lib/bundler/setup.rb b/lib/bundler/setup.rb index 8265c3d355..645320c011 100644 --- a/lib/bundler/setup.rb +++ b/lib/bundler/setup.rb @@ -1,13 +1,19 @@ # This is not actually required by the actual library +# loads the bundled environment require 'bundler/shared_helpers' if Bundler::SharedHelpers.in_bundle? - locked_env = Bundler::SharedHelpers.default_gemfile.join("../.bundle/environment.rb") - if locked_env.exist? - require locked_env + env_file = Bundler::SharedHelpers.env_file + if env_file.exist? + require env_file else require 'rubygems' require 'bundler' - Bundler.setup + begin + Bundler.setup + rescue Bundler::BundlerError => e + puts "\e[31m#{e.message}\e[0m" + exit e.status_code + end end end
\ No newline at end of file diff --git a/lib/bundler/shared_helpers.rb b/lib/bundler/shared_helpers.rb index 1597c5eb04..e476e11011 100644 --- a/lib/bundler/shared_helpers.rb +++ b/lib/bundler/shared_helpers.rb @@ -12,10 +12,11 @@ end module Bundler module SharedHelpers + attr_accessor :gem_loaded def default_gemfile gemfile = find_gemfile - gemfile or raise GemfileNotFound, "The default Gemfile was not found" + gemfile or raise GemfileNotFound, "Could not locate Gemfile" Pathname.new(gemfile) end @@ -23,6 +24,10 @@ module Bundler find_gemfile end + def env_file + default_gemfile.dirname.join(".bundle/environment.rb") + end + private def find_gemfile diff --git a/lib/bundler/specification.rb b/lib/bundler/specification.rb index 97798f607b..0f3f0f7020 100644 --- a/lib/bundler/specification.rb +++ b/lib/bundler/specification.rb @@ -16,7 +16,7 @@ module Bundler end def full_gem_path - Pathname.new(loaded_from).dirname.expand_path + Pathname.new(loaded_from).dirname.expand_path.to_s end end diff --git a/lib/bundler/templates/environment.erb b/lib/bundler/templates/environment.erb index e7d4af5a7d..2fca6bbf20 100644 --- a/lib/bundler/templates/environment.erb +++ b/lib/bundler/templates/environment.erb @@ -1,8 +1,8 @@ # DO NOT MODIFY THIS FILE +# Generated by Bundler <%= Bundler::VERSION %> require 'digest/sha1' require 'rubygems' - <%= shared_helpers %> module Bundler @@ -50,8 +50,11 @@ module Bundler configure_gem_path_and_home(SPECS) SPECS.each do |spec| Gem.loaded_specs[spec.name] = spec - $LOAD_PATH.unshift(*spec.require_paths) + spec.require_paths.each do |path| + $LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path) + end end + self end def self.require(*groups) @@ -70,6 +73,6 @@ module Bundler end end - # Setup bundle when it's required. - setup + # Set up load paths unless this file is being loaded after the Bundler gem + setup unless gem_loaded end diff --git a/spec/install/deprecated_spec.rb b/spec/install/deprecated_spec.rb index b5625dc959..8356a42ba1 100644 --- a/spec/install/deprecated_spec.rb +++ b/spec/install/deprecated_spec.rb @@ -14,7 +14,8 @@ describe "bundle install with deprecated features" do G bundle :install - out.should =~ /#{deprecated} is removed. See the README for more information/ + out.should =~ /'#{deprecated}' has been removed/ + out.should =~ /See the README for more information/ end end diff --git a/spec/install/gems/packed_spec.rb b/spec/install/gems/packed_spec.rb index 378d48fa0e..9611660b67 100644 --- a/spec/install/gems/packed_spec.rb +++ b/spec/install/gems/packed_spec.rb @@ -36,5 +36,20 @@ describe "bundle install with gem sources" do err.should be_empty should_be_installed "rack 1.0" end + + it "updates the cache if it exists" do + install_gemfile <<-G + source "file://#{gem_repo1}" + gem "rack" + G + + cached_gem = bundled_app("vendor/cache/rack-1.0.0.gem") + bundle "pack" + FileUtils.rm_rf(cached_gem) + bundle "install" + + out.should include("Copying .gem files into vendor/cache") + cached_gem.should exist + end end end
\ No newline at end of file diff --git a/spec/install/git_spec.rb b/spec/install/git_spec.rb index 264c539f50..2dfc8ef7af 100644 --- a/spec/install/git_spec.rb +++ b/spec/install/git_spec.rb @@ -284,4 +284,24 @@ describe "bundle install with git sources" do out.should match(/could not find gem 'foo/i) out.should match(/run `bundle install`/i) end + + it "handles long gem names and full shas with C extensions" do + build_git "some_gem_with_a_really_stupidly_long_name_argh" do |s| + s.executables = "stupid" + s.add_c_extension + end + sha = revision_for(lib_path("some_gem_with_a_really_stupidly_long_name_argh-1.0")) + install_gemfile <<-G + gem "some_gem_with_a_really_stupidly_long_name_argh", + :git => "#{lib_path("some_gem_with_a_really_stupidly_long_name_argh-1.0")}", + :ref => "#{sha}" + G + should_be_installed "some_gem_with_a_really_stupidly_long_name_argh 1.0" + + bundle "show some_gem_with_a_really_stupidly_long_name_argh" + puts out + + bundle "exec stupid" + out.should == "1.0" + end end diff --git a/spec/install/invalid_spec.rb b/spec/install/invalid_spec.rb index f85141a755..852c823589 100644 --- a/spec/install/invalid_spec.rb +++ b/spec/install/invalid_spec.rb @@ -11,7 +11,7 @@ describe "bundle install with deprecated features" do G bundle :install - out.should =~ /You passed lib as an option, but it is invalid/ + out.should =~ /You passed :lib as an option for gem 'rack', but it is invalid/ end end diff --git a/spec/other/check_spec.rb b/spec/other/check_spec.rb index 8e92c1f83f..6854b1bbc7 100644 --- a/spec/other/check_spec.rb +++ b/spec/other/check_spec.rb @@ -86,10 +86,10 @@ describe "bundle check" do @exitstatus.should == 1 end - it "outputs an error when the default Gemspec is not found" do + it "outputs an error when the default Gemfile is not found" do bundle :check, :exit_status => true @exitstatus.should == 10 - out.should include("The default Gemfile was not found") + out.should include("Could not locate Gemfile") end describe "when locked" do @@ -97,9 +97,9 @@ describe "bundle check" do system_gems "rack-1.0.0" gemfile <<-G source "file://#{gem_repo1}" - gem "rack" + gem "rack", "1.0" G - bundle "lock" + bundle :lock end it "rebuilds .bundle/environment.rb " do @@ -107,5 +107,19 @@ describe "bundle check" do bundle :check bundled_app('.bundle/environment.rb').should exist end + + it "returns success when the Gemfile is satisfied" do + bundle :install + bundle :check, :exit_status => true + @out.should == "The Gemfile's dependencies are satisfied" + @exitstatus.should == 0 + end + + it "shows what is missing with the current Gemfile if it is not satisfied" do + simulate_new_machine + bundle :check, :exit_status => true + @out.should include("rack (= 1.0.0, runtime)") + @exitstatus.should == 7 + end end end diff --git a/spec/other/exec_spec.rb b/spec/other/exec_spec.rb index 2102598566..3977e3d51f 100644 --- a/spec/other/exec_spec.rb +++ b/spec/other/exec_spec.rb @@ -133,6 +133,7 @@ describe "bundle exec" do it "works when locked" do bundle "lock" should_be_locked + bundle "exec fizz" out.should == "1.0" end diff --git a/spec/other/open_spec.rb b/spec/other/open_spec.rb index 8fc4534e9a..59d5eb7b01 100644 --- a/spec/other/open_spec.rb +++ b/spec/other/open_spec.rb @@ -22,4 +22,20 @@ describe "bundle open" do bundle "open missing", :env => {"EDITOR" => "echo editor", "VISUAL" => ''} out.should match(/could not find gem 'missing'/i) end + + describe "while locked" do + before :each do + bundle :lock + end + + it "opens the gem with EDITOR if set" do + bundle "open rails", :env => {"EDITOR" => "echo editor", "VISUAL" => ''} + out.should == "editor #{default_bundle_path('gems', 'rails-2.3.2')}" + end + + it "complains if gem not in bundle" do + bundle "open missing", :env => {"EDITOR" => "echo editor", "VISUAL" => ''} + out.should match(/could not find gem 'missing'/i) + end + end end diff --git a/spec/other/show_spec.rb b/spec/other/show_spec.rb index b69c298f58..2c2936f365 100644 --- a/spec/other/show_spec.rb +++ b/spec/other/show_spec.rb @@ -17,4 +17,62 @@ describe "bundle show" do bundle "show missing" out.should =~ /could not find gem 'missing'/i end + + describe "while locked" do + before :each do + bundle :lock + end + + it "prints path if gem exists in bundle" do + bundle "show rails" + out.should == default_bundle_path('gems', 'rails-2.3.2').to_s + end + + it "complains if gem not in bundle" do + bundle "show missing" + out.should =~ /could not find gem 'missing'/i + end + end + end + +describe "bundle show with a git repo" do + before :each do + build_git "foo", "1.0" + end + + it "prints out git info" do + install_gemfile <<-G + gem "foo", :git => "#{lib_path('foo-1.0')}" + G + should_be_installed "foo 1.0" + + bundle :show + out.should include("foo (1.0 master-#{@revision}") + end + + it "prints out branch names other than master" do + update_git "foo", :branch => "omg" do |s| + s.write "lib/foo.rb", "FOO = '1.0.omg'" + end + @revision = revision_for(lib_path("foo-1.0"))[0...6] + + install_gemfile <<-G + gem "foo", :git => "#{lib_path('foo-1.0')}", :branch => "omg" + G + should_be_installed "foo 1.0.omg" + + bundle :show + out.should include("foo (1.0 omg-#{@revision}") + end + + it "doesn't print the branch when tied to a ref" do + sha = revision_for(lib_path("foo-1.0")) + install_gemfile <<-G + gem "foo", :git => "#{lib_path('foo-1.0')}", :ref => "#{sha}" + G + + bundle :show + out.should include("foo (1.0 #{sha[0...6]})") + end +end
\ No newline at end of file diff --git a/spec/runtime/environment_rb_spec.rb b/spec/runtime/environment_rb_spec.rb index 17b2336ea1..6b03032631 100644 --- a/spec/runtime/environment_rb_spec.rb +++ b/spec/runtime/environment_rb_spec.rb @@ -137,4 +137,39 @@ describe "environment.rb file" do end if RUBY_VERSION >= "1.9" end + it "get regenerated when out of date" do + system_gems "rack-1.0.0" + install_gemfile %|gem "rack"| + bundle :lock + should_be_locked + + env_file <<-E + # Generated by Bundler 0.8 + puts "noo" + E + + ruby <<-R + require "rubygems" + require "bundler" + Bundler.setup + R + out.should_not include("noo") + env_file.read.should include("Generated by Bundler #{Bundler::VERSION}") + end + + it "gets used in Bundler.setup when up to date" do + system_gems "rack-1.0.0" + install_gemfile %|gem "rack"| + bundle :lock + should_be_locked + + File.open(env_file, 'a'){|f| f.puts "puts 'using environment.rb'" } + ruby <<-R + require "rubygems" + require "bundler" + Bundler.setup + R + out.should include("using environment.rb") + end + end diff --git a/spec/runtime/load_spec.rb b/spec/runtime/load_spec.rb index 07a0de2dbf..543ebebaf3 100644 --- a/spec/runtime/load_spec.rb +++ b/spec/runtime/load_spec.rb @@ -29,7 +29,7 @@ describe "Bundler.load" do it "raises an exception if the default gemfile is not found" do lambda { Bundler.load - }.should raise_error(Bundler::GemfileNotFound, /default/) + }.should raise_error(Bundler::GemfileNotFound, /could not locate gemfile/i) end it "raises an exception if a specified gemfile is not found" do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 9a3099d169..8c66e1817c 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -14,7 +14,7 @@ $debug = false $show_err = true Spec::Rubygems.setup -FileUtils.rm_rf(Spec::Path.gem_repo1) +Spec::Path.gem_repo1.rmtree Spec::Runner.configure do |config| config.include Spec::Builders diff --git a/spec/support/builders.rb b/spec/support/builders.rb index 2a3b530400..4e81c70cca 100644 --- a/spec/support/builders.rb +++ b/spec/support/builders.rb @@ -114,24 +114,7 @@ module Spec end build_gem "very_simple_binary" do |s| - s.require_paths << 'ext' - s.extensions << "ext/extconf.rb" - s.write "ext/extconf.rb", <<-RUBY - require "mkmf" - - exit 1 unless with_config("simple") - - extension_name = "very_simple_binary_c" - dir_config extension_name - create_makefile extension_name - RUBY - s.write "ext/very_simple_binary.c", <<-C - #include "ruby.h" - - void Init_very_simple_binary_c() { - rb_define_module("VerySimpleBinaryInC"); - } - C + s.add_c_extension end build_gem "bundler", "0.8.1" do |s| @@ -334,6 +317,27 @@ module Spec @spec.executables = Array(val) end + def add_c_extension + require_paths << 'ext' + extensions << "ext/extconf.rb" + write "ext/extconf.rb", <<-RUBY + require "mkmf" + + # exit 1 unless with_config("simple") + + extension_name = "very_simple_binary_c" + dir_config extension_name + create_makefile extension_name + RUBY + write "ext/very_simple_binary.c", <<-C + #include "ruby.h" + + void Init_very_simple_binary_c() { + rb_define_module("VerySimpleBinaryInC"); + } + C + end + def _build(options) path = options[:path] || _default_path @files["#{name}.gemspec"] = @spec.to_ruby unless options[:gemspec] == false diff --git a/spec/support/helpers.rb b/spec/support/helpers.rb index 8d61bded42..5004b8e077 100644 --- a/spec/support/helpers.rb +++ b/spec/support/helpers.rb @@ -85,12 +85,22 @@ module Spec path = bundled_app("Gemfile") path = args.shift if Pathname === args.first str = args.shift || "" - FileUtils.mkdir_p(path.dirname.to_s) + path.dirname.mkpath File.open(path.to_s, 'w') do |f| f.puts str end end + def env_file(*args) + path = bundled_app(".bundle/environment.rb") + if args.empty? + path + else + str = args.shift || "" + File.open(path, 'w'){|f| f.puts str } + end + end + def install_gemfile(*args) gemfile(*args) opts = args.last.is_a?(Hash) ? args.last : {} |