summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPablo Carranza <pcarranza@gmail.com>2015-12-06 16:56:59 +0000
committerPablo Carranza <pcarranza@gmail.com>2015-12-27 22:19:55 +0100
commitecf26eaa1010906b766b87712ba585574b455dfa (patch)
tree8e8fa127806cd8d60bba9b4a53da6d419da11e7e
parentbc4bb7b8c82fc406e5c6445d2e54b0afbe6d776c (diff)
downloadbundler-ecf26eaa1010906b766b87712ba585574b455dfa.tar.gz
Improved mirror config parsing with support for all and fallback_timeout
-rw-r--r--lib/bundler/mirror.rb102
-rw-r--r--lib/bundler/settings.rb31
-rw-r--r--spec/bundler/mirror_spec.rb54
-rw-r--r--spec/bundler/settings_spec.rb7
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