Class: Locd::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/locd/config.rb,
lib/locd/config/types.rb

Overview

A hash-like container providing access to a layered tree of config values sourced from YAML files and ENV vars.

Keys

Config keys are arrays of strings that

Defined Under Namespace

Modules: Types

Constant Summary collapse

DEFAULT_CONFIG_PATH =

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.

Returns:

  • (Pathname)
Locd::ROOT / 'config' / 'default.yml'
DEV_CONFIG_PATH =

Absolute path to the dev override config, which will be loaded last if it exists.

Returns:

  • (Pathname)
Locd::ROOT / 'dev' / 'config.yml'
KEY_SEPARATOR =

What to split string keys into key path segments on.

Returns:

  • (String)
'.'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(default_config_path: DEFAULT_CONFIG_PATH, dev_config_path: DEV_CONFIG_PATH) ⇒ Config

Instantiate a new Locd::Config.



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/locd/config.rb', line 83

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

Instance Attribute Details

#default_config_pathPathname (readonly)

Absolute path to the built-in default configuration file in use.

Returns:

  • (Pathname)


76
77
78
# File 'lib/locd/config.rb', line 76

def default_config_path
  @default_config_path
end

Class Method Details

.key_path_for(*key) ⇒ Object



128
129
130
# File 'lib/locd/config.rb', line 128

def self.key_path_for *key
  key.flat_map { |k| k.to_s.split KEY_SEPARATOR }
end

Instance Method Details

#[]=(*key, value) ⇒ Object

Proxy to #set orthogonal to #[] / #get (though in this case we need to do a little more work than an alias on account of how #[]= handled keyword args).

Examples:

Single string key

Locd.config[ 'cli.bash_comp.log.level' ] = :debug

List key

Locd.config[ :cli, :bash_comp, :log, :level ] = :debug

Checking the type

Locd.config[ 'home', type: t.abs_path ] = user_input


224
225
226
227
228
229
230
231
232
233
# File 'lib/locd/config.rb', line 224

def []= *key, value
  if Hash === key[-1]
    kwds = key[-1]
    key = key[0..-2]
  else
    kwds = {}
  end
  
  set *key, value, **kwds
end

#cli_ARGV_looks_like_bash_comp?Boolean

Does ARGV look like we're executing Bash completion?

We want to change how we're logging during Bash completion runs.

Returns:

  • (Boolean)


283
284
285
# File 'lib/locd/config.rb', line 283

def cli_ARGV_looks_like_bash_comp?
  ARGV[0] == 'bash-complete'
end

#cli_log_configHash<Symbol, ] @todo Document return value.

Get the logging config, taking account of the Bash completion environment.

Output from this

Returns:

  • (Hash<Symbol, ] @todo Document return value.)

    Hash<Symbol, ] @todo Document return value.



322
323
324
325
326
327
328
329
# File 'lib/locd/config.rb', line 322

def cli_log_config
  {
    application: get( 'cli.log.application' ),
    level: cli_log_level,
    dest: cli_log_dest,
    sync: true
  }
end

#cli_log_dest$stderr

Returns:

  • ($stderr)


301
302
303
304
305
306
307
308
309
310
311
312
# File 'lib/locd/config.rb', line 301

def cli_log_dest
  dest = if cli_ARGV_looks_like_bash_comp?
    get 'cli.bash_comp.log.dest'
  else
    get 'cli.log.dest'
  end
  
  {
    **( IO === dest ? { io: dest } : { file_name: dest.to_s } ),
    formatter: NRSER::Log::Formatters::Color.new,
  }
end

#cli_log_levelSymbol

Level to log at when CLI'ing.

Returns:

  • (Symbol)

    One of SemanticLogger::LEVELS.



293
294
295
296
# File 'lib/locd/config.rb', line 293

def cli_log_level
  get( cli_ARGV_looks_like_bash_comp? ? 'bash_comp.log.level' :
                                        'cli.log.level' )
end

#env_key_for(*key) ⇒ Object



154
155
156
157
158
159
# File 'lib/locd/config.rb', line 154

def env_key_for *key
  [
    from_files( :namespace, :env, type: t.non_empty_str ),
    *key_path_for( *key )
  ].join( '_' ).upcase
end

#from_env(*key, type: nil) ⇒ Object



175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/locd/config.rb', line 175

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 key, value, type: type
  end
end

#from_files(*key, type: nil) ⇒ Object

Get a value from the config files only.

Parameters:

  • *key (Array<#to_s>)

    The key to lookup.



142
143
144
145
146
147
148
149
150
151
# File 'lib/locd/config.rb', line 142

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 key, value, type: type
  end
end

#get(*key, type: nil, default: nil) ⇒ Object Also known as: []



189
190
191
192
193
194
195
196
197
# File 'lib/locd/config.rb', line 189

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 key, default, type: type
end

#home_dirPathname

Returns Absolute path to Loc'd home directory (it's workspace). Directory may not exist, or may be something else like a file.

Returns:

  • (Pathname)

    Absolute path to Loc'd home directory (it's workspace). Directory may not exist, or may be something else like a file.



254
255
256
# File 'lib/locd/config.rb', line 254

def home_dir
  self[:home, type: t.abs_path].to_pn
end

#key_path_for(*key) ⇒ Object



132
133
134
# File 'lib/locd/config.rb', line 132

def key_path_for *key
  self.class.key_path_for *key
end

#log_dirObject



259
260
261
262
263
264
265
# File 'lib/locd/config.rb', line 259

def log_dir
  self[
    :log_dir,
    type: t.abs_path,
    default: (home_dir / 'log')
  ]
end

#parse_and_check(key, value, type: nil) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
# File 'lib/locd/config.rb', line 162

def parse_and_check key, value, type: nil
  type = Types.for_key( *key ) if 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

#set(*key, value, type: nil) ⇒ Object



202
203
204
205
206
207
208
# File 'lib/locd/config.rb', line 202

def set *key, value, type: nil
  value_str = value.to_s
  
  parse_and_check key, value_str, type: type
  
  ENV[ env_key_for( *key ) ] = value_str
end

#to_hObject



236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/locd/config.rb', line 236

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

#user_config_pathPathname

Returns Absolute path to the user config file, which may not exist, but will be loaded if it does.

Returns:

  • (Pathname)

    Absolute path to the user config file, which may not exist, but will be loaded if it does.



272
273
274
# File 'lib/locd/config.rb', line 272

def user_config_path
  home_dir / 'config.yml'
end