diff options
author | Pablo Carranza <pcarranza@gmail.com> | 2015-12-06 16:56:59 +0000 |
---|---|---|
committer | Pablo Carranza <pcarranza@gmail.com> | 2015-12-27 22:19:55 +0100 |
commit | ecf26eaa1010906b766b87712ba585574b455dfa (patch) | |
tree | 8e8fa127806cd8d60bba9b4a53da6d419da11e7e | |
parent | bc4bb7b8c82fc406e5c6445d2e54b0afbe6d776c (diff) | |
download | bundler-ecf26eaa1010906b766b87712ba585574b455dfa.tar.gz |
Improved mirror config parsing with support for all and fallback_timeout
-rw-r--r-- | lib/bundler/mirror.rb | 102 | ||||
-rw-r--r-- | lib/bundler/settings.rb | 31 | ||||
-rw-r--r-- | spec/bundler/mirror_spec.rb | 54 | ||||
-rw-r--r-- | spec/bundler/settings_spec.rb | 7 |
4 files changed, 156 insertions, 38 deletions
diff --git a/lib/bundler/mirror.rb b/lib/bundler/mirror.rb index 5805d89bdf..dda6022e78 100644 --- a/lib/bundler/mirror.rb +++ b/lib/bundler/mirror.rb @@ -1,20 +1,94 @@ -class Mirror < Struct.new(:uri, :fallback_timeout) -end +module Bundler + class Settings + class Mirrors + def initialize + @all = Mirror.new + @mirrors = Hash.new { |h, k| h[k] = Mirror.new } + end -class Mirrors - def initialize - @mirrors = Hash.new { |h, k| h[k] = Mirror.new } - end + def [](key) + @mirrors[URI(key.to_s)] + end - def [](key) - @mirrors[key] - end + def fetch(key, &block) + @mirrors.fetch(key, &block) + end - def fetch(key, &block) - @mirrors.fetch(key, &block) - end + def each + @mirrors.each do |k, v| + yield k, v.uri.to_s + end + end + + def parse(key, value) + config = MirrorConfig.new(key, value) + if config.all? + mirror = @all + else + mirror = self[config.uri] + end + config.update_mirror(mirror) + end + end + + class Mirror + DEFAULT_FALLBACK_TIMEOUT = 0.1 + + attr_reader :uri, :fallback_timeout + + def initialize(uri = nil, fallback_timeout = 0) + self.uri = uri + self.fallback_timeout = fallback_timeout + end + + def uri=(uri) + @uri = URI(uri.to_s) + end + + def fallback_timeout=(timeout) + case timeout + when true + @fallback_timeout = DEFAULT_FALLBACK_TIMEOUT + when false + @fallback_timeout = 0 + else + @fallback_timeout = timeout.to_i + end + end + + def ==(o) + self.class == o.class && self.uri == o.uri && self.fallback_timeout == o.fallback_timeout + end + + def valid? + ! @uri.nil? + end + end + + private + + class MirrorConfig + attr_reader :uri, :value + def initialize(config_line, value) + all, uri, fallback = + config_line.match(/^mirror(\.all)?\.(.+?)(\.fallback_timeout)?\/?$/).captures + @all = !all.nil? + @fallback = !fallback.nil? + @uri = AbsoluteURI.normalize(uri) + @value = value + end + + def all? + @all + end - def to_h - @mirrors + def update_mirror(mirror) + if @fallback + mirror.fallback_timeout = @value + else + mirror.uri = AbsoluteURI.normalize(@value) + end + end + end end end diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb index 853ee3aff8..f3eed3b3df 100644 --- a/lib/bundler/settings.rb +++ b/lib/bundler/settings.rb @@ -65,7 +65,7 @@ module Bundler uri = URI(uri.to_s) unless uri.is_a?(URI) # Settings keys are all downcased - normalized_key = normalize_uri(uri.to_s.downcase) + normalized_key = AbsoluteURI.normalize(uri.to_s.downcase) (gem_mirrors.fetch(normalized_key) { Mirror.new(uri) }).uri end @@ -75,16 +75,7 @@ module Bundler def gem_mirrors all.inject(Mirrors.new) do |mirrors, k| - if k =~ /^mirror\./ - uri = $' - if uri =~ /\.fallback_timeout\/$/ - uri = normalize_uri($`) - mirrors[uri].fallback_timeout = self[k].to_i - else - uri = normalize_uri(uri) - mirrors[uri].uri = normalize_uri(self[k]) - end - end + mirrors.parse(k, self[k]) if k =~ /^mirror\./ mirrors end end @@ -167,7 +158,7 @@ module Bundler private def key_for(key) - key = normalize_uri(key).to_s if key.is_a?(String) && /https?:/ =~ key + key = AbsoluteURI.normalize(key).to_s if key.is_a?(String) && /https?:/ =~ key key = key.to_s.gsub(".", "__").upcase "BUNDLE_#{key}" end @@ -250,14 +241,16 @@ module Bundler # TODO: duplicates Rubygems#normalize_uri # TODO: is this the correct place to validate mirror URIs? - def normalize_uri(uri) - uri = uri.to_s - uri = "#{uri}/" unless uri =~ %r{/\Z} - uri = URI(uri) - unless uri.absolute? - raise ArgumentError, "Gem sources must be absolute. You provided '#{uri}'." + class AbsoluteURI + def self.normalize(uri) + uri = uri.to_s + uri = "#{uri}/" unless uri =~ %r{/\Z} + uri = URI(uri) + unless uri.absolute? + raise ArgumentError, "Gem sources must be absolute. You provided '#{uri}'." + end + uri end - uri end end end diff --git a/spec/bundler/mirror_spec.rb b/spec/bundler/mirror_spec.rb new file mode 100644 index 0000000000..9a97dc4f1c --- /dev/null +++ b/spec/bundler/mirror_spec.rb @@ -0,0 +1,54 @@ +require "spec_helper" +require "bundler/mirror" + +describe Bundler::Settings::Mirror do + let(:mirror) { Bundler::Settings::Mirror.new } + + it "returns zero when fallback_timeout is not set" do + expect(mirror.fallback_timeout).to eq(0) + end + + it "takes a number as a fallback_timeout" do + mirror.fallback_timeout = 1 + expect(mirror.fallback_timeout).to eq(1) + end + + it "takes truthy as a default fallback timeout" do + mirror.fallback_timeout = true + expect(mirror.fallback_timeout).to eq(0.1) + end + + it "takes falsey as a zero fallback timeout" do + mirror.fallback_timeout = false + expect(mirror.fallback_timeout).to eq(0) + end + + it "takes a string but returns a uri" do + mirror.uri = "http://localhost:9292" + expect(mirror.uri).to eq(URI("http://localhost:9292")) + end + + it "takes an uri for the uri" do + mirror.uri = URI("http://localhost:9293") + expect(mirror.uri).to eq(URI("http://localhost:9293")) + end +end + +describe Bundler::Settings::Mirrors do + let(:mirrors) { Bundler::Settings::Mirrors.new } + + it "returns an empty mirror for a new uri" do + mirror = mirrors["http://rubygems.org/"] + expect(mirror).to eq(Bundler::Settings::Mirror.new) + end + + it "takes a mirror key and assings the uri" do + mirrors.parse("mirror.http://rubygems.org/", "http://localhost:9292") + expect(mirrors["http://rubygems.org/"].uri).to eq(URI("http://localhost:9292")) + end + + it "takes a mirror fallback_timeout and assigns the timeout" do + mirrors.parse("mirror.http://rubygems.org.fallback_timeout", "2") + expect(mirrors["http://rubygems.org/"].fallback_timeout).to eq(2) + end +end diff --git a/spec/bundler/settings_spec.rb b/spec/bundler/settings_spec.rb index 4f7b3c0283..914f600357 100644 --- a/spec/bundler/settings_spec.rb +++ b/spec/bundler/settings_spec.rb @@ -113,10 +113,6 @@ describe Bundler::Settings do it "returns the fallback timeout" do expect(settings.gem_mirrors[uri].fallback_timeout).to eq(1) end - - it "has the uri and the fallback timeout" do - expect(settings.gem_mirrors.to_h).to eq(uri => Mirror.new(mirror_uri, 1)) - end end end end @@ -181,7 +177,8 @@ describe Bundler::Settings do it "reads older keys without trailing slashes" do settings["mirror.https://rubygems.org"] = "http://rubygems-mirror.org" - expect(settings.gem_mirrors.to_h).to eq(URI("https://rubygems.org/") => Mirror.new(URI("http://rubygems-mirror.org/"))) + expect(settings.mirror_for("https://rubygems.org/")).to eq( + URI("http://rubygems-mirror.org/")) end end |