123456789_123456789_123456789_123456789_123456789_

Class: Gem::ConfigFile

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Instance Chain:
Inherits: Object
Defined in: lib/rubygems/config_file.rb

Overview

ConfigFile RubyGems options and gem command options from gemrc.

gemrc is a ::YAML file that uses strings to match gem command arguments and symbols to match RubyGems options.

::Gem command arguments use a String key that matches the command name and allow you to specify default arguments:

install: --no-rdoc --no-ri
update: --no-rdoc --no-ri

You can use gem: to set default arguments for all commands.

RubyGems options use symbol keys. Valid options are:

:backtrace

See #backtrace

:sources

Sets sources

:verbose

See #verbose

gemrc files may exist in various locations and are read and merged in the following order:

  • system wide (/etc/gemrc)

  • per user (~/.gemrc)

  • per environment (gemrc files listed in the GEMRC environment variable)

Constant Summary

Class Method Summary

Instance Attribute Summary

  • #args readonly

    List of arguments supplied to the config file object.

  • #backtrace rw

    True if the backtrace option has been specified, or debug is on.

  • #backtrace=(value) rw

    True if we print backtraces on errors.

  • #bulk_threshold rw

    Bulk threshold value.

  • #disable_default_gem_server rw

    True if we want to force specification of gem server when pushing a gem.

  • #home rw

    Where to install gems (deprecated).

  • #path rw

    Where to look for gems (deprecated).

  • #rubygems_api_key rw

    Returns the RubyGems.org API key.

  • #rubygems_api_key=(api_key) rw

    Sets the RubyGems.org API key to api_key

  • #sources rw

    sources to look for gems.

  • #ssl_ca_cert rw

    Path name of directory or file of openssl CA certificate, used for remote https connection.

  • #ssl_client_cert readonly

    Path name of directory or file of openssl client certificate, used for remote https connection with client authentication.

  • #ssl_verify_mode readonly

    openssl verify mode value, used for remote https connection.

  • #update_sources rw

    True if we want to update the SourceInfoCache every time, false otherwise.

  • #verbose rw

    Verbose level of output: * false – No output * true – Normal output * :loud – Extra output.

  • #hash readonly protected

DefaultUserInteraction - Included

Instance Method Summary

UserInteraction - Included

#alert

Displays an alert statement.

#alert_error

Displays an error statement to the error output location.

#alert_warning

Displays a warning statement to the warning output location.

#ask

Asks a question and returns the answer.

#ask_for_password

Asks for a password with a prompt

#ask_yes_no

Asks a yes or no question.

#choose_from_list

Asks the user to answer question with an answer from the given list.

#say

Displays the given statement on the standard output (or equivalent).

#terminate_interaction

Terminates the RubyGems process with the given exit_code

#verbose

Calls say with msg or the results of the block if really_verbose is true.

DefaultUserInteraction - Included

Text - Included

#clean_text

Remove any non-printable characters and make the text suitable for printing.

#format_text

Wraps text to wrap characters and optionally indents by indent characters.

#levenshtein_distance

This code is based directly on the Text gem implementation Returns a value representing the “cost” of transforming str1 into str2.

#truncate_text, #min3

Constructor Details

.new(args) ⇒ ConfigFile

Create the config file object. #args is the list of arguments from the command line.

The following command line options are handled early here rather than later at the time most command options are processed.

--config-file, --config-file==NAME

Obviously these need to be handled by the ConfigFile object to ensure we get the right config file.

--backtrace

Backtrace needs to be turned on early so that errors before normal option parsing can be properly handled.

--debug

Enable Ruby level debug messages. Handled early for the same reason as –backtrace.

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 176

def initialize(args)
  @config_file_name = nil
  need_config_file_name = false

  arg_list = []

  args.each do |arg|
    if need_config_file_name then
      @config_file_name = arg
      need_config_file_name = false
    elsif arg =~ /^--config-file=(.*)/ then
      @config_file_name = $1
    elsif arg =~ /^--config-file$/ then
      need_config_file_name = true
    else
      arg_list << arg
    end
  end

  @backtrace = DEFAULT_BACKTRACE
  @bulk_threshold = DEFAULT_BULK_THRESHOLD
  @verbose = DEFAULT_VERBOSITY
  @update_sources = DEFAULT_UPDATE_SOURCES

  operating_system_config = Marshal.load Marshal.dump(OPERATING_SYSTEM_DEFAULTS)
  platform_config = Marshal.load Marshal.dump(PLATFORM_DEFAULTS)
  system_config = load_file SYSTEM_WIDE_CONFIG_FILE
  user_config = load_file config_file_name.dup.untaint
  environment_config = (ENV['GEMRC'] || '').split(/[:;]/).inject({}) do |result, file|
    result.merge load_file file
  end

  @hash = operating_system_config.merge platform_config
  unless arg_list.index '--norc'
    @hash = @hash.merge system_config
    @hash = @hash.merge user_config
    @hash = @hash.merge environment_config
  end

  # HACK these override command-line args, which is bad
  @backtrace                  = @hash[:backtrace]                  if @hash.key? :backtrace
  @bulk_threshold             = @hash[:bulk_threshold]             if @hash.key? :bulk_threshold
  @home                       = @hash[:gemhome]                    if @hash.key? :gemhome
  @path                       = @hash[:gempath]                    if @hash.key? :gempath
  @update_sources             = @hash[:update_sources]             if @hash.key? :update_sources
  @verbose                    = @hash[:verbose]                    if @hash.key? :verbose
  @disable_default_gem_server = @hash[:disable_default_gem_server] if @hash.key? :disable_default_gem_server
  @sources                    = @hash[:sources]                    if @hash.key? :sources

  @ssl_verify_mode  = @hash[:ssl_verify_mode]  if @hash.key? :ssl_verify_mode
  @ssl_ca_cert      = @hash[:ssl_ca_cert]      if @hash.key? :ssl_ca_cert
  @ssl_client_cert  = @hash[:ssl_client_cert]  if @hash.key? :ssl_client_cert

  @api_keys         = nil
  @rubygems_api_key = nil

  handle_arguments arg_list
end

Instance Attribute Details

#args (readonly)

List of arguments supplied to the config file object.

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 95

attr_reader :args

#backtrace (rw)

True if the backtrace option has been specified, or debug is on.

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 373

def backtrace
  @backtrace or $DEBUG
end

#backtrace=(value) (rw)

True if we print backtraces on errors.

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 110

attr_writer :backtrace

#bulk_threshold (rw)

Bulk threshold value. If the number of missing gems are above this threshold value, then a bulk download technique is used. (deprecated)

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 116

attr_accessor :bulk_threshold

#disable_default_gem_server (rw)

True if we want to force specification of gem server when pushing a gem

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 134

attr_accessor :disable_default_gem_server

#hash (readonly, protected)

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 485

attr_reader :hash

#home (rw)

Where to install gems (deprecated)

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 105

attr_accessor :home

#path (rw)

Where to look for gems (deprecated)

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 100

attr_accessor :path

#rubygems_api_key (rw)

Returns the RubyGems.org API key

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 303

def rubygems_api_key
  load_api_keys unless @rubygems_api_key

  @rubygems_api_key
end

#rubygems_api_key=(api_key) (rw)

Sets the RubyGems.org API key to api_key

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 312

def rubygems_api_key= api_key
  set_api_key :rubygems_api_key, api_key

  @rubygems_api_key = api_key
end

#sources (rw)

sources to look for gems

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 148

attr_accessor :sources

#ssl_ca_cert (rw)

Path name of directory or file of openssl CA certificate, used for remote https connection

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 144

attr_accessor :ssl_ca_cert

#ssl_client_cert (readonly)

Path name of directory or file of openssl client certificate, used for remote https connection with client authentication

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 153

attr_reader :ssl_client_cert

#ssl_verify_mode (readonly)

openssl verify mode value, used for remote https connection

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 138

attr_reader :ssl_verify_mode

#update_sources (rw)

True if we want to update the SourceInfoCache every time, false otherwise

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 129

attr_accessor :update_sources

#verbose (rw)

Verbose level of output:

  • false – No output

  • true – Normal output

  • :loud – Extra output

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 124

attr_accessor :verbose

Instance Method Details

#==(other)

This method is for internal use only.
[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 476

def ==(other) # :nodoc:
  self.class === other and
    @backtrace == other.backtrace and
    @bulk_threshold == other.bulk_threshold and
    @verbose == other.verbose and
    @update_sources == other.update_sources and
    @hash == other.hash
end

#[](key)

Return the configuration information for key.

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 467

def [](key)
  @hash[key.to_s]
end

#[]=(key, value)

Set configuration option key to value.

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 472

def []=(key, value)
  @hash[key.to_s] = value
end

#api_keys

Hash of RubyGems.org and alternate API keys

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 238

def api_keys
  load_api_keys unless @api_keys

  @api_keys
end

#check_credentials_permissions

Checks the permissions of the credentials file. If they are not 0600 an error message is displayed and RubyGems aborts.

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 248

def check_credentials_permissions
  return if Gem.win_platform? # windows doesn't write 0600 as 0600
  return unless File.exist? credentials_path

  existing_permissions = File.stat(credentials_path).mode & 0777

  return if existing_permissions == 0600

  alert_error <<-ERROR
Your gem push credentials file located at:

\t#{credentials_path}

has file permissions of 0#{existing_permissions.to_s 8} but 0600 is required.

To fix this error run:

\tchmod 0600 #{credentials_path}

You should reset your credentials at:

\thttps://rubygems.org/profile/edit

if you believe they were disclosed to a third party.
  ERROR

  terminate_interaction 1
end

#config_file_name

The name of the configuration file.

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 378

def config_file_name
  @config_file_name || Gem.config_file
end

#credentials_path

Location of RubyGems.org credentials

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 280

def credentials_path
  File.join Gem.user_home, '.gem', 'credentials'
end

#each {|:update_sources, @update_sources| ... }

Delegates to @hash

Yields:

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 383

def each(&block)
  hash = @hash.dup
  hash.delete :update_sources
  hash.delete :verbose
  hash.delete :backtrace
  hash.delete :bulk_threshold

  yield :update_sources, @update_sources
  yield :verbose, @verbose
  yield :backtrace, @backtrace
  yield :bulk_threshold, @bulk_threshold

  yield 'config_file_name', @config_file_name if @config_file_name

  hash.each(&block)
end

#handle_arguments(arg_list)

Handle the command arguments.

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 401

def handle_arguments(arg_list)
  @args = []

  arg_list.each do |arg|
    case arg
    when /^--(backtrace|traceback)$/ then
      @backtrace = true
    when /^--debug$/ then
      $DEBUG = true

      warn 'NOTE:  Debugging mode prints all exceptions even when rescued'
    else
      @args << arg
    end
  end
end

#load_api_keys

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 284

def load_api_keys
  check_credentials_permissions

  @api_keys = if File.exist? credentials_path then
                load_file(credentials_path)
              else
                @hash
              end

  if @api_keys.key? :rubygems_api_key then
    @rubygems_api_key    = @api_keys[:rubygems_api_key]
    @api_keys[:rubygems] = @api_keys.delete :rubygems_api_key unless
      @api_keys.key? :rubygems
  end
end

#load_file(filename)

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 348

def load_file(filename)
  Gem.load_yaml

  yaml_errors = [ArgumentError]
  yaml_errors << Psych::SyntaxError if defined?(Psych::SyntaxError)

  return {} unless filename and File.exist? filename

  begin
    content = Gem::SafeYAML.load(File.read(filename))
    unless content.kind_of? Hash
      warn "Failed to load #{filename} because it doesn't contain valid YAML hash"
      return {}
    end
    return content
  rescue *yaml_errors => e
    warn "Failed to load #{filename}, #{e}"
  rescue Errno::EACCES
    warn "Failed to load #{filename} due to permissions problem."
  end

  {}
end

#really_verbose

Really verbose mode gives you extra output.

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 419

def really_verbose
  case verbose
  when true, false, nil then
    false
  else
    true
  end
end

#set_api_key(host, api_key)

Set a specific host's API key to api_key

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 321

def set_api_key host, api_key
  check_credentials_permissions

  config = load_file(credentials_path).merge(host => api_key)

  dirname = File.dirname credentials_path
  Dir.mkdir(dirname) unless File.exist? dirname

  Gem.load_yaml

  permissions = 0600 & (~File.umask)
  File.open(credentials_path, 'w', permissions) do |f|
    f.write config.to_yaml
  end

  load_api_keys # reload
end

#to_yaml

This method is for internal use only.

to_yaml only overwrites things you can't override on the command line.

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 429

def to_yaml # :nodoc:
  yaml_hash = {}
  yaml_hash[:backtrace] = @hash.fetch(:backtrace, DEFAULT_BACKTRACE)
  yaml_hash[:bulk_threshold] = @hash.fetch(:bulk_threshold, DEFAULT_BULK_THRESHOLD)
  yaml_hash[:sources] = Gem.sources.to_a
  yaml_hash[:update_sources] = @hash.fetch(:update_sources, DEFAULT_UPDATE_SOURCES)
  yaml_hash[:verbose] = @hash.fetch(:verbose, DEFAULT_VERBOSITY)

  yaml_hash[:ssl_verify_mode] =
    @hash[:ssl_verify_mode] if @hash.key? :ssl_verify_mode

  yaml_hash[:ssl_ca_cert] =
    @hash[:ssl_ca_cert] if @hash.key? :ssl_ca_cert

  yaml_hash[:ssl_client_cert] =
    @hash[:ssl_client_cert] if @hash.key? :ssl_client_cert

  keys = yaml_hash.keys.map { |key| key.to_s }
  keys << 'debug'
  re = Regexp.union(*keys)

  @hash.each do |key, value|
    key = key.to_s
    next if key =~ re
    yaml_hash[key.to_s] = value
  end

  yaml_hash.to_yaml
end

#unset_api_key!

Remove the ~/.gem/credentials file to clear all the current sessions.

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 342

def unset_api_key!
  return false unless File.exist?(credentials_path)

  File.delete(credentials_path)
end

#write

Writes out this config file, replacing its source.

[ GitHub ]

  
# File 'lib/rubygems/config_file.rb', line 460

def write
  File.open config_file_name, 'w' do |io|
    io.write to_yaml
  end
end