class Bundler::Settings - bundler: Ruby Standard Library Documentation

# class Bundler::Settings

### Constants

ARRAY_KEYS
BOOL_KEYS
DEFAULT_CONFIG
FALLBACK_TIMEOUT_URI_OPTION
NORMALIZE_URI_OPTIONS_PATTERN
NUMBER_KEYS
Path
REMEMBERED_KEYS
STRING_KEYS

### Public Class Methods

new(root = nil) click to toggle source

    # File bundler/settings.rb, line 104
    def initialize(root = nil)
      @root            = root
      @local_config    = load_config(local_config_file)
      @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

### Private Class Methods

key_for(key) click to toggle source

    # File bundler/settings.rb, line 542
    def self.key_for(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

key_to_s(key) click to toggle source

    # File bundler/settings.rb, line 572
    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

normalize_uri(uri) click to toggle source

TODO: duplicates Rubygems#normalize_uri TODO: is this the correct place to validate mirror URIs?

    # File bundler/settings.rb, line 554
    def self.normalize_uri(uri)
      uri = uri.to_s
      if uri =~ NORMALIZE_URI_OPTIONS_PATTERN
        prefix = $1
        uri = $2
        suffix = $3
      end
      uri = URINormalizer.normalize_suffix(uri)
      require_relative "vendored_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

### Public Instance Methods

[](name) click to toggle source

    # File bundler/settings.rb, line 119
    def [](name)
      key = key_for(name)

      value = nil
      configs.each do |_, config|
        value = config[key]
        next if value.nil?
        break
      end

      converted_value(value, name)
    end

all() click to toggle source

    # File bundler/settings.rb, line 169
    def all
      keys = @temporary.keys.union(@global_config.keys, @local_config.keys, @env_config.keys)

      keys.map! do |key|
        key = key.delete_prefix("BUNDLE_")
        key.gsub!("___", "-")
        key.gsub!("__", ".")
        key.downcase!
        key
      end.sort!
      keys
    end

app_cache_path() click to toggle source

    # File bundler/settings.rb, line 318
    def app_cache_path
      @app_cache_path ||= self[:cache_path] || "vendor/cache"
    end

credentials_for(uri) click to toggle source

    # File bundler/settings.rb, line 199
    def credentials_for(uri)
      self[uri.to_s] || self[uri.host]
    end

gem_mirrors() click to toggle source

    # File bundler/settings.rb, line 203
    def gem_mirrors
      all.inject(Mirrors.new) do |mirrors, k|
        mirrors.parse(k, self[k]) if k.start_with?("mirror.")
        mirrors
      end
    end

ignore_config?() click to toggle source

    # File bundler/settings.rb, line 314
    def ignore_config?
      ENV["BUNDLE_IGNORE_CONFIG"]
    end

key_for(key) click to toggle source

    # File bundler/settings.rb, line 331
    def key_for(key)
      @key_cache[key] ||= self.class.key_for(key)
    end

local_overrides() click to toggle source

    # File bundler/settings.rb, line 182
    def local_overrides
      repos = {}
      all.each do |k|
        repos[k.delete_prefix("local.")] = self[k] if k.start_with?("local.")
      end
      repos
    end

locations(key) click to toggle source

    # File bundler/settings.rb, line 210
    def locations(key)
      key = key_for(key)
      configs.keys.inject({}) do |partial_locations, level|
        value_on_level = configs[level][key]
        partial_locations[level] = value_on_level unless value_on_level.nil?
        partial_locations
      end
    end

mirror_for(uri) click to toggle source

    # File bundler/settings.rb, line 190
    def mirror_for(uri)
      if uri.is_a?(String)
        require_relative "vendored_uri"
        uri = Gem::URI(uri)
      end

      gem_mirrors.for(uri.to_s).uri
    end

path() click to toggle source

for legacy reasons, in `Bundler` 2, we do not respect :disable_shared_gems

    # File bundler/settings.rb, line 252
    def path
      configs.each do |_level, settings|
        path = value_for("path", settings)
        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?
        system_path = path_system || (disabled_shared_gems == false)
        return Path.new(path, system_path)
      end

      path = "vendor/bundle" if self[:deployment]

      Path.new(path, false)
    end

pretty_values_for(exposed_key) click to toggle source

    # File bundler/settings.rb, line 219
    def pretty_values_for(exposed_key)
      key = key_for(exposed_key)

      locations = []

      if value = @temporary[key]
        locations << "Set for the current command: #{printable_value(value, exposed_key).inspect}"
      end

      if value = @local_config[key]
        locations << "Set for your local app (#{local_config_file}): #{printable_value(value, exposed_key).inspect}"
      end

      if value = @env_config[key]
        locations << "Set via #{key}: #{printable_value(value, exposed_key).inspect}"
      end

      if value = @global_config[key]
        locations << "Set for the current user (#{global_config_file}): #{printable_value(value, exposed_key).inspect}"
      end

      return ["You have not configured a value for `#{exposed_key}`"] if locations.empty?
      locations
    end

processor_count() click to toggle source

    # File bundler/settings.rb, line 244
    def processor_count
      require "etc"
      Etc.nprocessors
    rescue StandardError
      1
    end

set_command_option(key, value) click to toggle source

    # File bundler/settings.rb, line 132
    def set_command_option(key, value)
      if !is_remembered(key) || Bundler.feature_flag.forget_cli_options?
        temporary(key => value)
        value
      else
        set_local(key, value)
      end
    end

set_command_option_if_given(key, value) click to toggle source

    # File bundler/settings.rb, line 141
    def set_command_option_if_given(key, value)
      return if value.nil?
      set_command_option(key, value)
    end

set_global(key, value) click to toggle source

    # File bundler/settings.rb, line 165
    def set_global(key, value)
      set_key(key, value, @global_config, global_config_file)
    end

set_local(key, value) click to toggle source

    # File bundler/settings.rb, line 146
    def set_local(key, value)
      local_config_file = @local_root.join("config")

      set_key(key, value, @local_config, local_config_file)
    end

temporary(update) { || ... } click to toggle source

    # File bundler/settings.rb, line 152
    def temporary(update)
      existing = Hash[update.map {|k, _| [k, @temporary[key_for(k)]] }]
      update.each do |k, v|
        set_key(k, v, @temporary, nil)
      end
      return unless block_given?
      begin
        yield
      ensure
        existing.each {|k, v| set_key(k, v, @temporary, nil) }
      end
    end

validate!() click to toggle source

    # File bundler/settings.rb, line 322
    def validate!
      all.each do |raw_key|
        [@local_config, @env_config, @global_config].each do |settings|
          value = value_for(raw_key, settings)
          Validator.validate!(raw_key, value, settings.dup)
        end
      end
    end

### Private Instance Methods

array_to_s(array) click to toggle source

    # File bundler/settings.rb, line 409
    def array_to_s(array)
      array = Array(array)
      return nil if array.empty?
      array.join(":").tr(" ", ":")
    end

configs() click to toggle source

    # File bundler/settings.rb, line 337
    def configs
      @configs ||= {
        temporary: @temporary,
        local: @local_config,
        env: @env_config,
        global: @global_config,
        default: DEFAULT_CONFIG,
      }
    end

converted_value(value, key) click to toggle source

    # File bundler/settings.rb, line 439
    def converted_value(value, key)
      key = self.class.key_to_s(key)

      if is_array(key)
        to_array(value)
      elsif value.nil?
        nil
      elsif is_bool(key) || value == "false"
        to_bool(value)
      elsif is_num(key)
        value.to_i
      else
        value.to_s
      end
    end

global_config_file() click to toggle source

    # File bundler/settings.rb, line 478
    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
    end

is_array(key) click to toggle source

    # File bundler/settings.rb, line 388
    def is_array(key)
      ARRAY_KEYS.include?(self.class.key_to_s(key))
    end

is_bool(name) click to toggle source

    # File bundler/settings.rb, line 363
    def is_bool(name)
      name = self.class.key_to_s(name)
      BOOL_KEYS.include?(name) || BOOL_KEYS.include?(parent_setting_for(name))
    end

is_credential(key) click to toggle source

    # File bundler/settings.rb, line 396
    def is_credential(key)
      key == "gem.push_key"
    end

is_num(key) click to toggle source

    # File bundler/settings.rb, line 384
    def is_num(key)
      NUMBER_KEYS.include?(self.class.key_to_s(key))
    end

is_remembered(key) click to toggle source

    # File bundler/settings.rb, line 392
    def is_remembered(key)
      REMEMBERED_KEYS.include?(self.class.key_to_s(key))
    end

is_string(name) click to toggle source

    # File bundler/settings.rb, line 368
    def is_string(name)
      name = self.class.key_to_s(name)
      STRING_KEYS.include?(name) || name.start_with?("local.") || name.start_with?("mirror.") || name.start_with?("build.")
    end

is_userinfo(value) click to toggle source

    # File bundler/settings.rb, line 400
    def is_userinfo(value)
      value.include?(":")
    end

load_config(config_file) click to toggle source

    # File bundler/settings.rb, line 494
    def load_config(config_file)
      return {} if !config_file || ignore_config?
      SharedHelpers.filesystem_access(config_file, :read) do |file|
        valid_file = file.exist? && !file.size.zero?
        return {} unless valid_file
        serializer_class.load(file.read).inject({}) do |config, (k, v)|
          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 (`___`)."

              # string hash keys are frozen
              k = k.gsub("-", "___")
            end

            config[k] = v
          end

          config
        end
      end
    end

local_config_file() click to toggle source

    # File bundler/settings.rb, line 490
    def local_config_file
      Pathname.new(@root).join("config") if @root
    end

parent_setting_for(name) click to toggle source

    # File bundler/settings.rb, line 351
    def parent_setting_for(name)
      split_specific_setting_for(name)[0]
    end

printable_value(value, key) click to toggle source

    # File bundler/settings.rb, line 455
    def printable_value(value, key)
      converted = converted_value(value, key)
      return converted unless converted.is_a?(String)

      if is_string(key)
        converted
      elsif is_credential(key)
        "[REDACTED]"
      elsif is_userinfo(converted)
        username, pass = converted.split(":", 2)

        if pass == "x-oauth-basic"
          username = "[REDACTED]"
        else
          pass = "[REDACTED]"
        end

        [username, pass].join(":")
      else
        converted
      end
    end

serializer_class() click to toggle source

    # File bundler/settings.rb, line 522
    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

set_key(raw_key, value, hash, file) click to toggle source

    # File bundler/settings.rb, line 415
    def set_key(raw_key, value, hash, file)
      raw_key = self.class.key_to_s(raw_key)
      value = array_to_s(value) if is_array(raw_key)

      key = key_for(raw_key)

      return if hash[key] == value

      hash[key] = value
      hash.delete(key) if value.nil?

      Validator.validate!(raw_key, converted_value(value, raw_key), hash)

      return unless file

      SharedHelpers.filesystem_access(file.dirname, :create) do |p|
        FileUtils.mkdir_p(p)
      end

      SharedHelpers.filesystem_access(file) do |p|
        p.open("w") {|f| f.write(serializer_class.dump(hash)) }
      end
    end

specific_gem_for(name) click to toggle source

    # File bundler/settings.rb, line 355
    def specific_gem_for(name)
      split_specific_setting_for(name)[1]
    end

split_specific_setting_for(name) click to toggle source

    # File bundler/settings.rb, line 359
    def split_specific_setting_for(name)
      name.split(".")
    end

to_array(value) click to toggle source

    # File bundler/settings.rb, line 404
    def to_array(value)
      return [] unless value
      value.tr(" ", ":").split(":").map(&:to_sym)
    end

to_bool(value) click to toggle source

    # File bundler/settings.rb, line 373
    def to_bool(value)
      case value
      when String
        value.match?(/\A(false|f|no|n|0|)\z/i) ? false : true
      when nil, false
        false
      else
        true
      end
    end

value_for(name, config) click to toggle source

    # File bundler/settings.rb, line 347
    def value_for(name, config)
      converted_value(config[key_for(name)], name)
    end