//  [ruby]
  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

  ##
  # Location of RubyGems.org credentials

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

  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

  ##
  # Returns the RubyGems.org API key

  def rubygems_api_key
    load_api_keys unless @rubygems_api_key

    @rubygems_api_key
  end

  ##
  # Sets the RubyGems.org API key to +api_key+

  def rubygems_api_key= api_key
    set_api_key :rubygems_api_key, api_key

    @rubygems_api_key = api_key
  end

  ##
  # Set a specific host's API key to +api_key+

  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

  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 = YAML.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

  # True if the backtrace option has been specified, or debug is on.
  def backtrace
    @backtrace or $DEBUG
  end

  # The name of the configuration file.
  def config_file_name
    @config_file_name || Gem.config_file
  end

  # Delegates to @hash
  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 the command arguments.
  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