diff options
Diffstat (limited to 'lib/bundler/settings.rb')
-rw-r--r-- | lib/bundler/settings.rb | 196 |
1 files changed, 143 insertions, 53 deletions
diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb index de42cc16af..abbaec9783 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,9 +42,21 @@ module Bundler setup_makes_kernel_gem_public silence_deprecations silence_root_warning - suppress_install_using_messages update_requires_all_flag - use_gem_version_promoter_for_major_updates + ].freeze + + REMEMBERED_KEYS = %w[ + bin + cache_all + clean + deployment + frozen + no_prune + path + shebang + path.system + without + with ].freeze NUMBER_KEYS = %w[ @@ -57,6 +68,7 @@ module Bundler ].freeze ARRAY_KEYS = %w[ + only with without ].freeze @@ -75,6 +87,7 @@ module Bundler shebang system_bindir trust-policy + version ].freeze DEFAULT_CONFIG = { @@ -84,25 +97,38 @@ 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_.+/ } + + @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 @@ -139,17 +165,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 +188,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 @@ -226,7 +257,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 @@ -276,12 +309,6 @@ module Bundler end end - def allow_sudo? - key = key_for(:path) - path_configured = @temporary.key?(key) || @local_config.key?(key) - !path_configured - end - def ignore_config? ENV["BUNDLE_IGNORE_CONFIG"] end @@ -300,18 +327,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 @@ -332,16 +359,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 @@ -349,11 +380,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) @@ -366,7 +401,7 @@ module Bundler def to_array(value) return [] unless value - value.split(":").map(&:to_sym) + value.tr(" ", ":").split(":").map(&:to_sym) end def array_to_s(array) @@ -376,7 +411,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,12 +426,13 @@ module Bundler return unless file SharedHelpers.filesystem_access(file) do |p| FileUtils.mkdir_p(p.dirname) - require_relative "yaml_serializer" - p.open("w") {|f| f.write(YAMLSerializer.dump(hash)) } + p.open("w") {|f| f.write(serializer_class.dump(hash)) } end end def converted_value(value, key) + key = self.class.key_to_s(key) + if is_array(key) to_array(value) elsif value.nil? @@ -419,7 +455,15 @@ module Bundler elsif is_credential(key) "[REDACTED]" elsif is_userinfo(converted) - converted.gsub(/:.*$/, ":[REDACTED]") + username, pass = converted.split(":", 2) + + if pass == "x-oauth-basic" + username = "[REDACTED]" + else + pass = "[REDACTED]" + end + + [username, pass].join(":") else converted end @@ -428,6 +472,10 @@ module Bundler def global_config_file if ENV["BUNDLE_CONFIG"] && !ENV["BUNDLE_CONFIG"].empty? Pathname.new(ENV["BUNDLE_CONFIG"]) + elsif ENV["BUNDLE_USER_CONFIG"] && !ENV["BUNDLE_USER_CONFIG"].empty? + Pathname.new(ENV["BUNDLE_USER_CONFIG"]) + elsif ENV["BUNDLE_USER_HOME"] && !ENV["BUNDLE_USER_HOME"].empty? + Pathname.new(ENV["BUNDLE_USER_HOME"]).join("config") elsif Bundler.rubygems.user_home && !Bundler.rubygems.user_home.empty? Pathname.new(Bundler.rubygems.user_home).join(".bundle/config") end @@ -442,24 +490,34 @@ module Bundler SharedHelpers.filesystem_access(config_file, :read) do |file| valid_file = file.exist? && !file.size.zero? return {} unless valid_file - require_relative "yaml_serializer" - YAMLSerializer.load(file.read).inject({}) do |config, (k, v)| - new_k = k - - 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 (`___`)." - - new_k = k.gsub("-", "___") + serializer_class.load(file.read).inject({}) do |config, (k, v)| + 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 (`___`)." + + # string hash keys are frozen + k = k.gsub("-", "___") + end + + config[k] = v end - config[new_k] = v config end end end + def serializer_class + require "rubygems/yaml_serializer" + Gem::YAMLSerializer + rescue LoadError + # TODO: Remove this when RubyGems 3.4 is EOL + require_relative "yaml_serializer" + YAMLSerializer + end + PER_URI_OPTIONS = %w[ fallback_timeout ].freeze @@ -471,12 +529,15 @@ module Bundler (https?.*?) # URI (\.#{Regexp.union(PER_URI_OPTIONS)})? # optional suffix key \z - /ix.freeze + /ix def self.key_for(key) - key = normalize_uri(key).to_s if key.is_a?(String) && /https?:/ =~ key - key = key.to_s.gsub(".", "__").gsub("-", "___").upcase - "BUNDLE_#{key}" + key = normalize_uri(key).to_s if key.is_a?(String) && key.start_with?("http", "mirror.http") + key = key_to_s(key).gsub(".", "__") + key.gsub!("-", "___") + key.upcase! + + key.prepend("BUNDLE_") end # TODO: duplicates Rubygems#normalize_uri @@ -488,13 +549,42 @@ module Bundler uri = $2 suffix = $3 end - uri = "#{uri}/" unless uri.end_with?("/") + 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 |