diff options
author | Tim Moore <tmoore@incrementalism.net> | 2015-02-18 08:01:35 +1100 |
---|---|---|
committer | Tim Moore <tmoore@incrementalism.net> | 2015-02-18 08:01:35 +1100 |
commit | 28791072377019b89e561ccf8b034c4380e99a14 (patch) | |
tree | 6e91618b88ffa0df0834c1dba6cd80e3d8240245 | |
parent | 13d5e08de1e1b957bbf4c5fecd8d3e532a09c121 (diff) | |
parent | da20a792c60dd2e8d82b1179b48b14533422ebb8 (diff) | |
download | bundler-28791072377019b89e561ccf8b034c4380e99a14.tar.gz |
Merge tag 'v1.8.2'
Version 1.8.2
-rw-r--r-- | CHANGELOG.md | 25 | ||||
-rw-r--r-- | lib/bundler/fetcher.rb | 2 | ||||
-rw-r--r-- | lib/bundler/installer.rb | 7 | ||||
-rw-r--r-- | lib/bundler/lockfile_parser.rb | 4 | ||||
-rw-r--r-- | lib/bundler/rubygems_integration.rb | 35 | ||||
-rw-r--r-- | lib/bundler/settings.rb | 9 | ||||
-rw-r--r-- | lib/bundler/shared_helpers.rb | 4 | ||||
-rw-r--r-- | lib/bundler/source/path.rb | 2 | ||||
-rw-r--r-- | lib/bundler/source/rubygems.rb | 9 | ||||
-rw-r--r-- | lib/bundler/templates/newgem/README.md.tt | 2 | ||||
-rw-r--r-- | lib/bundler/templates/newgem/newgem.gemspec.tt | 1 | ||||
-rw-r--r-- | spec/bundler/gem_helper_spec.rb | 4 | ||||
-rw-r--r-- | spec/bundler/settings_spec.rb | 34 | ||||
-rw-r--r-- | spec/commands/config_spec.rb | 25 | ||||
-rw-r--r-- | spec/commands/newgem_spec.rb | 32 | ||||
-rw-r--r-- | spec/install/gems/groups_spec.rb | 16 | ||||
-rw-r--r-- | spec/quality_spec.rb | 5 | ||||
-rw-r--r-- | spec/realworld/parallel_spec.rb | 14 | ||||
-rw-r--r-- | spec/support/builders.rb | 4 | ||||
-rw-r--r-- | spec/support/helpers.rb | 7 |
20 files changed, 196 insertions, 45 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 4553833714..88bd610d7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,31 @@ +## 1.8.2 (2015-02-14) + +Bugfixes: + + - allow config settings for gems with 'http' in the name again (#3398, @tmoore) + +## 1.8.1 (2015-02-13) + +Bugfixes: + + - synchronize building git gem native extensions (#3385, @antifuchs & @indirect) + - set gemspec bindir correctly (#3392, @tmoore) + - request lockfile deletion when it is malformed (#3396, @indirect) + - explain problem when mirror config is missing (#3386, @indirect) + - explain problem when caching causes permission error (#3390, @indirect) + - normalize URLs in config keys (#3391, @indirect) + ## 1.8.0 (2015-02-10) Bugfixes: - - Gemfile `github` blocks now work (#3379, @indirect) + - gemfile `github` blocks now work (#3379, @indirect) Bugfixes from v1.7.13: - - Look up installed gems in remote sources (#3300, #3368, #3377, #3380, #3381, @indirect) - - Look up gems across all sources to satisfy dependencies (#3365, @keiths-osc) - - Request dependencies for no more than 100 gems at a time (#3367, @segiddins) + - look up installed gems in remote sources (#3300, #3368, #3377, #3380, #3381, @indirect) + - look up gems across all sources to satisfy dependencies (#3365, @keiths-osc) + - request dependencies for no more than 100 gems at a time (#3367, @segiddins) ## 1.8.0.rc (2015-01-26) diff --git a/lib/bundler/fetcher.rb b/lib/bundler/fetcher.rb index 64c265fb40..46ac8e44e8 100644 --- a/lib/bundler/fetcher.rb +++ b/lib/bundler/fetcher.rb @@ -323,7 +323,7 @@ module Bundler gem_list = [] deps_list = [] - gem_names.each_slice(Source::Rubygems::API_REQUEST_LIMIT) do |names| + gem_names.each_slice(Source::Rubygems::API_REQUEST_SIZE) do |names| marshalled_deps = fetch dependency_api_uri(names) gem_list += Bundler.load_marshal(marshalled_deps) end diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb index 52797314de..10526115a4 100644 --- a/lib/bundler/installer.rb +++ b/lib/bundler/installer.rb @@ -195,13 +195,12 @@ module Bundler private def can_install_in_parallel? - min_rubygems = "2.0.7" - if Bundler.current_ruby.mri? || Bundler.rubygems.provides?(">= #{min_rubygems}") + if Bundler.rubygems.provides?(">= 2.1.0") true else Bundler.ui.warn "Rubygems #{Gem::VERSION} is not threadsafe, so your "\ - "gems must be installed one at a time. Upgrade to Rubygems " \ - "#{min_rubygems} or higher to enable parallel gem installation." + "gems must be installed one at a time. Upgrade to Rubygems 2.1.0 " \ + "or higher to enable parallel gem installation." false end end diff --git a/lib/bundler/lockfile_parser.rb b/lib/bundler/lockfile_parser.rb index 07eb676661..1ced10ac33 100644 --- a/lib/bundler/lockfile_parser.rb +++ b/lib/bundler/lockfile_parser.rb @@ -47,6 +47,10 @@ module Bundler end @sources << @rubygems_aggregate @specs = @specs.values + rescue ArgumentError => e + Bundler.ui.debug(e) + raise LockfileError, "Your lockfile is unreadable. Run `rm Gemfile.lock` " \ + "and then `bundle install` to generate a new lockfile." end private diff --git a/lib/bundler/rubygems_integration.rb b/lib/bundler/rubygems_integration.rb index f139e9d337..d32bbb36ff 100644 --- a/lib/bundler/rubygems_integration.rb +++ b/lib/bundler/rubygems_integration.rb @@ -1,3 +1,4 @@ +require 'monitor' require 'rubygems' require 'rubygems/config_file' @@ -134,6 +135,10 @@ module Bundler Gem::DefaultUserInteraction.ui = obj end + def ext_lock + @ext_lock ||= Monitor.new + end + def fetch_specs(all, pre, &blk) specs = Gem::SpecFetcher.new.list(all, pre) specs.each { yield } if block_given? @@ -554,9 +559,37 @@ module Bundler end end + class MoreFuture < Future + def initialize + super + backport_ext_builder_monitor + end + + def backport_ext_builder_monitor + require 'rubygems/ext' + + Gem::Ext::Builder.class_eval do + if !const_defined?(:CHDIR_MONITOR) + const_set(:CHDIR_MONITOR, Monitor.new) + end + + if const_defined?(:CHDIR_MUTEX) + remove_const(:CHDIR_MUTEX) + const_set(:CHDIR_MUTEX, const_get(:CHDIR_MONITOR)) + end + end + end + + def ext_lock + Gem::Ext::Builder::CHDIR_MONITOR + end + end + end - if RubygemsIntegration.provides?(">= 1.99.99") + if RubygemsIntegration.provides?(">= 2.1.0") + @rubygems = RubygemsIntegration::MoreFuture.new + elsif RubygemsIntegration.provides?(">= 1.99.99") @rubygems = RubygemsIntegration::Future.new elsif RubygemsIntegration.provides?('>= 1.8.20') @rubygems = RubygemsIntegration::MoreModern.new diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb index afaddf9944..30df4df4bc 100644 --- a/lib/bundler/settings.rb +++ b/lib/bundler/settings.rb @@ -1,3 +1,5 @@ +require 'uri' + module Bundler class Settings BOOL_KEYS = %w(frozen cache_all no_prune disable_local_branch_check gem.mit gem.coc).freeze @@ -127,6 +129,9 @@ module Bundler private def key_for(key) + if key.is_a?(String) && /https?:/ =~ key + key = normalize_uri(key).to_s + end key = key.to_s.gsub(".", "__").upcase "BUNDLE_#{key}" end @@ -182,7 +187,9 @@ module Bundler uri = uri.to_s uri = "#{uri}/" unless uri =~ %r[/\Z] uri = URI(uri) - raise ArgumentError, "Gem mirror sources must be absolute URIs (configured: #{mirror_source})" unless uri.absolute? + unless uri.absolute? + raise ArgumentError, "Gem sources must be absolute. You provided '#{uri}'." + end uri end diff --git a/lib/bundler/shared_helpers.rb b/lib/bundler/shared_helpers.rb index e3a019dc8b..0087f0786a 100644 --- a/lib/bundler/shared_helpers.rb +++ b/lib/bundler/shared_helpers.rb @@ -1,4 +1,3 @@ -require 'monitor' require 'pathname' require 'rubygems' @@ -19,7 +18,6 @@ end module Bundler module SharedHelpers attr_accessor :gem_loaded - CHDIR_MONITOR = Monitor.new def default_gemfile gemfile = find_gemfile @@ -52,7 +50,7 @@ module Bundler end def chdir_monitor - CHDIR_MONITOR + Bundler.rubygems.ext_lock end def chdir(dir, &blk) diff --git a/lib/bundler/source/path.rb b/lib/bundler/source/path.rb index 3901a700bb..59131a52b4 100644 --- a/lib/bundler/source/path.rb +++ b/lib/bundler/source/path.rb @@ -172,7 +172,7 @@ module Bundler end def generate_bin(spec, disable_extensions = false) - gem_dir = Pathname.new(spec.full_gem_path) + gem_dir = Pathname.new(spec.full_gem_path) # Some gem authors put absolute paths in their gemspec # and we have to save them from themselves diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb index a769ee6953..9aa7019e4c 100644 --- a/lib/bundler/source/rubygems.rb +++ b/lib/bundler/source/rubygems.rb @@ -5,8 +5,10 @@ require 'rubygems/spec_fetcher' module Bundler class Source class Rubygems < Source - # threshold for switching back to the modern index instead of fetching every spec - API_REQUEST_LIMIT = 100 + # Use the API when installing less than X gems + API_REQUEST_LIMIT = 500 + # Ask for X gems per API request + API_REQUEST_SIZE = 50 attr_reader :remotes, :caches @@ -149,6 +151,9 @@ module Bundler return if File.dirname(cached_path) == Bundler.app_cache.to_s Bundler.ui.info " * #{File.basename(cached_path)}" FileUtils.cp(cached_path, Bundler.app_cache(custom_path)) + rescue Errno::EACCES => e + Bundler.ui.debug(e) + raise InstallError, e.message end def cached_built_in_gem(spec) diff --git a/lib/bundler/templates/newgem/README.md.tt b/lib/bundler/templates/newgem/README.md.tt index d1d5dc47ca..45d901738f 100644 --- a/lib/bundler/templates/newgem/README.md.tt +++ b/lib/bundler/templates/newgem/README.md.tt @@ -26,7 +26,7 @@ TODO: Write usage instructions here ## Development -After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment. <% if config[:bin] %>Run `bundle exec <%= config[:name] %>` to use the code located in this directory, ignoring other installed copies of this gem.<% end %> +After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.<% if config[:bin] %> Run `bundle exec <%= config[:name] %>` to use the code located in this directory, ignoring other installed copies of this gem.<% end %> To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). diff --git a/lib/bundler/templates/newgem/newgem.gemspec.tt b/lib/bundler/templates/newgem/newgem.gemspec.tt index efc08c9544..bc52852b73 100644 --- a/lib/bundler/templates/newgem/newgem.gemspec.tt +++ b/lib/bundler/templates/newgem/newgem.gemspec.tt @@ -19,6 +19,7 @@ Gem::Specification.new do |spec| spec.license = "MIT" spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } + spec.bindir = "exe" spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ["lib"] <%- if config[:ext] -%> diff --git a/spec/bundler/gem_helper_spec.rb b/spec/bundler/gem_helper_spec.rb index d605f2e7ad..2b0f3d97aa 100644 --- a/spec/bundler/gem_helper_spec.rb +++ b/spec/bundler/gem_helper_spec.rb @@ -40,9 +40,9 @@ describe Bundler::GemHelper do it "handles namespaces and converts them to CamelCase" do bundle "gem #{app_name}-foo_bar" - app_path = bundled_app "#{app_name}-foo_bar" + underscore_path = bundled_app "#{app_name}-foo_bar" - lib = app_path.join("lib/#{app_name}/foo_bar.rb").read + lib = underscore_path.join("lib/#{app_name}/foo_bar.rb").read expect(lib).to include("module LoremIpsum") expect(lib).to include("module FooBar") end diff --git a/spec/bundler/settings_spec.rb b/spec/bundler/settings_spec.rb index 44f40ce3d0..0faaa3f51c 100644 --- a/spec/bundler/settings_spec.rb +++ b/spec/bundler/settings_spec.rb @@ -10,4 +10,38 @@ describe Bundler::Settings do end end end + + describe "URI normalization" do + let(:settings) { described_class.new(bundled_app) } + + it "normalizes HTTP URIs in credentials configuration" do + settings["http://gemserver.example.org"] = "username:password" + expect(settings.all).to include("http://gemserver.example.org/") + end + + it "normalizes HTTPS URIs in credentials configuration" do + settings["https://gemserver.example.org"] = "username:password" + expect(settings.all).to include("https://gemserver.example.org/") + end + + it "normalizes HTTP URIs in mirror configuration" do + settings["mirror.http://rubygems.org"] = "http://rubygems-mirror.org" + expect(settings.all).to include("mirror.http://rubygems.org/") + end + + it "normalizes HTTPS URIs in mirror configuration" do + settings["mirror.https://rubygems.org"] = "http://rubygems-mirror.org" + expect(settings.all).to include("mirror.https://rubygems.org/") + end + + it "does not normalize other config keys that happen to contain 'http'" do + settings["local.httparty"] = home("httparty") + expect(settings.all).to include("local.httparty") + end + + it "does not normalize other config keys that happen to contain 'https'" do + settings["local.httpsmarty"] = home("httpsmarty") + expect(settings.all).to include("local.httpsmarty") + end + end end diff --git a/spec/commands/config_spec.rb b/spec/commands/config_spec.rb index 15384157f9..f12a844cc1 100644 --- a/spec/commands/config_spec.rb +++ b/spec/commands/config_spec.rb @@ -202,6 +202,10 @@ E describe "quoting" do before(:each) { gemfile "# no gems" } + let(:long_string) do + "--with-xml2-include=/usr/pkg/include/libxml2 --with-xml2-lib=/usr/pkg/lib " \ + "--with-xslt-dir=/usr/pkg" + end it "saves quotes" do bundle "config foo something\\'" @@ -232,7 +236,6 @@ E end it "doesn't duplicate quotes around long wrapped values" do - long_string = "--with-xml2-include=/usr/pkg/include/libxml2 --with-xml2-lib=/usr/pkg/lib --with-xslt-dir=/usr/pkg" bundle "config foo #{long_string}" run "puts Bundler.settings[:foo]" @@ -248,10 +251,12 @@ E describe "very long lines" do before(:each) { bundle :install } let(:long_string) do - "--with-xml2-include=/usr/pkg/include/libxml2 --with-xml2-lib=/usr/pkg/lib --with-xslt-dir=/usr/pkg" + "--with-xml2-include=/usr/pkg/include/libxml2 --with-xml2-lib=/usr/pkg/lib " \ + "--with-xslt-dir=/usr/pkg" end let(:long_string_without_special_characters) do - "here is quite a long string that will wrap to a second line but will not be surrounded by quotes" + "here is quite a long string that will wrap to a second line but will not be " \ + "surrounded by quotes" end it "doesn't wrap values" do @@ -270,14 +275,14 @@ end describe "setting gemfile via config" do context "when only the non-default Gemfile exists" do - before do - gemfile bundled_app("NotGemfile"), <<-G - source "file://#{gem_repo1}" - gem 'rack' - G - end - it "persists the gemfile location to .bundle/config" do + File.open(bundled_app("NotGemfile"), "w") do |f| + f.write <<-G + source "file://#{gem_repo1}" + gem 'rack' + G + end + bundle "config --local gemfile #{bundled_app("NotGemfile")}" expect(File.exist?(".bundle/config")).to eq(true) diff --git a/spec/commands/newgem_spec.rb b/spec/commands/newgem_spec.rb index 09af5b0da6..2ca9a8a768 100644 --- a/spec/commands/newgem_spec.rb +++ b/spec/commands/newgem_spec.rb @@ -30,7 +30,7 @@ describe "bundle gem" do end end - shared_examples_for "git config is absent" do |hoge| + shared_examples_for "git config is absent" do it "sets gemspec author to default message if git user.name is not set or empty" do expect(generated_gem.gemspec.authors.first).to eq("TODO: Write your name") end @@ -40,6 +40,36 @@ describe "bundle gem" do end end + it "generates a valid gemspec" do + system_gems ["rake-10.0.2"] + + in_app_root + bundle "gem newgem --bin" + + process_file(bundled_app('newgem', "newgem.gemspec")) do |line| + next line unless line =~ /TODO/ + # Simulate replacing TODOs with real values + case line + when /spec\.metadata\['allowed_push_host'\]/, /spec\.homepage/ + line.gsub(/\=.*$/, "= 'http://example.org'") + when /spec\.summary/ + line.gsub(/\=.*$/, "= %q{A short summary of my new gem.}") + when /spec\.description/ + line.gsub(/\=.*$/, "= %q{A longer description of my new gem.}") + else + line + end + end + + Dir.chdir(bundled_app('newgem')) do + bundle "exec rake build" + end + + expect(exitstatus).to be_zero if exitstatus + expect(out).not_to include("ERROR") + expect(err).not_to include("ERROR") + end + context "gem naming with relative paths" do before do reset! diff --git a/spec/install/gems/groups_spec.rb b/spec/install/gems/groups_spec.rb index afce362ad8..23af4aee65 100644 --- a/spec/install/gems/groups_spec.rb +++ b/spec/install/gems/groups_spec.rb @@ -41,14 +41,14 @@ describe "bundle install with groups" do end it "sets up everything if Bundler.setup is used with no groups" do - out = run("require 'rack'; puts RACK") - expect(out).to eq('1.0.0') + output = run("require 'rack'; puts RACK") + expect(output).to eq('1.0.0') - out = run("require 'activesupport'; puts ACTIVESUPPORT") - expect(out).to eq('2.3.5') + output = run("require 'activesupport'; puts ACTIVESUPPORT") + expect(output).to eq('2.3.5') - out = run("require 'thin'; puts THIN") - expect(out).to eq('1.0') + output = run("require 'thin'; puts THIN") + expect(output).to eq('1.0') end it "removes old groups when new groups are set up" do @@ -62,12 +62,12 @@ describe "bundle install with groups" do end it "sets up old groups when they have previously been removed" do - out = run <<-RUBY, :emo + output = run <<-RUBY, :emo Bundler.setup(:default) Bundler.setup(:default, :emo) require 'thin'; puts THIN RUBY - expect(out).to eq('1.0') + expect(output).to eq('1.0') end end diff --git a/spec/quality_spec.rb b/spec/quality_spec.rb index 378f62d3ec..81fcddfb32 100644 --- a/spec/quality_spec.rb +++ b/spec/quality_spec.rb @@ -1,7 +1,8 @@ require "spec_helper" -if defined?(Encoding) && Encoding.default_external != "UTF-8" - Encoding.default_external = "UTF-8" +if defined?(Encoding) && Encoding.default_external.name != "UTF-8" + # Poor man's ruby -E UTF-8, since it works on 1.8.7 + Encoding.default_external = Encoding.find("UTF-8") end describe "The library itself" do diff --git a/spec/realworld/parallel_spec.rb b/spec/realworld/parallel_spec.rb index ef37020531..67311a7e7c 100644 --- a/spec/realworld/parallel_spec.rb +++ b/spec/realworld/parallel_spec.rb @@ -10,7 +10,12 @@ describe "parallel", :realworld => true do G bundle :install, :jobs => 4, :env => {"DEBUG" => "1"} - expect(out).to match(/[1-3]: /) + + if Bundler.rubygems.provides?(">= 2.1.0") + expect(out).to match(/[1-3]: /) + else + expect(out).to include("is not threadsafe") + end bundle "show activesupport" expect(out).to match(/activesupport/) @@ -37,7 +42,12 @@ describe "parallel", :realworld => true do G bundle :update, :jobs => 4, :env => {"DEBUG" => "1"} - expect(out).to match(/[1-3]: /) + + if Bundler.rubygems.provides?(">= 2.1.0") + expect(out).to match(/[1-3]: /) + else + expect(out).to include("is not threadsafe") + end bundle "show activesupport" expect(out).to match(/activesupport-3\.2\.\d+/) diff --git a/spec/support/builders.rb b/spec/support/builders.rb index dadaa731ce..5490a2b976 100644 --- a/spec/support/builders.rb +++ b/spec/support/builders.rb @@ -633,7 +633,7 @@ module Spec end end - TEST_CERT = <<-CERT.gsub /^\s*/, '' + TEST_CERT = <<-CERT.gsub(/^\s*/, '') -----BEGIN CERTIFICATE----- MIIDMjCCAhqgAwIBAgIBATANBgkqhkiG9w0BAQUFADAnMQwwCgYDVQQDDAN5b3Ux FzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMB4XDTE1MDIwODAwMTIyM1oXDTQyMDYy @@ -656,7 +656,7 @@ module Spec -----END CERTIFICATE----- CERT - TEST_PKEY = <<-PKEY.gsub /^\s*/, '' + TEST_PKEY = <<-PKEY.gsub(/^\s*/, '') -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEA2W8V2k3jdzgMxL0mjTqbRruTdtDcdZDXKtiFkyLvsXUXvc2k GSdgcjMOS1CkafqGz/hAUlPibjM0QEXjtQuMdTmdMrmuORLeeIZhSO+HdkTNV6j3 diff --git a/spec/support/helpers.rb b/spec/support/helpers.rb index c17a92c363..e5774f12a3 100644 --- a/spec/support/helpers.rb +++ b/spec/support/helpers.rb @@ -349,5 +349,12 @@ module Spec ensure Dir[pattern].each(&chmod[0755, 0644]) end + + def process_file(pathname) + changed_lines = pathname.readlines.map do |line| + yield line + end + File.open(pathname, 'w') { |file| file.puts(changed_lines.join) } + end end end |