diff options
-rw-r--r-- | lib/bundler/cli/lock.rb | 2 | ||||
-rw-r--r-- | lib/bundler/env.rb | 45 | ||||
-rw-r--r-- | lib/bundler/errors.rb | 20 | ||||
-rw-r--r-- | lib/bundler/fetcher/compact_index.rb | 16 | ||||
-rw-r--r-- | lib/bundler/friendly_errors.rb | 30 | ||||
-rw-r--r-- | lib/bundler/shared_helpers.rb | 6 | ||||
-rw-r--r-- | lib/bundler/templates/newgem/gitignore.tt | 5 | ||||
-rw-r--r-- | lib/bundler/templates/newgem/spec/spec_helper.rb.tt | 11 | ||||
-rw-r--r-- | man/bundle-config.ronn | 2 | ||||
-rw-r--r-- | man/bundle-install.ronn | 2 | ||||
-rw-r--r-- | spec/bundler/env_spec.rb | 6 | ||||
-rw-r--r-- | spec/bundler/fetcher/compact_index_spec.rb | 16 | ||||
-rw-r--r-- | spec/bundler/shared_helpers_spec.rb | 21 | ||||
-rw-r--r-- | spec/commands/lock_spec.rb | 6 |
14 files changed, 152 insertions, 36 deletions
diff --git a/lib/bundler/cli/lock.rb b/lib/bundler/cli/lock.rb index 2ccaba86..beeb2e46 100644 --- a/lib/bundler/cli/lock.rb +++ b/lib/bundler/cli/lock.rb @@ -33,7 +33,7 @@ module Bundler options["add-platform"].each do |platform_string| platform = Gem::Platform.new(platform_string) - if platform.to_a.compact == %w(unknown) + if platform.to_s == "unknown" Bundler.ui.warn "The platform `#{platform_string}` is unknown to RubyGems " \ "and adding it will likely lead to resolution errors" end diff --git a/lib/bundler/env.rb b/lib/bundler/env.rb index f7c6f7e8..7e9bcc28 100644 --- a/lib/bundler/env.rb +++ b/lib/bundler/env.rb @@ -12,44 +12,49 @@ module Bundler print_gemfile = options.delete(:print_gemfile) print_gemspecs = options.delete(:print_gemspecs) - out = String.new("Environment\n\n") - out << " Bundler #{Bundler::VERSION}\n" - out << " Rubygems #{Gem::VERSION}\n" - out << " Ruby #{ruby_version}" - out << " GEM_HOME #{ENV["GEM_HOME"]}\n" unless ENV["GEM_HOME"].nil? || ENV["GEM_HOME"].empty? - out << " GEM_PATH #{ENV["GEM_PATH"]}\n" unless ENV["GEM_PATH"] == ENV["GEM_HOME"] - out << " RVM #{ENV["rvm_version"]}\n" if ENV["rvm_version"] - out << " Git #{git_version}\n" - out << " Platform #{Gem::Platform.local}\n" - out << " OpenSSL #{OpenSSL::OPENSSL_VERSION}\n" if defined?(OpenSSL::OPENSSL_VERSION) + out = String.new("## Environment\n\n```\n") + out << "Bundler #{Bundler::VERSION}\n" + out << "Rubygems #{Gem::VERSION}\n" + out << "Ruby #{ruby_version}" + out << "GEM_HOME #{ENV["GEM_HOME"]}\n" unless ENV["GEM_HOME"].nil? || ENV["GEM_HOME"].empty? + out << "GEM_PATH #{ENV["GEM_PATH"]}\n" unless ENV["GEM_PATH"] == ENV["GEM_HOME"] + out << "RVM #{ENV["rvm_version"]}\n" if ENV["rvm_version"] + out << "Git #{git_version}\n" + out << "Platform #{Gem::Platform.local}\n" + out << "OpenSSL #{OpenSSL::OPENSSL_VERSION}\n" if defined?(OpenSSL::OPENSSL_VERSION) %w(rubygems-bundler open_gem).each do |name| specs = Bundler.rubygems.find_name(name) - out << " #{name} (#{specs.map(&:version).join(",")})\n" unless specs.empty? + out << "#{name} (#{specs.map(&:version).join(",")})\n" unless specs.empty? end - out << "\nBundler settings\n\n" unless Bundler.settings.all.empty? + out << "```\n" + + out << "\n## Bundler settings\n\n```\n" unless Bundler.settings.all.empty? Bundler.settings.all.each do |setting| - out << " " << setting << "\n" + out << setting << "\n" Bundler.settings.pretty_values_for(setting).each do |line| - out << " " << line << "\n" + out << " " << line << "\n" end end + out << "```\n" return out unless SharedHelpers.in_bundle? if print_gemfile - out << "\n#{Bundler.default_gemfile.relative_path_from(SharedHelpers.pwd)}\n\n" - out << " " << read_file(Bundler.default_gemfile).gsub(/\n/, "\n ") << "\n" + out << "\n## Gemfile\n" + out << "\n### #{Bundler.default_gemfile.relative_path_from(SharedHelpers.pwd)}\n\n" + out << "```ruby\n" << read_file(Bundler.default_gemfile).chomp << "\n```\n" - out << "\n#{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}\n\n" - out << " " << read_file(Bundler.default_lockfile).gsub(/\n/, "\n ") << "\n" + out << "\n### #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}\n\n" + out << "```\n" << read_file(Bundler.default_lockfile).chomp << "\n```\n" end if print_gemspecs dsl = Dsl.new.tap {|d| d.eval_gemfile(Bundler.default_gemfile) } + out << "\n## Gemspecs\n" unless dsl.gemspecs.empty? dsl.gemspecs.each do |gs| - out << "\n#{File.basename(gs.loaded_from)}" - out << "\n\n " << read_file(gs.loaded_from).gsub(/\n/, "\n ") << "\n" + out << "\n### #{File.basename(gs.loaded_from)}" + out << "\n\n```ruby\n" << read_file(gs.loaded_from).chomp << "\n```\n" end end diff --git a/lib/bundler/errors.rb b/lib/bundler/errors.rb index dd5782fb..be72a9ee 100644 --- a/lib/bundler/errors.rb +++ b/lib/bundler/errors.rb @@ -132,4 +132,24 @@ module Bundler status_code(28) end + + class NoSpaceOnDeviceError < PermissionError + def message + "There was an error while trying to #{action} `#{@path}`. " \ + "There was insufficent space remaining on the device." + end + + status_code(31) + end + + class GenericSystemCallError < BundlerError + attr_reader :underlying_error + + def initialize(underlying_error, message) + @underlying_error = underlying_error + super("#{message}\nThe underlying system error is #{@underlying_error.class}: #{@underlying_error}") + end + + status_code(32) + end end diff --git a/lib/bundler/fetcher/compact_index.rb b/lib/bundler/fetcher/compact_index.rb index 5d703a3a..dcc9d57c 100644 --- a/lib/bundler/fetcher/compact_index.rb +++ b/lib/bundler/fetcher/compact_index.rb @@ -3,10 +3,10 @@ require "bundler/fetcher/base" require "bundler/worker" module Bundler + autoload :CompactIndexClient, "bundler/compact_index_client" + class Fetcher class CompactIndex < Base - require "bundler/compact_index_client" - def self.compact_index_request(method_name) method = instance_method(method_name) undef_method(method_name) @@ -61,6 +61,7 @@ module Bundler compact_index_request :fetch_spec def available? + return nil unless md5_available? user_home = Bundler.user_home return nil unless user_home.directory? && user_home.writable? # Read info file checksums out of /versions, so we can know if gems are up to date @@ -119,6 +120,17 @@ module Bundler Net::HTTPNotModified.new(nil, nil, nil) end end + + def md5_available? + begin + require "openssl" + return false if defined?(OpenSSL::OPENSSL_FIPS) && OpenSSL::OPENSSL_FIPS + rescue LoadError + nil + end + + true + end end end end diff --git a/lib/bundler/friendly_errors.rb b/lib/bundler/friendly_errors.rb index c2853294..3a464734 100644 --- a/lib/bundler/friendly_errors.rb +++ b/lib/bundler/friendly_errors.rb @@ -58,25 +58,41 @@ module Bundler def request_issue_report_for(e) Bundler.ui.info <<-EOS.gsub(/^ {8}/, "") --- ERROR REPORT TEMPLATE ------------------------------------------------------- - - What did you do? + # Error Report + + ## Questions + + Please fill out answers to these questions, it'll help us figure out + why things are going wrong. + + - **What did you do?** I ran the command `#{$PROGRAM_NAME} #{ARGV.join(" ")}` - - What did you expect to happen? + - **What did you expect to happen?** I expected Bundler to... - - What happened instead? + - **What happened instead?** Instead, what happened was... + - **Have you tried any solutions posted on similar issues in our issue tracker, stack overflow, or google?** + + I tried... + + - **Have you read our issues document, https://github.com/bundler/bundler/blob/master/ISSUES.md?** + + ... - Error details + ## Backtrace - #{e.class}: #{e.message} - #{e.backtrace && e.backtrace.join("\n ")} + ``` + #{e.class}: #{e.message} + #{e.backtrace && e.backtrace.join("\n ").chomp} + ``` - #{Bundler::Env.new.report(:print_gemfile => false, :print_gemspecs => false).gsub(/\n/, "\n ").strip} + #{Bundler::Env.new.report(:print_gemfile => false, :print_gemspecs => false)} --- TEMPLATE END ---------------------------------------------------------------- EOS diff --git a/lib/bundler/shared_helpers.rb b/lib/bundler/shared_helpers.rb index 0ddcea1c..62ade29e 100644 --- a/lib/bundler/shared_helpers.rb +++ b/lib/bundler/shared_helpers.rb @@ -111,8 +111,14 @@ module Bundler raise TemporaryResourceError.new(path, action) rescue Errno::EPROTO raise VirtualProtocolError.new + rescue Errno::ENOSPC + raise NoSpaceOnDeviceError.new(path, action) rescue *[const_get_safely(:ENOTSUP, Errno)].compact raise OperationNotSupportedError.new(path, action) + rescue Errno::EEXIST, Errno::ENOENT + raise + rescue SystemCallError => e + raise GenericSystemCallError.new(e, "There was an error accessing `#{path}`.") end def const_get_safely(constant_name, namespace) diff --git a/lib/bundler/templates/newgem/gitignore.tt b/lib/bundler/templates/newgem/gitignore.tt index ebff7ac5..573d76b4 100644 --- a/lib/bundler/templates/newgem/gitignore.tt +++ b/lib/bundler/templates/newgem/gitignore.tt @@ -14,3 +14,8 @@ *.a mkmf.log <%- end -%> +<%- if config[:test] == "rspec" -%> + +# rspec failure tracking +.rspec_status +<%- end -%> diff --git a/lib/bundler/templates/newgem/spec/spec_helper.rb.tt b/lib/bundler/templates/newgem/spec/spec_helper.rb.tt index 4c69d354..a5e7f92f 100644 --- a/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +++ b/lib/bundler/templates/newgem/spec/spec_helper.rb.tt @@ -1,2 +1,11 @@ -$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__) +require "bundler/setup" require "<%= config[:namespaced_path] %>" + +RSpec.configure do |config| + # Enable flags like --only-failures and --next-failure + config.example_status_persistence_file_path = ".rspec_status" + + config.expect_with :rspec do |c| + c.syntax = :expect + end +end diff --git a/man/bundle-config.ronn b/man/bundle-config.ronn index 5f10aaa6..cb9fc6cc 100644 --- a/man/bundle-config.ronn +++ b/man/bundle-config.ronn @@ -65,7 +65,7 @@ The options that can be configured are: The location to install the specified gems to. This defaults to Rubygems' setting. Bundler shares this location with Rubygems, `gem install ...` will have gem installed there, too. Therefore, gems installed without a - `--path ...` setting will show up by calling `gem list`. Accodingly, gems + `--path ...` setting will show up by calling `gem list`. Accordingly, gems installed to other locations will not get listed. * `without`: diff --git a/man/bundle-install.ronn b/man/bundle-install.ronn index 92d1d8d4..3a030905 100644 --- a/man/bundle-install.ronn +++ b/man/bundle-install.ronn @@ -110,7 +110,7 @@ time `bundle install` is run, use `bundle config` (see bundle-config(1)). The location to install the specified gems to. This defaults to Rubygems' setting. Bundler shares this location with Rubygems, `gem install ...` will have gem installed there, too. Therefore, gems installed without a - `--path ...` setting will show up by calling `gem list`. Accodingly, gems + `--path ...` setting will show up by calling `gem list`. Accordingly, gems installed to other locations will not get listed. * `--quiet`: diff --git a/spec/bundler/env_spec.rb b/spec/bundler/env_spec.rb index 245073d9..f2cf26c4 100644 --- a/spec/bundler/env_spec.rb +++ b/spec/bundler/env_spec.rb @@ -53,13 +53,13 @@ describe Bundler::Env do let(:output) { env.report(:print_gemfile => true) } it "prints the environment" do - expect(output).to start_with("Environment") + expect(output).to start_with("## Environment") end end context "when Gemfile contains a gemspec and print_gemspecs is true" do let(:gemspec) do - <<-GEMSPEC.gsub(/^\s+/, "") + strip_whitespace(<<-GEMSPEC) Gem::Specification.new do |gem| gem.name = "foo" gem.author = "Fumofu" @@ -76,7 +76,7 @@ describe Bundler::Env do end it "prints the gemspec" do - output = env.report(:print_gemspecs => true).gsub(/^\s+/, "") + output = env.report(:print_gemspecs => true) expect(output).to include("foo.gemspec") expect(output).to include(gemspec) diff --git a/spec/bundler/fetcher/compact_index_spec.rb b/spec/bundler/fetcher/compact_index_spec.rb index e3f36666..691e19f6 100644 --- a/spec/bundler/fetcher/compact_index_spec.rb +++ b/spec/bundler/fetcher/compact_index_spec.rb @@ -25,6 +25,22 @@ describe Bundler::Fetcher::CompactIndex do compact_index.specs_for_names(["lskdjf"]) end + describe "#available?" do + context "when OpenSSL is in FIPS mode", :ruby => ">= 2.0.0" do + before { stub_const("OpenSSL::OPENSSL_FIPS", true) } + + it "returns false" do + expect(compact_index).to_not be_available + end + + it "never requires digest/md5" do + expect(Kernel).to receive(:require).with("digest/md5").never + + compact_index.available? + end + end + end + context "logging" do before { allow(compact_index).to receive(:log_specs).and_call_original } diff --git a/spec/bundler/shared_helpers_spec.rb b/spec/bundler/shared_helpers_spec.rb index 8826dcd4..fc3371ac 100644 --- a/spec/bundler/shared_helpers_spec.rb +++ b/spec/bundler/shared_helpers_spec.rb @@ -388,6 +388,27 @@ describe Bundler::SharedHelpers do ) end end + + context "system throws Errno::ENOSPC" do + let(:file_op_block) { proc {|_path| raise Errno::ENOSPC } } + + it "raises a NoSpaceOnDeviceError" do + expect { subject.filesystem_access("/path", &file_op_block) }.to raise_error( + Bundler::NoSpaceOnDeviceError + ) + end + end + + context "system throws an unhandled SystemCallError" do + let(:error) { SystemCallError.new("Shields down", 1337) } + let(:file_op_block) { proc {|_path| raise error } } + + it "raises a GenericSystemCallError" do + expect { subject.filesystem_access("/path", &file_op_block) }.to raise_error( + Bundler::GenericSystemCallError, /error accessing.+underlying.+Shields down/m + ) + end + end end describe "#const_get_safely" do diff --git a/spec/commands/lock_spec.rb b/spec/commands/lock_spec.rb index 1c00aa3c..b51003f2 100644 --- a/spec/commands/lock_spec.rb +++ b/spec/commands/lock_spec.rb @@ -161,6 +161,12 @@ describe "bundle lock" do expect(lockfile.platforms).to eq([java, local, mingw]) end + it "supports adding the `ruby` platform" do + bundle! "lock --add-platform ruby" + lockfile = Bundler::LockfileParser.new(read_lockfile) + expect(lockfile.platforms).to eq([local, "ruby"].uniq) + end + it "warns when adding an unknown platform" do bundle "lock --add-platform foobarbaz" expect(out).to include("The platform `foobarbaz` is unknown to RubyGems and adding it will likely lead to resolution errors") |