# frozen_string_literal: true#--# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.# All rights reserved.# See LICENSE.txt for permissions.#++require'rubygems/user_interaction'require'rbconfig'### Gem::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 <tt>gem:</tt> to set default arguments for all commands.## RubyGems options use symbol keys. Valid options are:## +:backtrace+:: See #backtrace# +:sources+:: Sets Gem::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)classGem::ConfigFileincludeGem::UserInteractionDEFAULT_BACKTRACE=falseDEFAULT_BULK_THRESHOLD=1000DEFAULT_VERBOSITY=trueDEFAULT_UPDATE_SOURCES=true### For Ruby packagers to set configuration defaults. Set in# rubygems/defaults/operating_system.rbOPERATING_SYSTEM_DEFAULTS={}### For Ruby implementers to set configuration defaults. Set in# rubygems/defaults/#{RUBY_ENGINE}.rbPLATFORM_DEFAULTS={}# :stopdoc:SYSTEM_CONFIG_PATH=beginrequire"etc"Etc.sysconfdirrescueLoadError,NoMethodErrorbegin# TODO: remove after we drop 1.8.7 and 1.9.1require'Win32API'CSIDL_COMMON_APPDATA=0x0023path=0.chr*260ifRUBY_VERSION>'1.9'thenSHGetFolderPath=Win32API.new'shell32','SHGetFolderPath','PLPLP','L',:stdcallSHGetFolderPath.callnil,CSIDL_COMMON_APPDATA,nil,1,pathelseSHGetFolderPath=Win32API.new'shell32','SHGetFolderPath','LLLLP','L'SHGetFolderPath.call0,CSIDL_COMMON_APPDATA,0,1,pathendpath.striprescueLoadErrorRbConfig::CONFIG["sysconfdir"]||"/etc"endend# :startdoc:SYSTEM_WIDE_CONFIG_FILE=File.joinSYSTEM_CONFIG_PATH,'gemrc'### List of arguments supplied to the config file object.attr_reader:args### Where to look for gems (deprecated)attr_accessor:path### Where to install gems (deprecated)attr_accessor:home### True if we print backtraces on errors.attr_writer:backtrace### Bulk threshold value. If the number of missing gems are above this# threshold value, then a bulk download technique is used. (deprecated)attr_accessor:bulk_threshold### Verbose level of output:# * false -- No output# * true -- Normal output# * :loud -- Extra outputattr_accessor:verbose### True if we want to update the SourceInfoCache every time, false otherwiseattr_accessor:update_sources### True if we want to force specification of gem server when pushing a gemattr_accessor:disable_default_gem_server# openssl verify mode value, used for remote https connectionattr_reader:ssl_verify_mode### Path name of directory or file of openssl CA certificate, used for remote# https connectionattr_accessor:ssl_ca_cert### Path name of directory or file of openssl client certificate, used for remote https connection with client authenticationattr_reader:ssl_client_cert### 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.## <tt>--config-file</tt>, <tt>--config-file==NAME</tt>::# Obviously these need to be handled by the ConfigFile object to ensure we# get the right config file.## <tt>--backtrace</tt>::# Backtrace needs to be turned on early so that errors before normal# option parsing can be properly handled.## <tt>--debug</tt>::# Enable Ruby level debug messages. Handled early for the same reason as# --backtrace.#--# TODO: parse options upstream, pass in options directlydefinitialize(args)@config_file_name=nilneed_config_file_name=falsearg_list=[]args.eachdo|arg|ifneed_config_file_namethen@config_file_name=argneed_config_file_name=falseelsifarg=~/^--config-file=(.*)/then@config_file_name=$1elsifarg=~/^--config-file$/thenneed_config_file_name=trueelsearg_list<<argendend@backtrace=DEFAULT_BACKTRACE@bulk_threshold=DEFAULT_BULK_THRESHOLD@verbose=DEFAULT_VERBOSITY@update_sources=DEFAULT_UPDATE_SOURCESoperating_system_config=Marshal.loadMarshal.dump(OPERATING_SYSTEM_DEFAULTS)platform_config=Marshal.loadMarshal.dump(PLATFORM_DEFAULTS)system_config=load_fileSYSTEM_WIDE_CONFIG_FILEuser_config=load_fileconfig_file_name.dup.untaintenvironment_config=(ENV['GEMRC']||'').split(/[:;]/).inject({})do|result,file|result.mergeload_filefileend@hash=operating_system_config.mergeplatform_configunlessarg_list.index'--norc'@hash=@hash.mergesystem_config@hash=@hash.mergeuser_config@hash=@hash.mergeenvironment_configend# 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@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=nilGem.sources=@hash[:sources]if@hash.key?:sourceshandle_argumentsarg_listend### Hash of RubyGems.org and alternate API keysdefapi_keysload_api_keysunless@api_keys@api_keysend### Checks the permissions of the credentials file. If they are not 0600 an# error message is displayed and RubyGems aborts.defcheck_credentials_permissionsreturnifGem.win_platform?# windows doesn't write 0600 as 0600returnunlessFile.exist?credentials_pathexisting_permissions=File.stat(credentials_path).mode&0777returnifexisting_permissions==0600alert_error<<-ERROR
Your gem push credentials file located at:
\t#{credentials_path}
has file permissions of 0#{existing_permissions.to_s8} 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.
ERRORterminate_interaction1end### Location of RubyGems.org credentialsdefcredentials_pathFile.joinGem.user_home,'.gem','credentials'enddefload_api_keyscheck_credentials_permissions@api_keys=ifFile.exist?credentials_paththenload_file(credentials_path)else@hashendif@api_keys.key?:rubygems_api_keythen@rubygems_api_key=@api_keys[:rubygems_api_key]@api_keys[:rubygems]=@api_keys.delete:rubygems_api_keyunless@api_keys.key?:rubygemsendend### Returns the RubyGems.org API keydefrubygems_api_keyload_api_keysunless@rubygems_api_key@rubygems_api_keyend### Sets the RubyGems.org API key to +api_key+defrubygems_api_key=api_keyset_api_key:rubygems_api_key,api_key@rubygems_api_key=api_keyend### Set a specific host's API key to +api_key+defset_api_keyhost,api_keycheck_credentials_permissionsconfig=load_file(credentials_path).merge(host=>api_key)dirname=File.dirnamecredentials_pathDir.mkdir(dirname)unlessFile.exist?dirnameGem.load_yamlpermissions=0600&(~File.umask)File.open(credentials_path,'w',permissions)do|f|f.writeconfig.to_yamlendload_api_keys# reloadenddefload_file(filename)Gem.load_yamlyaml_errors=[ArgumentError]yaml_errors<<Psych::SyntaxErrorifdefined?(Psych::SyntaxError)return{}unlessfilenameandFile.exist?filenamebegincontent=YAML.load(File.read(filename))unlesscontent.kind_of?Hashwarn"Failed to load #{filename} because it doesn't contain valid YAML hash"return{}endreturncontentrescue*yaml_errors=>ewarn"Failed to load #{filename}, #{e}"rescueErrno::EACCESwarn"Failed to load #{filename} due to permissions problem."end{}end# True if the backtrace option has been specified, or debug is on.defbacktrace@backtraceor$DEBUGend# The name of the configuration file.defconfig_file_name@config_file_name||Gem.config_fileend# Delegates to @hashdefeach(&block)hash=@hash.duphash.delete:update_sourceshash.delete:verbosehash.delete:backtracehash.delete:bulk_thresholdyield:update_sources,@update_sourcesyield:verbose,@verboseyield:backtrace,@backtraceyield:bulk_threshold,@bulk_thresholdyield'config_file_name',@config_file_nameif@config_file_namehash.each(&block)end# Handle the command arguments.defhandle_arguments(arg_list)@args=[]arg_list.eachdo|arg|caseargwhen/^--(backtrace|traceback)$/then@backtrace=truewhen/^--debug$/then$DEBUG=truewarn'NOTE: Debugging mode prints all exceptions even when rescued'else@args<<argendendend# Really verbose mode gives you extra output.defreally_verbosecaseverbosewhentrue,false,nilthenfalseelsetrueendend# to_yaml only overwrites things you can't override on the command line.defto_yaml# :nodoc:yaml_hash={}yaml_hash[:backtrace]=if@hash.key?(:backtrace)@hash[:backtrace]elseDEFAULT_BACKTRACEendyaml_hash[:bulk_threshold]=if@hash.key?(:bulk_threshold)@hash[:bulk_threshold]elseDEFAULT_BULK_THRESHOLDendyaml_hash[:sources]=Gem.sources.to_ayaml_hash[:update_sources]=if@hash.key?(:update_sources)@hash[:update_sources]elseDEFAULT_UPDATE_SOURCESendyaml_hash[:verbose]=if@hash.key?(:verbose)@hash[:verbose]elseDEFAULT_VERBOSITYendyaml_hash[:ssl_verify_mode]=@hash[:ssl_verify_mode]if@hash.key?:ssl_verify_modeyaml_hash[:ssl_ca_cert]=@hash[:ssl_ca_cert]if@hash.key?:ssl_ca_certyaml_hash[:ssl_client_cert]=@hash[:ssl_client_cert]if@hash.key?:ssl_client_certkeys=yaml_hash.keys.map{|key|key.to_s}keys<<'debug're=Regexp.union(*keys)@hash.eachdo|key,value|key=key.to_snextifkey=~reyaml_hash[key.to_s]=valueendyaml_hash.to_yamlend# Writes out this config file, replacing its source.defwriteopenconfig_file_name,'w'do|io|io.writeto_yamlendend# Return the configuration information for +key+.def[](key)@hash[key.to_s]end# Set configuration option +key+ to +value+.def[]=(key,value)@hash[key.to_s]=valueenddef==(other)# :nodoc:self.class===otherand@backtrace==other.backtraceand@bulk_threshold==other.bulk_thresholdand@verbose==other.verboseand@update_sources==other.update_sourcesand@hash==other.hashendattr_reader:hashprotected:hashend