class Google::Cloud::Config
config.sub.opt9 #=> nil (warning about unknown key)
config.opt9 #=> “hi” (no warning: key now known)
config.opt9 = “hi” #=> “hi” (warning about unknown key)
config.sub.opt5 = nil #=> nil (but prints a warning)
config.sub.opt5 #=> true
config.sub.opt5 = true #=> true (true and false allowed)
config.sub.opt5 #=> false
config.sub #=> <Google::Cloud::Config>
config.opt4 = nil #=> nil (no warning: nil allowed)
config.opt4 = 3.14 #=> 3.14 (but prints a warning)
config.opt4 #=> :yo
config.opt4 = :yo #=> :yo (Strings and Symbols allowed)
config.opt4 #=> “yo”
config.opt3 = “HI” #=> “HI” (but prints a warning)
config.opt3 #=> “hiho”
config.opt3 = “hiho” #=> “hiho”
config.opt3 #=> “hi”
config.opt2 = :four #=> :four (but prints a warning)
config.opt2 #=> :two
config.opt2 = :two #=> :two
config.opt2 #=> :one
config.opt1 = nil #=> nil (but prints a warning)
config.opt1 = “hi” #=> “hi” (but prints a warning)
config.opt1 #=> 20
config.opt1 = 20 #=> 20
config.opt1 #=> 10
end
end
c2.add_field! :opt5, false
c.add_config! :sub do |c2|
c.add_field! :opt4, “hi”, match: /^[a-z]+$/, allow_nil: true
c.add_field! :opt3, “hi”, match: [String, Symbol]
c.add_field! :opt2, :one, enum: [:one, :two, :three]
c.add_field! :opt1, 10
config = Google::Cloud::Config.create do |c|
require “google/cloud/config”
@example
forth.
For example, ‘to_s`, `inspect`, `is_a?`, `instance_variable_get`, and so
not define many methods you might expect to find in most Ruby objects.
Note that config objects inherit from `BasicObject`. This means it does
It is also possible to access a field using the `[]` operator.
with a trailing “!” or “?” so they don’t pollute the method namespace.
Methods meant for “administration” such as adding options, are named
You generally access fields and subconfigs by calling accessor methods.
printed when a validation fails.
a value is set, it is validated for the correct type. Warnings are
generally validated to ensure that the field is defined, and when a
of which are subconfigurations, i.e. categories. Field access is
contains a list of predefined keys, some of which are values and others
Configuration mechanism for Google Cloud libraries. A Config object
#
def self.config? obj
-
(boolean)
-
def self.config? obj Config.send :===, obj end
def self.create show_warnings: true
-
(Config)
- The constructed Config object.
Parameters:
-
show_warnings
(boolean
) -- Whether to print warnings when a
def self.create show_warnings: true config = new [], show_warnings: show_warnings yield config if block_given? config end
def self.credentials_from_env *vars
- Private: -
def self.credentials_from_env *vars vars.each do |var| data = ::ENV[var] next unless data str = data.strip return str if ::File.file? str json = begin ::JSON.parse str rescue ::StandardError nil end return json if json.is_a? ::Hash end nil end
def self.deferred &block
- Private: -
def self.deferred &block DeferredValue.new(&block) end
def [] key
-
(Object)
- The option value or subconfig object
Parameters:
-
key
(Symbol, String
) -- The option or subconfig name
def [] key key = resolve_key! key unless @validators.key? key warn! "Key #{key.inspect} does not exist. Returning nil." end value = @values[key] value = value.call if Config::DeferredValue === value value end
def []= key, value
-
value
(Object
) -- The new option value -
key
(Symbol, String
) -- The option name
def []= key, value key = resolve_key! key validate_value! key, @validators[key], value @values[key] = value end
def add_alias! key, to_key
the same field.
Cause a key to be an alias of another key. The two keys will refer to
#
def add_alias! key, to_key key = validate_new_key! key @values.delete key @defaults.delete key @validators[key] = to_key.to_sym self end
def add_config! key, config = nil, &block
-
(Config)
- self for chaining
Parameters:
-
config
(Config
) -- A config object to attach here. If not provided, -
key
(String, Symbol
) -- The name of the subconfig
def add_config! key, config = nil, &block key = validate_new_key! key if config.nil? config = Config.create(&block) elsif block yield config end @values[key] = config @defaults[key] = config @validators[key] = SUBCONFIG self end
def add_field! key, initial = nil, opts = {}, &block
-
(Config)
- self for chaining
Parameters:
-
opts
(Hash
) -- Validation options -
initial
(Object
) -- Initial value (defaults to nil) -
key
(String, Symbol
) -- The name of the option
def add_field! key, initial = nil, opts = {}, &block key = validate_new_key! key opts[:validator] = block if block validator = resolve_validator! initial, opts validate_value! key, validator, initial @values[key] = initial @defaults[key] = initial @validators[key] = validator self end
def add_options legacy_categories
- Private: -
Deprecated:
def add_options legacy_categories [legacy_categories].flatten(1).each do |sub_key| case sub_key when ::Symbol add_config! sub_key, Config.new when ::Hash sub_key.each do |k, v| add_config! k, Config.new(v) end else raise ArgumentError "Category must be a Symbol or Hash" end end end
def alias? key
-
(Symbol, nil)
- The alias target, or nil if not an alias.
Parameters:
-
key
(Symbol
) -- The key to check for.
def alias? key target = @validators[key.to_sym] target.is_a?(::Symbol) ? target : nil end
def aliases!
-
(Array
- a list of alias names as symbols.)
def aliases! @validators.keys.find_all { |key| @validators[key].is_a? ::Symbol } end
def build_enum_validator! allowed, allow_nil
def build_enum_validator! allowed, allow_nil allowed = ::Kernel.Array(allowed) allowed += [nil] if allow_nil && !allowed.include?(nil) ->(val) { allowed.include? val } end
def build_match_validator! matches, allow_nil
def build_match_validator! matches, allow_nil matches = ::Kernel.Array(matches) matches += [nil] if allow_nil && !matches.include?(nil) ->(val) { matches.any? { |m| m.send :===, val } } end
def build_proc_validator! proc, allow_nil
def build_proc_validator! proc, allow_nil ->(val) { proc.call(val) || (allow_nil && val.nil?) } end
def delete! key = nil
-
key
(Symbol, nil
) -- The key to delete. If omitted or `nil`,
def delete! key = nil if key.nil? @values.clear @defaults.clear @validators.clear else @values.delete key @defaults.delete key @validators.delete key end self end
def field? key
-
(boolean)
-
Parameters:
-
key
(Symbol
) -- The key to check for.
def field? key @validators[key.to_sym].is_a? ::Proc end
def fields!
-
(Array
- a list of field names as symbols.)
def fields! @validators.keys.find_all { |key| @validators[key].is_a? ::Proc } end
def initialize legacy_categories = {}, opts = {}
- Private: -
def initialize legacy_categories = {}, opts = {} @show_warnings = opts.fetch :show_warnings, false @values = {} @defaults = {} @validators = {} add_options legacy_categories end
def method_missing name, *args
- Private: -
def method_missing name, *args name_str = name.to_s super unless name_str =~ /^[a-zA-Z]\w*=?$/ if name_str.chomp! "=" self[name_str] = args.first else self[name] end end
def nil?
-
(false)
-
Other tags:
- Private: -
def nil? false end
def reset! key = nil
-
key
(Symbol, nil
) -- The key to reset. If omitted or `nil`,
def reset! key = nil if key.nil? @values.each_key { |k| reset! k } else key = key.to_sym if @defaults.key? key @values[key] = @defaults[key] @values[key].reset! if @validators[key] == SUBCONFIG elsif @values.key? key warn! "Key #{key.inspect} has not been added, but has a value." \ " Removing the value." @values.delete key else warn! "Key #{key.inspect} does not exist. Nothing to reset." end end self end
def resolve_key! key
def resolve_key! key key = key.to_sym alias_target = @validators[key] alias_target.is_a?(::Symbol) ? alias_target : key end
def resolve_validator! initial, opts
def resolve_validator! initial, opts allow_nil = initial.nil? || opts[:allow_nil] if opts.key? :validator build_proc_validator! opts[:validator], allow_nil elsif opts.key? :match build_match_validator! opts[:match], allow_nil elsif opts.key? :enum build_enum_validator! opts[:enum], allow_nil elsif [true, false].include? initial build_enum_validator! [true, false], allow_nil elsif initial.nil? OPEN_VALIDATOR else klass = Config.config?(initial) ? Config : initial.class build_match_validator! klass, allow_nil end end
def respond_to_missing? name, include_private
- Private: -
def respond_to_missing? name, include_private return true if value_set? name.to_s.chomp("=") super end
def subconfig? key
-
(boolean)
-
Parameters:
-
key
(Symbol
) -- The key to check for.
def subconfig? key @validators[key.to_sym] == SUBCONFIG end
def subconfigs!
-
(Array
- a list of subconfig names as symbols.)
def subconfigs! @validators.keys.find_all { |key| @validators[key] == SUBCONFIG } end
def to_h!
-
(Hash)
-
def to_h! h = {} @validators.each_key do |k| v = @values[k] h[k] = Config.config?(v) ? v.to_h! : v.inspect end h end
def to_s!
-
(String)
-
def to_s! elems = @validators.keys.map do |k| v = @values[k] vstr = Config.config?(v) ? v.to_s! : value.inspect " #{k}=#{vstr}" end "<Config:#{elems.join}>" end
def validate_new_key! key
def validate_new_key! key key_str = key.to_s key = key.to_sym if key_str !~ /^[a-zA-Z]\w*$/ || ILLEGAL_KEYS.include?(key) warn! "Illegal key name: #{key_str.inspect}. Method dispatch will" \ " not work for this key." end if @validators.key? key warn! "Key #{key.inspect} already exists. It will be replaced." end key end
def validate_value! key, validator, value
def validate_value! key, validator, value value = value.call if Config::DeferredValue === value case validator when ::Proc unless validator.call value warn! "Invalid value #{value.inspect} for key #{key.inspect}." \ " Setting anyway." end when Config if value != validator warn! "Key #{key.inspect} refers to a subconfig and shouldn't" \ " be changed. Setting anyway." end else warn! "Key #{key.inspect} has not been added. Setting anyway." end end
def value_set? key
-
(boolean)
-
Parameters:
-
key
(Symbol
) -- The key to check for.
def value_set? key @values.key? resolve_key! key end
def warn! msg
def warn! msg return unless @show_warnings location = ::Kernel.caller_locations.find do |s| !s.to_s.include? "/google/cloud/config.rb:" end ::Kernel.warn "#{msg} at #{location}" end