# encoding: UTF-8 # frozen_string_literal: true # Requirements # ======================================================================= # Stdlib # ----------------------------------------------------------------------- require 'pathname' # Deps # ----------------------------------------------------------------------- require 'nrser' require 'nrser/core_ext/object' # Project / Package # ----------------------------------------------------------------------- # Refinements # ======================================================================= require 'nrser/refinements/types' using NRSER::Types # Definitions # ======================================================================= # @todo document Locd::Config class. class Locd::Config # Constants # =================================================================== # Absolute path to the default config file (`//config/default.yml`). # # Has to be defined as a constant because no other config is loaded # before it and it contains the ENV var prefix. # # @return [Pathname] # DEFAULT_CONFIG_PATH = Locd::ROOT / 'config' / 'default.yml' # Absolute path to the dev override config, which will be loaded # last if it exists. # # @return [Pathname] # DEV_CONFIG_PATH = Locd::ROOT / 'dev' / 'config.yml' # What to split string keys into key path segments on. # # @return [String] # KEY_SEPARATOR = '.' # Attributes # ============================================================================ # Absolute path to the built-in default configuration file in use. # # @return [Pathname] # attr_reader :default_config_path # Constructor # =================================================================== # Instantiate a new `Locd::Config`. def initialize default_config_path: DEFAULT_CONFIG_PATH, dev_config_path: DEV_CONFIG_PATH @default_config_path = default_config_path.to_pn @dev_config_path = dev_config_path.to_pn @from_files = {} load_file default_config_path if user_config_path.exist? load_file user_config_path end if dev_config_path && dev_config_path.exist? load_file dev_config_path end end # #initialize # Instance Methods # =================================================================== protected # ======================================================================== # @todo Document load_file method. # # @param [type] arg_name # @todo Add name param description. # # @return [return_type] # @todo Document return value. # def load_file path bnd = binding path. to_pn. read. thru { |contents| YAML.load contents }. map_leaves { |path, leaf| case leaf when String bnd.erb leaf else leaf end }. thru { |tree| @from_files.deep_merge! tree } nil end # #load_file public # end protected *************************************************** def key_path_for *key key.flat_map { |k| k.to_s.split KEY_SEPARATOR } end def from_files *key, type: nil key_path = key_path_for *key value = @from_files.dig Locd::GEM_NAME, *key_path if value.nil? nil else parse_and_check value, type: type end end def env_key_for *key [ from_files( :namespace, :env, type: t.non_empty_str ), *key_path_for( *key ) ].join( '_' ).upcase end def parse_and_check value, type: nil return value if type.nil? if value.is_a?( String ) && type.has_from_s? type.from_s value else type.check value end end def from_env *key, type: nil env_key = env_key_for *key value = ENV[env_key] case value when nil, '' nil else parse_and_check value, type: type end end def get *key, type: nil, default: nil env_value = from_env *key, type: type return env_value unless env_value.nil? files_value = from_files *key, type: type return files_value unless files_value.nil? parse_and_check default, type: type end alias_method :[], :get def to_h @from_files.merge \ "locd" => @from_files["locd"].map_leaves { |key_path, value| env_value = from_env *key_path if env_value.nil? value else env_value end } end # @return [Pathname] # Absolute path to Loc'd home directory (it's workspace). # Directory may not exist, or may be something else like a file. # def home_dir self[:home, type: t.abs_path].to_pn end def log_dir self[ :log_dir, type: t.abs_path, default: (home_dir / 'log') ] end # @return [Pathname] # Absolute path to the user config file, which may not exist, but # will be loaded if it does. # def user_config_path home_dir / 'config.yml' end end # class Locd::Config