diff options
Diffstat (limited to 'lib/bundler/settings.rb')
-rw-r--r-- | lib/bundler/settings.rb | 166 |
1 files changed, 123 insertions, 43 deletions
diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb index 88dd829d66..878747a53b 100644 --- a/lib/bundler/settings.rb +++ b/lib/bundler/settings.rb @@ -7,7 +7,6 @@ module Bundler autoload :Validator, File.expand_path("settings/validator", __dir__) BOOL_KEYS = %w[ - allow_deployment_source_credential_changes allow_offline_install auto_clean_without_path auto_install @@ -43,10 +42,23 @@ module Bundler setup_makes_kernel_gem_public silence_deprecations silence_root_warning - suppress_install_using_messages update_requires_all_flag ].freeze + REMEMBERED_KEYS = %w[ + bin + cache_all + clean + deployment + frozen + no_prune + path + shebang + path.system + without + with + ].freeze + NUMBER_KEYS = %w[ jobs redirect @@ -75,6 +87,7 @@ module Bundler shebang system_bindir trust-policy + version ].freeze DEFAULT_CONFIG = { @@ -84,25 +97,39 @@ module Bundler "BUNDLE_REDIRECT" => 5, "BUNDLE_RETRY" => 3, "BUNDLE_TIMEOUT" => 10, + "BUNDLE_VERSION" => "lockfile", }.freeze def initialize(root = nil) @root = root @local_config = load_config(local_config_file) - @env_config = ENV.to_h.select {|key, _value| key =~ /\ABUNDLE_.+/ } + @local_root = root || Pathname.new(".bundle").expand_path + + @env_config = ENV.to_h + @env_config.select! {|key, _value| key.start_with?("BUNDLE_") } + @env_config.delete("BUNDLE_") + @global_config = load_config(global_config_file) @temporary = {} + + @key_cache = {} end def [](name) key = key_for(name) - value = configs.values.map {|config| config[key] }.compact.first + + value = nil + configs.each do |_, config| + value = config[key] + next if value.nil? + break + end converted_value(value, name) end def set_command_option(key, value) - if Bundler.feature_flag.forget_cli_options? + if !is_remembered(key) || Bundler.feature_flag.forget_cli_options? temporary(key => value) value else @@ -116,7 +143,7 @@ module Bundler end def set_local(key, value) - local_config_file || raise(GemfileNotFound, "Could not locate Gemfile") + local_config_file = @local_root.join("config") set_key(key, value, @local_config, local_config_file) end @@ -139,17 +166,22 @@ module Bundler end def all - keys = @temporary.keys | @global_config.keys | @local_config.keys | @env_config.keys + keys = @temporary.keys.union(@global_config.keys, @local_config.keys, @env_config.keys) - keys.map do |key| - key.sub(/^BUNDLE_/, "").gsub(/___/, "-").gsub(/__/, ".").downcase - end.sort + keys.map! do |key| + key = key.delete_prefix("BUNDLE_") + key.gsub!("___", "-") + key.gsub!("__", ".") + key.downcase! + key + end.sort! + keys end def local_overrides repos = {} all.each do |k| - repos[$'] = self[k] if k =~ /^local\./ + repos[k.delete_prefix("local.")] = self[k] if k.start_with?("local.") end repos end @@ -157,7 +189,7 @@ module Bundler def mirror_for(uri) if uri.is_a?(String) require_relative "vendored_uri" - uri = Bundler::URI(uri) + uri = Gem::URI(uri) end gem_mirrors.for(uri.to_s).uri @@ -219,7 +251,6 @@ module Bundler def path configs.each do |_level, settings| path = value_for("path", settings) - path = "vendor/bundle" if value_for("deployment", settings) && path.nil? path_system = value_for("path.system", settings) disabled_shared_gems = value_for("disable_shared_gems", settings) next if path.nil? && path_system.nil? && disabled_shared_gems.nil? @@ -227,7 +258,9 @@ module Bundler return Path.new(path, system_path) end - Path.new(nil, false) + path = "vendor/bundle" if self[:deployment] + + Path.new(path, false) end Path = Struct.new(:explicit_path, :system_path) do @@ -295,18 +328,18 @@ module Bundler end def key_for(key) - self.class.key_for(key) + @key_cache[key] ||= self.class.key_for(key) end private def configs - { - :temporary => @temporary, - :local => @local_config, - :env => @env_config, - :global => @global_config, - :default => DEFAULT_CONFIG, + @configs ||= { + temporary: @temporary, + local: @local_config, + env: @env_config, + global: @global_config, + default: DEFAULT_CONFIG, } end @@ -327,16 +360,20 @@ module Bundler end def is_bool(name) - BOOL_KEYS.include?(name.to_s) || BOOL_KEYS.include?(parent_setting_for(name.to_s)) + name = self.class.key_to_s(name) + BOOL_KEYS.include?(name) || BOOL_KEYS.include?(parent_setting_for(name)) end def is_string(name) - STRING_KEYS.include?(name.to_s) || name.to_s.start_with?("local.") || name.to_s.start_with?("mirror.") || name.to_s.start_with?("build.") + name = self.class.key_to_s(name) + STRING_KEYS.include?(name) || name.start_with?("local.") || name.start_with?("mirror.") || name.start_with?("build.") end def to_bool(value) case value - when nil, /\A(false|f|no|n|0|)\z/i, false + when String + value.match?(/\A(false|f|no|n|0|)\z/i) ? false : true + when nil, false false else true @@ -344,11 +381,15 @@ module Bundler end def is_num(key) - NUMBER_KEYS.include?(key.to_s) + NUMBER_KEYS.include?(self.class.key_to_s(key)) end def is_array(key) - ARRAY_KEYS.include?(key.to_s) + ARRAY_KEYS.include?(self.class.key_to_s(key)) + end + + def is_remembered(key) + REMEMBERED_KEYS.include?(self.class.key_to_s(key)) end def is_credential(key) @@ -371,7 +412,7 @@ module Bundler end def set_key(raw_key, value, hash, file) - raw_key = raw_key.to_s + raw_key = self.class.key_to_s(raw_key) value = array_to_s(value) if is_array(raw_key) key = key_for(raw_key) @@ -391,6 +432,8 @@ module Bundler end def converted_value(value, key) + key = self.class.key_to_s(key) + if is_array(key) to_array(value) elsif value.nil? @@ -449,17 +492,23 @@ module Bundler valid_file = file.exist? && !file.size.zero? return {} unless valid_file serializer_class.load(file.read).inject({}) do |config, (k, v)| - new_k = k + k = k.dup + k << "/" if /https?:/i.match?(k) && !k.end_with?("/", "__#{FALLBACK_TIMEOUT_URI_OPTION.upcase}") + k.gsub!(".", "__") + + unless k.start_with?("#") + if k.include?("-") + Bundler.ui.warn "Your #{file} config includes `#{k}`, which contains the dash character (`-`).\n" \ + "This is deprecated, because configuration through `ENV` should be possible, but `ENV` keys cannot include dashes.\n" \ + "Please edit #{file} and replace any dashes in configuration keys with a triple underscore (`___`)." - if k.include?("-") - Bundler.ui.warn "Your #{file} config includes `#{k}`, which contains the dash character (`-`).\n" \ - "This is deprecated, because configuration through `ENV` should be possible, but `ENV` keys cannot include dashes.\n" \ - "Please edit #{file} and replace any dashes in configuration keys with a triple underscore (`___`)." + # string hash keys are frozen + k = k.gsub("-", "___") + end - new_k = k.gsub("-", "___") + config[k] = v end - config[new_k] = v config end end @@ -474,23 +523,25 @@ module Bundler YAMLSerializer end - PER_URI_OPTIONS = %w[ - fallback_timeout - ].freeze + FALLBACK_TIMEOUT_URI_OPTION = "fallback_timeout" NORMALIZE_URI_OPTIONS_PATTERN = / \A (\w+\.)? # optional prefix key (https?.*?) # URI - (\.#{Regexp.union(PER_URI_OPTIONS)})? # optional suffix key + (\.#{FALLBACK_TIMEOUT_URI_OPTION})? # optional suffix key \z - /ix.freeze + /ix def self.key_for(key) - key = normalize_uri(key).to_s if key.is_a?(String) && key.start_with?("http", "mirror.http") - key = key.to_s.gsub(".", "__").gsub("-", "___").upcase - "BUNDLE_#{key}" + key = key_to_s(key) + key = normalize_uri(key) if key.start_with?("http", "mirror.http") + key = key.gsub(".", "__") + key.gsub!("-", "___") + key.upcase! + + key.gsub(/\A([ #]*)/, '\1BUNDLE_') end # TODO: duplicates Rubygems#normalize_uri @@ -504,11 +555,40 @@ module Bundler end uri = URINormalizer.normalize_suffix(uri) require_relative "vendored_uri" - uri = Bundler::URI(uri) + uri = Gem::URI(uri) unless uri.absolute? raise ArgumentError, format("Gem sources must be absolute. You provided '%s'.", uri) end "#{prefix}#{uri}#{suffix}" end + + # This is a hot method, so avoid respond_to? checks on every invocation + if :read.respond_to?(:name) + def self.key_to_s(key) + case key + when String + key + when Symbol + key.name + when Gem::URI::HTTP + key.to_s + else + raise ArgumentError, "Invalid key: #{key.inspect}" + end + end + else + def self.key_to_s(key) + case key + when String + key + when Symbol + key.to_s + when Gem::URI::HTTP + key.to_s + else + raise ArgumentError, "Invalid key: #{key.inspect}" + end + end + end end end |