diff options
Diffstat (limited to 'lib/bundler')
-rw-r--r-- | lib/bundler/capistrano.rb | 2 | ||||
-rw-r--r-- | lib/bundler/cli.rb | 27 | ||||
-rw-r--r-- | lib/bundler/current_ruby.rb | 21 | ||||
-rw-r--r-- | lib/bundler/definition.rb | 2 | ||||
-rw-r--r-- | lib/bundler/dependency.rb | 6 | ||||
-rw-r--r-- | lib/bundler/endpoint_specification.rb | 2 | ||||
-rw-r--r-- | lib/bundler/fetcher.rb | 5 | ||||
-rw-r--r-- | lib/bundler/index.rb | 7 | ||||
-rw-r--r-- | lib/bundler/installer.rb | 39 | ||||
-rw-r--r-- | lib/bundler/lazy_specification.rb | 1 | ||||
-rw-r--r-- | lib/bundler/parallel_workers/thread_worker.rb | 7 | ||||
-rw-r--r-- | lib/bundler/parallel_workers/unix_worker.rb | 7 | ||||
-rw-r--r-- | lib/bundler/parallel_workers/worker.rb | 2 | ||||
-rw-r--r-- | lib/bundler/ruby_dsl.rb | 2 | ||||
-rw-r--r-- | lib/bundler/ruby_version.rb | 15 | ||||
-rw-r--r-- | lib/bundler/source/git.rb | 6 | ||||
-rw-r--r-- | lib/bundler/source/git/git_proxy.rb | 2 | ||||
-rw-r--r-- | lib/bundler/source/path.rb | 3 | ||||
-rw-r--r-- | lib/bundler/source/rubygems.rb | 8 | ||||
-rw-r--r-- | lib/bundler/templates/newgem/newgem.gemspec.tt | 4 | ||||
-rw-r--r-- | lib/bundler/version.rb | 2 |
21 files changed, 112 insertions, 58 deletions
diff --git a/lib/bundler/capistrano.rb b/lib/bundler/capistrano.rb index 40d7da15df..336f04cacf 100644 --- a/lib/bundler/capistrano.rb +++ b/lib/bundler/capistrano.rb @@ -4,7 +4,7 @@ # Bundler will be activated after each new deployment. require 'bundler/deployment' -if Gem::Version.new(Capistrano::Version).release >= Gem::Version.new("3.0") +if defined?(Capistrano::Version) && Gem::Version.new(Capistrano::Version).release >= Gem::Version.new("3.0") raise "For Capistrano 3.x integration, please use http://github.com/capistrano/bundler" end diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb index af0a7fb618..07d437ac4f 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -234,16 +234,16 @@ module Bundler opts["no-cache"] ||= opts[:local] - # Can't use Bundler.settings for this because settings needs gemfile.dirname Bundler.settings[:path] = nil if opts[:system] Bundler.settings[:path] = "vendor/bundle" if opts[:deployment] - Bundler.settings[:path] = opts[:path] if opts[:path] - Bundler.settings[:path] ||= "bundle" if opts[:standalone] + Bundler.settings[:path] = opts["path"] if opts["path"] + Bundler.settings[:path] ||= "bundle" if opts["standalone"] Bundler.settings[:bin] = opts["binstubs"] if opts["binstubs"] Bundler.settings[:bin] = nil if opts["binstubs"] && opts["binstubs"].empty? - Bundler.settings[:shebang] = opts["shebang"] if opts[:shebang] + Bundler.settings[:shebang] = opts["shebang"] if opts["shebang"] + Bundler.settings[:jobs] = opts["jobs"] if opts["jobs"] Bundler.settings[:no_prune] = true if opts["no-prune"] - Bundler.settings[:clean] = opts[:clean] if opts[:clean] + Bundler.settings[:clean] = opts["clean"] if opts["clean"] Bundler.settings.without = opts[:without] Bundler.ui.level = "warn" if opts[:quiet] Bundler::Fetcher.disable_endpoint = opts["full-index"] @@ -311,8 +311,7 @@ module Bundler Bundler.definition(true) else # cycle through the requested gems, just to make sure they exist - lock = Bundler.read_file(Bundler.default_lockfile) - names = LockfileParser.new(lock).specs.map{ |s| s.name } + names = Bundler.locked_gems.specs.map{ |s| s.name } gems.each do |g| next if names.include?(g) raise GemNotFound, not_found_message(g, names) @@ -419,8 +418,12 @@ module Bundler "Do not attempt to fetch gems remotely and use the gem cache instead" def outdated(*gems) sources = Array(options[:source]) - Bundler.definition.validate_ruby! + gems.each do |gem_name| + select_spec(gem_name) + end + + Bundler.definition.validate_ruby! current_specs = Bundler.ui.silence { Bundler.load.specs } current_dependencies = {} Bundler.ui.silence { Bundler.load.dependencies.each { |dep| current_dependencies[dep.name] = dep } } @@ -514,6 +517,7 @@ module Bundler map %w(pack) => :package desc "exec", "Run the command in context of the bundle" + method_option :keep_file_descriptors, :type => :boolean, :default => false long_desc <<-D Exec runs a command, providing it access to the gems in the bundle. While using bundle exec you can require and call the bundled gems as if they were installed @@ -524,6 +528,12 @@ module Bundler Bundler.load.setup_environment begin + if RUBY_VERSION >= "2.0" + args << { :close_others => !options.keep_file_descriptors? } + elsif options.keep_file_descriptors? + Bundler.ui.warn "Ruby version #{RUBY_VERSION} defaults to keeping non-standard file descriptors on Kernel#exec." + end + # Run Kernel.exec(*args) rescue Errno::EACCES @@ -880,7 +890,6 @@ module Bundler message end - def without_groups_message groups = Bundler.settings.without group_list = [groups[0...-1].join(", "), groups[-1..-1]]. diff --git a/lib/bundler/current_ruby.rb b/lib/bundler/current_ruby.rb index 7b187eebb5..8d012a03d7 100644 --- a/lib/bundler/current_ruby.rb +++ b/lib/bundler/current_ruby.rb @@ -19,6 +19,10 @@ module Bundler RUBY_VERSION =~ /^2\.0/ end + def on_21? + RUBY_VERSION =~ /^2\.1/ + end + def ruby? !mswin? && (!defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby" || RUBY_ENGINE == "rbx" || RUBY_ENGINE == "maglev") end @@ -35,6 +39,10 @@ module Bundler ruby? && on_20? end + def ruby_21? + ruby? && on_21? + end + def mri? !mswin? && (!defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby") end @@ -47,11 +55,14 @@ module Bundler mri? && on_19? end - def mri_20? mri? && on_20? end + def mri_21? + mri? && on_21? + end + def rbx? ruby? && defined?(RUBY_ENGINE) && RUBY_ENGINE == "rbx" end @@ -92,6 +103,10 @@ module Bundler mingw? && on_20? end + def mingw_21? + mingw? && on_21? + end + def x64_mingw? Bundler::WINDOWS && Gem::Platform.local.os == "mingw32" && Gem::Platform.local.cpu == 'x64' end @@ -100,5 +115,9 @@ module Bundler x64_mingw? && on_20? end + def x64_mingw_21? + x64_mingw? && on_21? + end + end end diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index be0246fbfe..4e538e6199 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -380,6 +380,8 @@ module Bundler "Your Ruby version is #{actual}, but your Gemfile specified #{expected}" when :engine_version "Your #{system_ruby_version.engine} version is #{actual}, but your Gemfile specified #{ruby_version.engine} #{expected}" + when :patchlevel + "Your Ruby patchlevel is #{actual}, but your Gemfile specified #{expected}" end raise RubyVersionMismatch, msg diff --git a/lib/bundler/dependency.rb b/lib/bundler/dependency.rb index 9e17fe0eb8..1b09ed74c5 100644 --- a/lib/bundler/dependency.rb +++ b/lib/bundler/dependency.rb @@ -13,10 +13,12 @@ module Bundler :ruby_18 => Gem::Platform::RUBY, :ruby_19 => Gem::Platform::RUBY, :ruby_20 => Gem::Platform::RUBY, + :ruby_21 => Gem::Platform::RUBY, :mri => Gem::Platform::RUBY, :mri_18 => Gem::Platform::RUBY, :mri_19 => Gem::Platform::RUBY, :mri_20 => Gem::Platform::RUBY, + :mri_21 => Gem::Platform::RUBY, :rbx => Gem::Platform::RUBY, :jruby => Gem::Platform::JAVA, :jruby_18 => Gem::Platform::JAVA, @@ -26,8 +28,10 @@ module Bundler :mingw_18 => Gem::Platform::MINGW, :mingw_19 => Gem::Platform::MINGW, :mingw_20 => Gem::Platform::MINGW, + :mingw_21 => Gem::Platform::MINGW, :x64_mingw => Gem::Platform::X64_MINGW, - :x64_mingw_20 => Gem::Platform::X64_MINGW + :x64_mingw_20 => Gem::Platform::X64_MINGW, + :x64_mingw_21 => Gem::Platform::X64_MINGW }.freeze def initialize(name, version, options = {}, &blk) diff --git a/lib/bundler/endpoint_specification.rb b/lib/bundler/endpoint_specification.rb index c88d341ab5..4d599c5344 100644 --- a/lib/bundler/endpoint_specification.rb +++ b/lib/bundler/endpoint_specification.rb @@ -1,5 +1,3 @@ -require 'uri' - module Bundler # used for Creating Specifications from the Gemcutter Endpoint class EndpointSpecification < Gem::Specification diff --git a/lib/bundler/fetcher.rb b/lib/bundler/fetcher.rb index 78588c7adc..8b05046003 100644 --- a/lib/bundler/fetcher.rb +++ b/lib/bundler/fetcher.rb @@ -75,6 +75,11 @@ module Bundler @connection.verify_mode = (Bundler.settings[:ssl_verify_mode] || OpenSSL::SSL::VERIFY_PEER) @connection.cert_store = bundler_cert_store + if Bundler.settings[:ssl_client_cert] + pem = File.read(Bundler.settings[:ssl_client_cert]) + @connection.cert = OpenSSL::X509::Certificate.new(pem) + @connection.key = OpenSSL::PKey::RSA.new(pem) + end else raise SSLError if @remote_uri.scheme == "https" @connection = Net::HTTP.new(@remote_uri.host, @remote_uri.port) diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb index 49e82977e8..bb35179ce1 100644 --- a/lib/bundler/index.rb +++ b/lib/bundler/index.rb @@ -47,8 +47,11 @@ module Bundler @sources.each do |source| source.search(query, base).each do |spec| - results << spec unless seen.include?([spec.name, spec.version, spec.platform]) - seen << [spec.name, spec.version, spec.platform] + lookup = [spec.name, spec.version, spec.platform] + unless seen.include?(lookup) + results << spec + seen << lookup + end end end diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb index 393cbe7c79..80427ff937 100644 --- a/lib/bundler/installer.rb +++ b/lib/bundler/installer.rb @@ -84,16 +84,15 @@ module Bundler @definition.resolve_remotely! end - # Must install gems in the order that the resolver provides - # as dependencies might actually affect the installation of - # the gem. Installer.post_install_messages = {} - size = options[:jobs] || 1 - size = [size, 1].max - - if size > 1 && can_install_parallely? - install_in_parallel size, options[:standalone] + # the order that the resolver provides is significant, since + # dependencies might actually affect the installation of a gem. + # that said, it's a rare situation (other than rake), and parallel + # installation is just SO MUCH FASTER. so we let people opt in. + jobs = [Bundler.settings[:jobs].to_i, 1].max + if jobs > 1 && can_install_parallely? + install_in_parallel jobs, options[:standalone] else install_sequentially options[:standalone] end @@ -102,17 +101,21 @@ module Bundler generate_standalone(options[:standalone]) if options[:standalone] end - def install_gem_from_spec(spec, standalone = false) + def install_gem_from_spec(spec, standalone = false, worker = 0) # Download the gem to get the spec, because some specs that are returned # by rubygems.org are broken and wrong. Bundler::Fetcher.fetch(spec) if spec.source.is_a?(Bundler::Source::Rubygems) # Fetch the build settings, if there are any - settings = Bundler.settings["build.#{spec.name}"] - message = nil + settings = Bundler.settings["build.#{spec.name}"] + install_message = nil + post_install_message = nil + debug_message = nil Bundler.rubygems.with_build_args [settings] do - message = spec.source.install(spec) - Bundler.ui.debug " #{spec.name} (#{spec.version}) from #{spec.loaded_from}" + install_message, post_install_message, debug_message = spec.source.install(spec) + Bundler.ui.info install_message + Bundler.ui.debug debug_message if debug_message + Bundler.ui.debug "#{worker}: #{spec.name} (#{spec.version}) from #{spec.loaded_from}" end if Bundler.settings[:bin] && standalone @@ -122,9 +125,9 @@ module Bundler end FileUtils.rm_rf(Bundler.tmp) - message + post_install_message rescue Exception => e - # install hook failed + # if install hook failed or gem signature is bad, just die raise e if e.is_a?(Bundler::InstallHookError) || e.is_a?(Bundler::SecurityError) # other failure, likely a native extension build failure @@ -260,7 +263,7 @@ module Bundler def install_sequentially(standalone) specs.each do |spec| - message = install_gem_from_spec spec, standalone + message = install_gem_from_spec spec, standalone, 0 if message Installer.post_install_messages[spec.name] = message end @@ -276,9 +279,9 @@ module Bundler remains[spec.name] = true end - worker_pool = ParallelWorkers.worker_pool size, lambda { |name| + worker_pool = ParallelWorkers.worker_pool size, lambda { |name, worker| spec = name2spec[name] - message = install_gem_from_spec spec, standalone + message = install_gem_from_spec spec, standalone, worker { :name => spec.name, :post_install => message } } specs.each do |spec| diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb index af9baff80b..966d107c38 100644 --- a/lib/bundler/lazy_specification.rb +++ b/lib/bundler/lazy_specification.rb @@ -1,5 +1,6 @@ require "uri" require "rubygems/spec_fetcher" +require "bundler/match_platform" module Bundler class LazySpecification diff --git a/lib/bundler/parallel_workers/thread_worker.rb b/lib/bundler/parallel_workers/thread_worker.rb index eed69dbd3e..ef2c9ecd18 100644 --- a/lib/bundler/parallel_workers/thread_worker.rb +++ b/lib/bundler/parallel_workers/thread_worker.rb @@ -12,11 +12,14 @@ module Bundler def prepare_workers(size, func) @threads = size.times.map do |i| Thread.start do - Thread.current.abort_on_exception = true loop do obj = @request_queue.deq break if obj.equal? POISON - @response_queue.enq func.call(obj) + begin + @response_queue.enq func.call(obj, i) + rescue Exception => e + @response_queue.enq(WrappedException.new(e)) + end end end end diff --git a/lib/bundler/parallel_workers/unix_worker.rb b/lib/bundler/parallel_workers/unix_worker.rb index 1d5fee6697..ce7b7fe9ed 100644 --- a/lib/bundler/parallel_workers/unix_worker.rb +++ b/lib/bundler/parallel_workers/unix_worker.rb @@ -9,7 +9,7 @@ module Bundler def work(obj) Marshal.dump obj, io_w Marshal.load io_r - rescue IOError + rescue IOError, Errno::EPIPE nil end end @@ -22,7 +22,7 @@ module Bundler # @param size [Integer] Size of worker pool # @param func [Proc] Job that should be executed in the worker def prepare_workers(size, func) - @workers = size.times.map do + @workers = size.times.map do |num| child_read, parent_write = IO.pipe parent_read, child_write = IO.pipe @@ -33,7 +33,7 @@ module Bundler while !child_read.eof? obj = Marshal.load child_read - Marshal.dump func.call(obj), child_write + Marshal.dump func.call(obj, num), child_write end rescue Exception => e begin @@ -62,7 +62,6 @@ module Bundler @threads = size.times.map do |i| Thread.start do worker = @workers[i] - Thread.current.abort_on_exception = true loop do obj = @request_queue.deq break if obj.equal? POISON diff --git a/lib/bundler/parallel_workers/worker.rb b/lib/bundler/parallel_workers/worker.rb index 975b6a3342..6e22eb4ce7 100644 --- a/lib/bundler/parallel_workers/worker.rb +++ b/lib/bundler/parallel_workers/worker.rb @@ -39,8 +39,8 @@ module Bundler # Stop the forked workers and started threads def stop - stop_workers stop_threads + stop_workers end private diff --git a/lib/bundler/ruby_dsl.rb b/lib/bundler/ruby_dsl.rb index 87bb801dc7..b29fc019a7 100644 --- a/lib/bundler/ruby_dsl.rb +++ b/lib/bundler/ruby_dsl.rb @@ -5,7 +5,7 @@ module Bundler raise GemfileError, "Please define :engine" if options[:engine_version] && options[:engine].nil? raise GemfileError, "ruby_version must match the :engine_version for MRI" if options[:engine] == "ruby" && options[:engine_version] && ruby_version != options[:engine_version] - @ruby_version = RubyVersion.new(ruby_version, options[:engine], options[:engine_version]) + @ruby_version = RubyVersion.new(ruby_version, options[:patchlevel], options[:engine], options[:engine_version]) end end end diff --git a/lib/bundler/ruby_version.rb b/lib/bundler/ruby_version.rb index 9fff1431ad..bf44278b46 100644 --- a/lib/bundler/ruby_version.rb +++ b/lib/bundler/ruby_version.rb @@ -1,8 +1,8 @@ module Bundler class RubyVersion - attr_reader :version, :engine, :engine_version + attr_reader :version, :patchlevel, :engine, :engine_version - def initialize(version, engine, engine_version) + def initialize(version, patchlevel, engine, engine_version) # The parameters to this method must satisfy the # following constraints, which are verified in # the DSL: @@ -20,10 +20,12 @@ module Bundler # keep track of the engine specified by the user @input_engine = engine @engine_version = engine_version || version + @patchlevel = patchlevel end def to_s output = "ruby #{version}" + output << "p#{patchlevel}" if patchlevel output << " (#{engine} #{engine_version})" unless engine == "ruby" output @@ -32,7 +34,8 @@ module Bundler def ==(other) version == other.version && engine == other.engine && - engine_version == other.engine_version + engine_version == other.engine_version && + patchlevel == other.patchlevel end # Returns a tuple of thsee things: @@ -48,6 +51,8 @@ module Bundler [ :version, version, other.version ] elsif engine_version != other.engine_version && @input_engine [ :engine_version, engine_version, other.engine_version ] + elsif patchlevel != other.patchlevel && @patchlevel + [ :patchlevel, patchlevel, other.patchlevel ] else nil end @@ -96,5 +101,9 @@ module Bundler nil end end + + def patchlevel + RUBY_PATCHLEVEL + end end end diff --git a/lib/bundler/source/git.rb b/lib/bundler/source/git.rb index 9f308881e7..0480428c3f 100644 --- a/lib/bundler/source/git.rb +++ b/lib/bundler/source/git.rb @@ -151,15 +151,15 @@ module Bundler end def install(spec) - Bundler.ui.info "Using #{spec.name} (#{spec.version}) from #{to_s}" + debug = nil if requires_checkout? && !@copied - Bundler.ui.debug " * Checking out revision: #{ref}" + debug = " * Checking out revision: #{ref}" git_proxy.copy_to(install_path, submodules) serialize_gemspecs_in(install_path) @copied = true end generate_bin(spec) - nil + ["Using #{spec.name} (#{spec.version}) from #{to_s}", nil, debug] end def cache(spec) diff --git a/lib/bundler/source/git/git_proxy.rb b/lib/bundler/source/git/git_proxy.rb index 19e297fcc2..fa398215bc 100644 --- a/lib/bundler/source/git/git_proxy.rb +++ b/lib/bundler/source/git/git_proxy.rb @@ -85,6 +85,8 @@ module Bundler def git(command, check_errors=true) if allow? + raise GitError, "You need to install git to be able to use gems from git repositories. For help installing git, please refer to GitHub's tutorial at https://help.github.com/articles/set-up-git" if !Bundler.git_present? + out = SharedHelpers.with_clean_git_env { %x{git #{command}} } if check_errors && $?.exitstatus != 0 diff --git a/lib/bundler/source/path.rb b/lib/bundler/source/path.rb index e0a818b5ab..b95192fb9a 100644 --- a/lib/bundler/source/path.rb +++ b/lib/bundler/source/path.rb @@ -70,9 +70,8 @@ module Bundler end def install(spec) - Bundler.ui.info "Using #{spec.name} (#{spec.version}) from #{to_s}" generate_bin(spec, :disable_extensions) - nil + ["Using #{spec.name} (#{spec.version}) from #{to_s}", nil] end def cache(spec) diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb index 76db202536..b7fdbd2c7b 100644 --- a/lib/bundler/source/rubygems.rb +++ b/lib/bundler/source/rubygems.rb @@ -69,11 +69,10 @@ module Bundler def install(spec) if installed_specs[spec].any? - Bundler.ui.info "Using #{spec.name} (#{spec.version})" - return + return ["Using #{spec.name} (#{spec.version})", nil] end - Bundler.ui.info "Installing #{spec.name} (#{spec.version})" + install_message = "Installing #{spec.name} (#{spec.version})" path = cached_gem(spec) if Bundler.requires_sudo? install_path = Bundler.tmp @@ -105,10 +104,9 @@ module Bundler Bundler.sudo "cp -R #{Bundler.tmp}/bin/#{exe} #{Bundler.system_bindir}" end end - Bundler.ui.info "Installed #{spec.name} (#{spec.version})" installed_spec.loaded_from = "#{Bundler.rubygems.gem_dir}/specifications/#{spec.full_name}.gemspec" spec.loaded_from = "#{Bundler.rubygems.gem_dir}/specifications/#{spec.full_name}.gemspec" - spec.post_install_message + [install_message, spec.post_install_message] end def cache(spec) diff --git a/lib/bundler/templates/newgem/newgem.gemspec.tt b/lib/bundler/templates/newgem/newgem.gemspec.tt index 28997f0277..5a3c312aca 100644 --- a/lib/bundler/templates/newgem/newgem.gemspec.tt +++ b/lib/bundler/templates/newgem/newgem.gemspec.tt @@ -8,8 +8,8 @@ Gem::Specification.new do |spec| spec.version = <%=config[:constant_name]%>::VERSION spec.authors = [<%=config[:author].inspect%>] spec.email = [<%=config[:email].inspect%>] - spec.description = %q{TODO: Write a gem description} - spec.summary = %q{TODO: Write a gem summary} + spec.summary = %q{TODO: Write a short summary. Required.} + spec.description = %q{TODO: Write a longer description. Optional.} spec.homepage = "" spec.license = "MIT" diff --git a/lib/bundler/version.rb b/lib/bundler/version.rb index ddbb667c4c..0ec16e6bdd 100644 --- a/lib/bundler/version.rb +++ b/lib/bundler/version.rb @@ -2,5 +2,5 @@ module Bundler # We're doing this because we might write tests that deal # with other versions of bundler and we are unsure how to # handle this better. - VERSION = "1.4.0.pre.1" unless defined?(::Bundler::VERSION) + VERSION = "1.4.0.pre.2" unless defined?(::Bundler::VERSION) end |