Module: Gems::Configuration

Included in:
Gems
Defined in:
lib/gems/configuration.rb

Overview

Global configuration for Client instances

Constant Summary collapse

DEFAULT_HOST =

The API endpoint used when the RUBYGEMS_HOST environment variable is not set

"https://rubygems.org"
DEFAULT_USER_AGENT =

The default 'User-Agent' HTTP header

RequestBuilder::DEFAULT_USER_AGENT

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#debug_output ⇒ IO?

The IO object for debug output

Examples:

Get or set the debug output

Gems.debug_output = $stderr

Returns:

  • (IO, nil) —

    the IO object for debug output



172
173
174
# File 'lib/gems/configuration.rb', line 172

def debug_output
  @debug_output
end

#host ⇒ String

The host used for API requests

Examples:

Get the host

Gems.host

Returns:

  • (String) —

    the host, including scheme



33
34
35
# File 'lib/gems/configuration.rb', line 33

def host
  @host
end

#id_token ⇒ String?

The OIDC ID token used for trusted publishing

Examples:

Get or set the ID token

Gems.id_token = ENV.fetch("ID_TOKEN")

Returns:

  • (String, nil) —

    the OIDC ID token



40
41
42
# File 'lib/gems/configuration.rb', line 40

def id_token
  @id_token
end

#otp ⇒ String?

The one-time passcode used for multi-factor authentication

Falls back to #default_otp until a passcode is assigned. Assigning nil disables that fallback, so that requests are sent without a passcode.

Examples:

Get the one-time passcode

Gems.otp

Returns:

  • (String, nil) —

    the one-time passcode



293
294
295
# File 'lib/gems/configuration.rb', line 293

def otp
  otp_configured? ? @otp : default_otp
end

#password ⇒ String?

The password used for HTTP basic authentication

Examples:

Get or set the password

Gems.password = "schwwwwing"

Returns:

  • (String, nil) —

    the password



84
85
86
# File 'lib/gems/configuration.rb', line 84

def password
  @password
end

#proxy_url ⇒ String?

The proxy URL for requests

When nil, proxies are read from the http_proxy, https_proxy, and no_proxy environment variables.

Examples:

Get the proxy URL

Gems.proxy_url

Returns:

  • (String, nil) —

    the proxy URL for requests



182
183
184
# File 'lib/gems/configuration.rb', line 182

def proxy_url
  @proxy_url
end

#user_agent ⇒ String

The 'User-Agent' HTTP header sent with requests

Examples:

Get or set the user agent

Gems.user_agent = "Custom User Agent"

Returns:

  • (String) —

    the user agent



91
92
93
# File 'lib/gems/configuration.rb', line 91

def user_agent
  @user_agent
end

#username ⇒ String?

The username used for HTTP basic authentication

Examples:

Get or set the username

Gems.username = "[email protected]"

Returns:

  • (String, nil) —

    the username



98
99
100
# File 'lib/gems/configuration.rb', line 98

def username
  @username
end

Instance Method Details

#configure {|self| ... } ⇒ self

Convenience method to allow configuration options to be set in a block

Examples:

Configure the API key

Gems.configure do |config|
  config.key = "rubygems_701243f217cdf23b1370c7b66b65ca97"
end

Yields:

  • (self) —

    the configuration

Returns:

  • (self)


407
408
409
410
# File 'lib/gems/configuration.rb', line 407

def configure
  yield self
  self
end

#default_host ⇒ String

The host gem push would use

This is the RUBYGEMS_HOST environment variable, else RubyGems.org. The environment is read when this method is called, as it is for #default_key, rather than when the library is required.

Examples:

Get the default host

Gems.default_host

Returns:

  • (String) —

    the host, including scheme



306
307
308
# File 'lib/gems/configuration.rb', line 306

def default_host
  ENV.fetch("RUBYGEMS_HOST", DEFAULT_HOST)
end

#default_key(gem_host = host) ⇒ String?

The API key gem push would use for a host

This is the GEM_HOST_API_KEY environment variable, else the key gem signin --host stored for the host in ~/.gem/credentials, else, for RubyGems.org itself, the key gem signin stored there. The environment is read each time this method is called, rather than when the library is required, and the credentials file is read the first time it is needed: RubyGems keeps what it read in Gem.configuration, which it shares with everything else running in the process, so a key gem signin stores afterwards is picked up only by a new process.

A host nothing is stored for is left without a key, where gem push --host falls back to the RubyGems.org key for it. RubyGems keeps the key of RubyGems.org under rubygems_api_key rather than under its URL, and the key of every other host under the URL gem signin --host stored it for, so that key is the key of RubyGems.org rather than one for whichever host is asked about: handing it to another host would send a credential RubyGems.org issued to a host it was not issued for. The host is read as a URL, so RubyGems.org named with a trailing slash or a path of its own is still the host the key was stored for, and a host that is not a URL at all is not.

An empty GEM_HOST_API_KEY counts as no key rather than as an empty one, since a continuous integration service sets a variable to the empty string when the secret it was given is not set, and an empty Authorization header answers with a puzzling 401 where a request without one answers with the error the endpoint has for an unauthenticated request.

When the credentials file does not have the permissions RubyGems requires, RubyGems reports the problem on standard error and would exit the process; this method returns nil instead.

Examples:

Get the default API key

Gems.default_key

Get the default API key for another host

Gems.default_key("https://gems.example.com")

Parameters:

  • gem_host (String) (defaults to: host) —

    the host to resolve the key for, which defaults to #host

Returns:

  • (String, nil) —

    the API key, or nil when none is stored or the credentials file cannot be read



342
343
344
345
346
347
348
349
350
351
# File 'lib/gems/configuration.rb', line 342

def default_key(gem_host = host)
  env_key = ENV.fetch("GEM_HOST_API_KEY", "")
  return env_key unless env_key.empty?

  ::Gem.configuration.api_keys.fetch(gem_host) do
    ::Gem.configuration.rubygems_api_key if http_url?(gem_host) && same_origin?(gem_host, DEFAULT_HOST)
  end
rescue ::Gem::SystemExitException
  nil
end

#default_otp ⇒ String?

The one-time passcode gem push would use

This is the GEM_HOST_OTP_CODE environment variable, which gem push falls back to when it is not given a passcode of its own. The environment is read when this method is called, as it is for #default_key, rather than when the library is required.

An empty GEM_HOST_OTP_CODE counts as no passcode rather than as an empty one, as an empty GEM_HOST_API_KEY counts as no key, since a continuous integration service sets a variable to the empty string when the secret it was given is not set, and an empty OTP header is refused where a request without one is answered with the error the endpoint has for a request that needs a passcode.

Examples:

Get the default one-time passcode

Gems.default_otp

Returns:

  • (String, nil) —

    the one-time passcode, or nil when the environment does not carry one



368
369
370
371
# File 'lib/gems/configuration.rb', line 368

def default_otp
  code = ENV.fetch("GEM_HOST_OTP_CODE", "")
  code unless code.empty?
end

#keep_alive_timeout ⇒ Numeric

The seconds an idle connection is kept open for another request

Zero closes every connection when its request is done.

Examples:

Get the keep-alive timeout

Gems.keep_alive_timeout

Returns:

  • (Numeric) —

    the seconds an idle connection is kept open



165
# File 'lib/gems/configuration.rb', line 165

seconds_setting :keep_alive_timeout

#keep_alive_timeout=(keep_alive_timeout) ⇒ void

This method returns an undefined value.

Set the seconds an idle connection is kept open for another request

Examples:

Set the keep-alive timeout

Gems.keep_alive_timeout = 0

Parameters:

  • keep_alive_timeout (Numeric) —

    the seconds an idle connection is kept open

Raises:

  • (ArgumentError) —

    if it is not a number of seconds, in which case the timeout is left as it was



165
# File 'lib/gems/configuration.rb', line 165

seconds_setting :keep_alive_timeout

#key ⇒ String?

The API key used for authentication

Falls back to #default_key until a key is assigned. Assigning nil disables this API-key fallback. Basic authentication and trusted publishing remain available when their credentials are configured.

Examples:

Get the API key

Gems.key

Returns:

  • (String, nil) —

    the API key



280
281
282
# File 'lib/gems/configuration.rb', line 280

def key
  key_configured? ? @key : default_key
end

#key=(key) ⇒ void

This method returns an undefined value.

Set the API key used for authentication

Examples:

Set the API key

Gems.key = "rubygems_701243f217cdf23b1370c7b66b65ca97"

Set the API key from a newly created API key

Gems.key = Gems.create_api_key("ci-push", scopes: %i[push_rubygem])

Parameters:

  • key (String, APIKey, nil) —

    the API key, or an API key object



66
67
68
# File 'lib/gems/configuration.rb', line 66

def key=(key)
  @key = key_of(key)
end

#key_configured? ⇒ Boolean

Whether an API key has been assigned, rather than falling back to #default_key

A client built without a key of its own asks this to tell a configured key, which it sends wherever it sends a request, from the fallback it resolves for the host of each request.

Examples:

Tell a configured key from the one resolved for the host

Gems.key_configured?

Returns:

  • (Boolean) —

    whether an API key has been assigned



382
383
384
# File 'lib/gems/configuration.rb', line 382

def key_configured?
  instance_variable_defined?(:@key)
end

#max_redirects ⇒ Integer

The maximum number of redirects to follow

Examples:

Get the maximum redirects

Gems.max_redirects

Returns:

  • (Integer) —

    the maximum number of redirects to follow



215
# File 'lib/gems/configuration.rb', line 215

count_setting :max_redirects

#max_redirects=(max_redirects) ⇒ void

This method returns an undefined value.

Set the maximum number of redirects to follow

Examples:

Set the maximum redirects

Gems.max_redirects = 5

Parameters:

  • max_redirects (Integer) —

    the maximum number of redirects to follow

Raises:

  • (ArgumentError) —

    if it is not a whole number of times, in which case the maximum is left as it was



215
# File 'lib/gems/configuration.rb', line 215

count_setting :max_redirects

#max_retries ⇒ Integer

The number of times a request that was turned away is sent again

Two by default. Zero raises TooManyRequests, BadGateway, ServiceUnavailable, GatewayTimeout, or NetworkError rather than waiting. A 429 sends any request again, since a rate limiter answers it before the request reaches the endpoint, so a push that was rate limited is sent again; a 502, 503, 504, or NetworkError sends only a request that reads again, since a request that acts on a gem may have been acted on by the origin before the answer went missing. The trusted publishing token exchange is the exception: it is sent again when the endpoint answers it with no key or the network loses it, although it is a POST.

Examples:

Get the maximum retries

Gems.max_retries

Returns:

  • (Integer) —

    the number of times a request that was turned away is sent again



240
# File 'lib/gems/configuration.rb', line 240

count_setting :max_retries

#max_retries=(max_retries) ⇒ void

This method returns an undefined value.

Set the number of times a request that was turned away is sent again

Examples:

Set the maximum retries

Gems.max_retries = 3

Parameters:

  • max_retries (Integer) —

    the number of times a request that was turned away is sent again

Raises:

  • (ArgumentError) —

    if it is not a whole number of times, in which case the maximum is left as it was



240
# File 'lib/gems/configuration.rb', line 240

count_setting :max_retries

#max_retry_delay ⇒ Numeric

The longest a request waits before it is sent again, in seconds

A response asking to wait longer than this raises rather than being waited for.

Examples:

Get the maximum retry delay

Gems.max_retry_delay

Returns:

  • (Numeric) —

    the longest a request waits before it is sent again, in seconds



259
# File 'lib/gems/configuration.rb', line 259

seconds_setting :max_retry_delay

#max_retry_delay=(max_retry_delay) ⇒ void

This method returns an undefined value.

Set the longest a request waits before it is sent again, in seconds

Examples:

Set the maximum retry delay

Gems.max_retry_delay = 30

Parameters:

  • max_retry_delay (Numeric) —

    the longest a request waits before it is sent again, in seconds

Raises:

  • (ArgumentError) —

    if it is not a number of seconds, in which case the maximum is left as it was



259
# File 'lib/gems/configuration.rb', line 259

seconds_setting :max_retry_delay

#open_timeout ⇒ Numeric

The timeout for opening connections in seconds

Examples:

Get the open timeout

Gems.open_timeout

Returns:

  • (Numeric) —

    the timeout for opening connections in seconds



114
# File 'lib/gems/configuration.rb', line 114

seconds_setting :open_timeout

#open_timeout=(open_timeout) ⇒ void

This method returns an undefined value.

Set the timeout for opening connections in seconds

Examples:

Set the open timeout

Gems.open_timeout = 30

Parameters:

  • open_timeout (Numeric) —

    the timeout for opening connections in seconds

Raises:

  • (ArgumentError) —

    if it is not a number of seconds, in which case the timeout is left as it was



114
# File 'lib/gems/configuration.rb', line 114

seconds_setting :open_timeout

#otp_configured? ⇒ Boolean

Whether a one-time passcode has been assigned

When none has been, #otp falls back to #default_otp.

Examples:

Tell a configured passcode from the one the environment carries

Gems.otp_configured?

Returns:

  • (Boolean) —

    whether a one-time passcode has been assigned



394
395
396
# File 'lib/gems/configuration.rb', line 394

def otp_configured?
  instance_variable_defined?(:@otp)
end

#read_timeout ⇒ Numeric

The timeout for reading responses in seconds

Examples:

Get the read timeout

Gems.read_timeout

Returns:

  • (Numeric) —

    the timeout for reading responses in seconds



130
# File 'lib/gems/configuration.rb', line 130

seconds_setting :read_timeout

#read_timeout=(read_timeout) ⇒ void

This method returns an undefined value.

Set the timeout for reading responses in seconds

Examples:

Set the read timeout

Gems.read_timeout = 30

Parameters:

  • read_timeout (Numeric) —

    the timeout for reading responses in seconds

Raises:

  • (ArgumentError) —

    if it is not a number of seconds, in which case the timeout is left as it was



130
# File 'lib/gems/configuration.rb', line 130

seconds_setting :read_timeout

#reset ⇒ self

Reset all configuration options to defaults

The default host is the one gem push would use, which is taken as it is rather than checked the way a host assigned to #host= is, so that a RUBYGEMS_HOST that is not a URL is reported when a client is built with it rather than when the library is required.

Examples:

Reset the configuration

Gems.reset

Returns:

  • (self)


422
423
424
425
426
427
428
429
# File 'lib/gems/configuration.rb', line 422

def reset
  @host = default_host
  self.user_agent = DEFAULT_USER_AGENT
  reset_credentials
  reset_connection
  reset_certificates
  self
end

#write_timeout ⇒ Numeric

The timeout for writing requests in seconds

Examples:

Get the write timeout

Gems.write_timeout

Returns:

  • (Numeric) —

    the timeout for writing requests in seconds



146
# File 'lib/gems/configuration.rb', line 146

seconds_setting :write_timeout

#write_timeout=(write_timeout) ⇒ void

This method returns an undefined value.

Set the timeout for writing requests in seconds

Examples:

Set the write timeout

Gems.write_timeout = 30

Parameters:

  • write_timeout (Numeric) —

    the timeout for writing requests in seconds

Raises:

  • (ArgumentError) —

    if it is not a number of seconds, in which case the timeout is left as it was



146
# File 'lib/gems/configuration.rb', line 146

seconds_setting :write_timeout