class Lorj::MetaAppConfig
Private functions for MetaAppConfig
This class is the Meta Application configuration class accessible from PrcLib.metadata
A unique class instance load data from Lorj::Defaults
thanks to the defaults.yaml. In the near future, sections `:setup` and `:sections` will be moved to a different file and loaded by this instance itself.
It implements Meta Config
layers to help in loading default application meta data, and any controller/process redefinition.
The defaults.yaml :sections and :setup is defined as follow:
-
:setup: Contains :ask_step array
-
:ask_step:
Array
of group of keys/values to setup. Each group will be internally identified by a index starting at 0. parameters are as follow:-
:desc: string to print out before group setup
ERB template enable: To get config data in ERB context, use config
-
:explanation: longer string to display after :desc:
It is printed out in brown color.
It supports ERB template. To get config data, type <%= config %>
In your defaults.yaml file, write multiline with |- after the key.
Ex: if config returns 'text', defaults.yaml can have the following explanation.
:setup: :ask_step: - :desc: 'Small description' :explanation: |- My complete explanation is in multiline <%= config['text'] %>
By default, thanks to data model dependency, the group is automatically populated. So, you need update this part only for data that are not found from the dependency.
-
:add: array of keys to add manually in the group. The
Array
can be written with [] or list of dash elementsExample of a defaults.yaml content:
:setup: :ask_step: - :desc: 'Small description' :add: [:key_pair_files, :ssh_user]
-
-
-
:section: Contains a list of sections with several keys and attributes and eventually :default:
This list of sections and keys will be used to build the account files with the lorj
Lorj::Core.setup
function. Those data is accessible through theLorj.defaults
.get_meta,Lorj.defaults
.get_meta_auto orLorj.defaults
.get_meta_sectionplease note that
Lorj.defaults
.get_meta uses the controller config layer to redefine defaults application meta data on controller needs. SeeBaseDefinition.define_data
for details.Ex:
# Use Lorj.defaults.data exceptionnaly Lorj.defaults.data.merge({sections: {:mysection: {key: { data1: 'test1', data2: 'test2' } } } }) puts Lorj.defaults.get_meta(:mysection, :key) # => { data1: 'test1', data2: 'test2' } puts Lorj.defaults.get_meta(:mysection) # => {:key => { data1: 'test1', data2: 'test2' }} puts Lorj.defaults.get_meta_section(:key) # => :mysection puts Lorj.defaults.get_meta_auto(:key) # => { data1: 'test1', data2: 'test2' }
-
:default: This section define updatable data available from config.yaml. But will never be added in an account file.
It contains a list of key and options.
-
:<aKey>: Possible options
-
:desc: default description for that <aKey>
-
-
-
:<aSectionName>: Name of the section which should contains a list
-
:<aKeyName>: Name of the key to setup.
-
:desc:
Description of that key, printed out at setup time. default: nil
-
:explanation: Multi line explanation. In yaml, use |- to write multilines
Print a multiline explanation before ask the key value. ERB template enable. To get config data, type <%= config %>
-
:encrypted: true if this has to be encrypted with ~/.cache/forj/.key
-
:readonly: true if this key is not modifiable by a simple. Lorj::Account::set function. false otherwise. Default: false
-
:account_exclusive: true to limit the data to account config layer.
-
:account: Set to true for setup to ask this data to the user during setup process. default: false
-
:validate: Ruby Regex to validate the end user input.
Ex: :validate: !ruby/regexp /^w?w*$/
-
:default: Default value. Replace /:default/<data>
-
:default_value: default value proposed to the user.
-
:ask_step: Define the group number to attach the key to be asked.
By default, setup will determine the step, thanks to lorj object dependencies tree.
This number start at 0. Each step can be defined by /:setup/:ask_step/<steps> list. See :setup section.
ex:
:sections: :mysection: :mydata: :setup: :ask_step: 2
-
:ask_sort: Number which represents the ask order in the step group. (See /:setup/:ask_step for details)
-
:after: <Data> Name of the previous <Data> to ask before the current one.
-
:depends_on: Identify :data type required to be set before the current one.
-
:value_mapping: list of values to map as defined by the controller
-
:controller: mapping for get controller value from process values
<value> : <map> value map equivalence. See data_value_mapping function
-
-
:process: mapping for get process value from controller values
<value> : <map> value map equivalence. See data_value_mapping function
-
:list_values: Provide capabililities to get a list and choose from.
-
:query_type: It can be:
-
:query_call to execute a query on flavor, query_params is empty for all.
Data
are extracted thanks to :values. -
:process_call to execute a process function to get the values.
Data
are extracted thanks to :values. -
:controller_call to execute a controller query.
Data
are extracted thanks to :values. -
:values to get list of fixed values from :values.
-
-
:object:
-
When used with :query_type == :query_call or :controller_call, :object is the object type symbol to query.
-
When used with :query_type == :process_call, :object is the object used in the process.
-
-
:query
Used with :query_type=:process_call. process function name to call
-
:query_call:
Used with :query_type=:controller_call. Handler function to use. (query_e, create_e, …) The function called must return an
Array
.Used with :query_type=:process_call. Function name to call
-
:query_params:
Used with :query_type=:query_call. Query hash defining filtering capabilities.
Used with :query_type=:process_call. hParams data passed to the process function.
-
:values: List of fields to get values or list of fixed values.
Depends on query type.
-
:validate:
if :list_strict, the value is limited to the possible values from the list
-
-
:pre_step_function: Process called before asking the data.
if it returns true, user interaction is cancelled.
-
:post_step_function:Process called after asking the data.
if it returns false, the user is requested to re-enter a new value.
-
-
-
Public Class Methods
Implements a 2 layers metadata config.
# File lib/lorj_meta.rb, line 387 def initialize(data) config_layers = [] # Application layer config_layers << define_meta_app_layer(data) # mapping section/keys layer config_layers << define_meta_map_layer # controller Config layer config_layers << define_meta_controller_layer initialize_layers(config_layers) build_section_mapping end
Public Instance Methods
return 1st section/data existence.
If a key name is found in several different section,
auto_* functions, usually, will get the first section from a key/sections mapping Array
except if you provide a '#' in the data name. (Ex: :'section1#key1')
The list of sections for one key is build thanks to build_section_mapping.
-
Args :
-
data
: data name to check. Support 'section#data'.
-
-
Returns :
-
true/false
-
# File lib/lorj_meta.rb, line 471 def auto_meta_exist?(data) return nil unless data section, data = first_section(data) p_exist?(:keys => [:sections, section, data]) end
Get model data options. Section name is determined by the associated data name
auto_* functions, usually, will get the first section from a key/sections mapping Array
. But it supports also 'Section#Name' to determine the section to use instead of first one.
The list of sections for one key is build thanks to build_section_mapping.
-
Args :
-
data
: data name. Support 'Section#Name' -
options
: Optionnal. List of sub keys in tree to get data.
-
-
Returns :
-
data options values
OR
-
nil if:
-
missing data name as parameter.
-
data was not found. defined in /:sections/<section>/<data
-
-
# File lib/lorj_meta.rb, line 613 def auto_section_data(data, *options) return nil if data.nil? section, data = first_section(data) section_data(section, data, *options) end
return the list of valid keys found in meta data.
-
Args :
-
Returns :
-
Array
of data name.
-
# File lib/lorj_meta.rb, line 525 def datas p_get(:keys => [:keys], :name => 'map').keys end
Controller data definition which will enhance data Application definition. This function replace any controller definition. To update/add options to an existing controller data, use update_data. You can also use [], []=, etc… provided by parent class. This will work only if the 'controller' is the highest layer.
-
Args:
-
section
: Symbol. Section name of the data to define. -
data
: Symbol. Name of the data -
options
:Hash
. List of options -
layer
: optional. Layer name to define. All layers are authorized, except 'app'. 'app' is the protected application layer data. By default, the layer configured is 'controller'
-
# File lib/lorj_meta.rb, line 699 def define_controller_data(section, data, options, layer = 'controller') return nil unless check_par(section, Symbol, data, Symbol, options, Hash, layer, [String, NilClass]) keys = [:sections] keys << section << data layer = 'controller' if layer.nil? || layer == 'app' update_map(section, data) p_set(:keys => keys, :name => layer, :value => options) end
section/data removal function
-
Args
-
section
: Symbol. Section name of the data to define. -
data
: Symbol orArray
of Symbols. Name of the data -
layer
: optional. Layer name to define. All layers are authorized, except 'app'. 'app' is the protected application layer data. By default, the layer configured is 'controller'
-
-
Returns
-
The value set or nil
-
# File lib/lorj_meta.rb, line 671 def del(type, section, data_keys, layer = 'controller') return nil unless check_par(type, Symbol, section, Symbol, data_keys, [Symbol, Array], layer, [String, NilClass]) keys = build_keys(type, section, data_keys) layer = 'controller' if layer.nil? || %w(app map).include?(layer) delete_map(section, keys[2]) if keys[0] == :sections p_del(:keys => keys, :name => layer) end
return the 1st section name found of a data or the section discovered.
-
Args :
-
data
: data name to search. It supports section#name.
-
-
Returns :
-
Array:
-
section name
-
key name
-
-
# File lib/lorj_meta.rb, line 488 def first_section(data) section, data = _detect_section(data, nil) return [section, data] unless section.nil? && p_exist?(:keys => [:keys, data]) arr = p_get(:keys => [:keys, data]) return nil unless arr.is_a?(Array) && arr[0] if /1\.8/ =~ RUBY_VERSION && arr.length > 1 PrcLib.warning('Avoid using Lorj::MetaAppConfig.first_section(%s) with'\ ' Ruby 1.8 and searching for the first section as it do'\ ' not preserve the order of Hash keys.', data) end [arr[0], data] end
Redefine CoreConfig#layer_add to add mapping build
See CoreConfig#layer_add for details
# File lib/lorj_meta.rb, line 407 def layer_add(options) p_layer_add(options) build_section_mapping end
Redefine CoreConfig#layer_remove to add mapping build
See CoreConfig#layer_remove for details
# File lib/lorj_meta.rb, line 415 def layer_remove(options) p_layer_remove(options) build_section_mapping end
Loop on Config
metadata
-
Args :
-
code
: Block of code on `section`, `key`, `value`
-
-
Returns :
-
nothing
-
# File lib/lorj_meta.rb, line 427 def meta_each data = p_get(:keys => [:sections], :merge => true) if data.nil? PrcLib.warning('No model data definition found. Do you have a model'\ ' loaded?') return end data.each do |section, hValue| hValue.each do |key, value| yield section, key, value end end end
return section/data existence
-
Args :
-
section
: Section to search for data. -
data
: data name to check
-
-
Returns :
-
true/false
-
# File lib/lorj_meta.rb, line 451 def meta_exist?(section, key) p_exist?(:keys => [:sections, section, key]) end
Get model section/data options. It returns the list of options, against layers, of all Hash
options, cloned and merged.
-
Args :
-
section
: section name -
data
: data name -
options
: Optionnal. List of sub keys in tree to get data.
-
-
Returns :
-
Merged cloned data options values.
OR
-
# File lib/lorj_meta.rb, line 584 def section_data(section, key, *options) return nil if section.nil? || key.nil? keys = [:sections] keys << section << key keys.concat(options) p_get(:keys => keys, :merge => true) end
return the list of sections name of a data.
-
Args :
-
data
: Optional. data name to search. If no name given, returns all existing sections.
-
-
Returns :
-
Array
of sections name.
-
# File lib/lorj_meta.rb, line 511 def sections(data = nil) return p_get(:keys => [:sections]).keys if data.nil? _, data = _detect_section(data, nil) return nil unless p_exist?(:keys => [:keys, data]) p_get(:keys => [:keys, data]) end
layer setting function
-
Args
-
type
: Define the section type name. Predefined section type are :setup and :sections -
section
: Symbol. Section name of the data to define. -
data
: Symbol orArray
of Symbols. Name of the data -
options
:Hash
. List of options -
layer
: optional. Layer name to define. All layers are authorized, except 'app'/'keys'. 'app' is the protected application layer data. By default, the layer configured is 'controller'
-
-
Returns
-
The value set or nil
OR
-
# File lib/lorj_meta.rb, line 641 def set(type, section, data_keys, options, layer = 'controller') return nil unless check_par(type, Symbol, section, Symbol, data_keys, [Symbol, Array], options, Hash, layer, [String, NilClass]) keys = build_keys(type, section, data_keys) # :keys is a special sections used internally. return nil if keys[1] == :keys update_map(section, keys[2]) if keys[0] == :sections layer = 'controller' if layer.nil? || %w(app map).include?(layer) p_set(:keys => keys, :name => layer, :value => options) end
Get setup options. It returns the top layer data for options requested
-
Args :
-
options
:Array
of options tree.
-
-
Returns :
-
top layer data found.
OR
-
nil if:
-
data was not found. defined in /:setup/options…
-
-
# File lib/lorj_meta.rb, line 562 def setup_data(*options) keys = [:setup] keys.concat(options) p_get(:keys => keys, :merge => true) end
Get model setup/data options. It returns the list of options, against layers, of all Hash
options, cloned and merged. Warning! This function assumes data found to be a Hash
or Array
. To get the top layer data, use setup_data(options)
-
Args :
-
options
:Array
of setup options tree
-
-
Returns :
-
Merged cloned options values.
OR
-
# File lib/lorj_meta.rb, line 545 def setup_options(*options) keys = [:setup] keys.concat(options) p_get(:keys => keys, :merge => true) end
Controller data definition which will enhance data Application definition. This function replace any controller definition. To replace or redefine options to an existing controller data, use define_data. You can also use [], []=, etc… provided by parent class. This will work only if the 'controller' is the highest layer.
-
Args:
-
section
: Symbol. Section name of the data to define. -
data
: Symbol. Name of the data -
options
:Hash
. List of options to add or update. -
layer
: optional. Layer name to define. All layers are authorized, except 'app'. 'app' is the protected application layer data. By default, the layer configured is 'controller'
-
# File lib/lorj_meta.rb, line 728 def update_controller_data(section, data, options, layer = 'controller') return nil unless check_par(section, Symbol, data, Symbol, options, Hash, layer, [String, NilClass]) keys = [:sections, section, data] value = p_get(:keys => keys, :name => 'controller') layer = 'controller' if layer.nil? || layer == 'app' p_set(:keys => keys, :name => layer, :value => value.merge(options)) end
Private Instance Methods
Implement a section detection in a symbol/string Help each auto_* functions to work without update.
# File lib/lorj_meta.rb, line 64 def _detect_section(key, default_section) m = key.to_s.match(/^(.*)#(.*)$/) return [m[1].to_sym, m[2].to_sym] if m && m[1] != '' && m[2] != '' [default_section, key] end
build keys for set and del We assume type, section, data_keys to be with appropriate type.
# File lib/lorj_meta.rb, line 124 def build_keys(type, section, data_keys) keys = [type, section] return keys.concat(data_keys) if data_keys.is_a?(Array) keys << data_keys end
Used anytime config is updated (config data load or initialization)
This function rebuild the section/key mapping Usually, executed while initializing or while loading a config.
# File lib/lorj_meta.rb, line 40 def build_section_mapping return unless p_exist?(:keys => [:sections]) # The primary data key should change from key to section & key. data = p_get(:keys => [:sections], :merge => true) return if data.nil? section_map = {} data.each do |section, values| next if values.nil? values.keys.each do |key| section_map[key] = [] unless section_map.key?(key) next if section_map[key].include?(section) section_map[key] << section end end p_set(:keys => [:keys], :value => section_map, :name => 'map') end
parameters tester functions
-
Args Each data are defined by a couple parameters.
-
1st one is the value to check
-
2nd one is the expected class (Class object) or
-
acceptable classes (Array
of class).
-
Returns
-
false if value is not of the expected Class.
-
true if all parameters are as expected.
-
# File lib/lorj_meta.rb, line 105 def check_par(*parameters) parameters.each_index do |index| next unless index.odd? if parameters[index].is_a?(Array) unless parameters[index].include?(parameters[index - 1].class) return false end end if parameters[index].is_a?(Class) return false unless parameters[index - 1].is_a?(parameters[index]) end end true end
Define the meta_data Application layer It requires a Hash
to initialize this layer until a file load is done instead. (Planned for Lorj
2.0)
# File lib/lorj_meta.rb, line 134 def define_meta_app_layer(data) data.delete(:keys) if data.is_a?(Hash) && data.key?(:keys) PRC::CoreConfig.define_layer(:name => 'app', :config => PRC::BaseConfig.new(data), :set => false) end
Define the meta_data Application layer
# File lib/lorj_meta.rb, line 148 def define_meta_controller_layer PRC::CoreConfig.define_layer(:name => 'controller', :set => true, :load => true) end
Define the meta_data section/keys mapping layer
# File lib/lorj_meta.rb, line 143 def define_meta_map_layer PRC::CoreConfig.define_layer(:name => 'map', :set => true) end
delete section data mapping
# File lib/lorj_meta.rb, line 85 def delete_map(section, data) keys = [:keys, data] map = p_set(:keys => keys, :name => 'map') return if map.nil? map.remove section end
set section data mapping
# File lib/lorj_meta.rb, line 72 def update_map(section, data) keys = [:keys, data] map = p_get(:keys => keys, :name => 'map') if map.nil? map = [section] else map << section unless map.include?(section) end p_set(:keys => keys, :name => 'map', :value => map) end