lib/forj-config.rb in forj-0.0.43 vs lib/forj-config.rb in forj-0.0.44

- old
+ new

@@ -22,65 +22,205 @@ require 'yaml' #require_relative 'log.rb' #include Logging +def rhExist?(yVal, *p) + + if p.length() == 0 + return 0 + end + return 0 if yVal.class != Hash + p=p.flatten + if p.length() == 1 + return 1 if yVal.key?(p[0]) + return 0 + end + return 0 if yVal.nil? or not yVal.key?(p[0]) + ret = 0 + ret = rhExist?(yVal[p[0]], p.drop(1)) if yVal[p[0]].class == Hash + return 1 + ret +end + +def rhGet(yVal, *p) + + return nil if yVal.class != Hash + p=p.flatten + if p.length() == 0 or not yVal + return yVal + end + if p.length() == 1 + return yVal[p[0]] if yVal.key?(p[0]) + return nil + end + return nil if not yVal + return rhGet(yVal[p[0]], p.drop(1)) if yVal.key?(p[0]) + nil +end + +def rhSet(yVal, value, *p) + if p.length() == 0 + return yVal + end + p=p.flatten + if p.length() == 1 + if not yVal.nil? + if value + yVal[p[0]] = value + else + yVal.delete(p[0]) + end + return yVal + end + if value + ret = { p[0] => value } + else + ret = {} + end + return ret + end + if not yVal.nil? + yVal[p[0]] = {} if not yVal[p[0]] or yVal[p[0]].class != Hash + ret=rhSet(yVal[p[0]], value, p.drop(1)) + return yVal + else + ret = rhSet(nil, value, p.drop(1)) + return { p[0] => ret } + end +end + +def rhKeyToSymbol(yVal, levels = 1) + return nil if yVal.nil? or yVal.class != Hash + yRes = {} + yVal.each { | key, value | + if key.class == String + if levels <= 1 + yRes[key.to_sym] = value + else + yRes[key.to_sym] = rhKeyToSymbol(value, levels - 1) + end + else + if levels <= 1 + yRes[key] = value + else + yRes[key] = rhKeyToSymbol(value, levels - 1) + end + end + } + yRes +end + +def rhKeyToSymbol?(yVal, levels = 1) + return false if yVal.nil? or yVal.class != Hash + yVal.each { | key, value | + if key.class == String + return true + end + if levels >1 + res = rhKeyToSymbol?(value, levels - 1) + return true if res + end + } + false +end + class ForjDefault # @sDefaultsName='defaults.yaml' # @yDefaults = defaults.yaml file data hash - def initialize() - # Load yaml documents (defaults) - # If config doesn't exist, it will be created, empty with 'defaults:' only + # Load yaml documents (defaults) + # If config doesn't exist, it will be created, empty with 'defaults:' only - if not $LIB_PATH - Logging.fatal(1, 'Internal $LIB_PATH was not set.') - end - Logging.info('Reading default configuration...') + def self.exist?(key, section = :default) + key = key.to_sym if key.class == String + (rhExist?(@@yDefaults, section, key) == 2) + end - @sDefaultsName=File.join($LIB_PATH,'defaults.yaml') + def self.get(key, section = :default) + key = key.to_sym if key.class == String + return(rhGet(@@yDefaults, section, key)) if key + rhGet(@@yDefaults, section) if not key + end - @yDefaults=YAML.load_file(@sDefaultsName) + def self.dump() + @@yDefaults end + # Loop on Config metadata + def self.meta_each + rhGet(@@yDefaults, :sections).each { | section, hValue | + hValue.each { | key, value | + yield section, key, value + } + } + end - def exist?(key, section = :default) + def self.meta_exist?(key) + return nil if not key + key = key.to_sym if key.class == String - (rhExist?(@yDefaults, section, key) == 2) + section = rhGet(@@account_section_mapping, key) + rhExist?(@@yDefaults, :sections, section, key) == 3 end - def get(key, section = :default) + def self.get_meta(key) + return nil if not key + key = key.to_sym if key.class == String - return(rhGet(@yDefaults, section, key)) if key - rhGet(@yDefaults, section) if not key + section = rhGet(@@account_section_mapping, key) + rhGet(@@yDefaults, :sections, section, key) end - def dump() - @yDefaults + def self.build_section_mapping + @@account_section_mapping = {} + rhGet(@@yDefaults, :sections).each { | section, hValue | + next if section == :default + hValue.each_key { | map_key | + Logging.fatal(1, "defaults.yaml: Duplicate entry between sections. '%s' defined in section '%s' already exists in section '%s'" % [map_key, section, rhGet(@account_section_mapping, map_key) ])if rhExist?(@account_section_mapping, map_key) != 0 + rhSet(@@account_section_mapping, section, map_key) + } + } end + + def self.get_meta_section(key) + key = key.to_sym if key.class == String + rhGet(@@account_section_mapping, key) + end + + if not $LIB_PATH + Logging.fatal(1, 'Internal $LIB_PATH was not set.') + end + + Logging.info('Reading default configuration...') + + @@sDefaultsName=File.join($LIB_PATH,'defaults.yaml') + + @@yDefaults=YAML.load_file(@@sDefaultsName) + + self.build_section_mapping end class ForjConfig # Internal Object variables: # @sConfigName= 'config.yaml' # @yRuntime = data in memory. # @yLocal = config.yaml file data hash. # @yObjConfig = Extra loaded data - # @oDefaults = Application defaults object + # ForjDefault = Application defaults class attr_reader :sConfigName # Load yaml documents (defaults + config) # If config doesn't exist, it will be created, empty with 'defaults:' only def default_dump(interms = nil) # Build a config hash. res = {} - @oDefaults.dump[:default].each_key { |key| + ForjDefault.dump[:default].each_key { |key| dump_key = exist?(key) rhSet(res, get(key), dump_key, key) } if rhExist?(@yLocal, :default) == 1 @yLocal[:default].each_key { |key| @@ -132,16 +272,14 @@ end else @sConfigName = File.join($FORJ_DATA_PATH,sConfigDefaultName) end - @oDefaults = ForjDefault.new - if File.exists?(@sConfigName) @yLocal = YAML.load_file(@sConfigName) if rhKeyToSymbol?(@yLocal, 2) - @yLocal = rhKeyToSymbol(@yLocal, 2) + @yLocal = rhKeyToSymbol(@yLocal, 2) self.SaveConfig() end else @yLocal = { :default => nil } @@ -220,11 +358,11 @@ def set(key, value) # Function to set a runtime key/value, but remove it if value is nil. # To set in config.yaml, use LocalSet # To set on extra data, like account information, use ExtraSet - + key = key.to_sym if key.class == String return false if key.class != Symbol if value rhSet(@yRuntime, value, key) @@ -232,55 +370,62 @@ @yRuntime.delete(key) end true end - def get(key, interms = nil, default = nil) - + def runtimeExist?(key) + (rhExist?(@yRuntime, key) == 1) + end + + def runtimeGet(key) + rhGet(@yRuntime, key) if runtimeExist?(key) + end + + def get(key, default = nil) key = key.to_sym if key.class == String return nil if key.class != Symbol # If key is in runtime - return rhGet(@yRuntime, key) if rhExist?(@yRuntime, key) == 1 - # Check data in intermediate hashes or array of hash. (like account data - key have to be identical) - if interms - if interms.instance_of? Hash - return rhGet(interms, key) if rhExist?(interms, key) == 1 - elsif interms.instance_of? Array # Array of hashes - iCount=0 - oVal = nil - interms.each { | elem | - if elem.class == Hash - elem.each { | hashkey, value | - if value.class == Hash and rhExist?(elem, hashkey, key) == 2 # hash of hash - oVal = rhGet(elem, hashkey, key) - break - elsif value.class != Hash and rhExist?(elem, hashkey) == 1 # single hash: key = value. - oVal = rhGet(elem, hashkey) - break - - end - } - break if oVal - end - iCount += 1 - } - return oVal - end - end + return runtimeGet(key) if runtimeExist?(key) + #~ # Check data in intermediate hashes or array of hash. (like account data - key have to be identical) + #~ if interms + #~ if interms.instance_of? Hash + #~ return rhGet(interms, key) if rhExist?(interms, key) == 1 + #~ elsif interms.instance_of? Array # Array of hashes + #~ iCount=0 + #~ oVal = nil + #~ interms.each { | elem | + #~ if elem.class == Hash + #~ elem.each { | hashkey, value | + #~ if value.class == Hash and rhExist?(elem, hashkey, key) == 2 # hash of hash + #~ oVal = rhGet(elem, hashkey, key) + #~ break + #~ elsif value.class != Hash and rhExist?(elem, hashkey) == 1 # single hash: key = value. + #~ oVal = rhGet(elem, hashkey) + #~ break +#~ + #~ end + #~ } + #~ break if oVal + #~ end + #~ iCount += 1 + #~ } + #~ return oVal + #~ end + #~ end # else key in local default config of default section. return LocalGet(key) if LocalDefaultExist?(key) # else key in application defaults - return @oDefaults.get(key) if @oDefaults.exist?(key) + return ForjDefault.get(key) if ForjDefault.exist?(key) # else default default end def getAppDefault(section, key = nil) key = key.to_sym if key.class == String - @oDefaults.get(key, section) + ForjDefault.get(key, section) end def exist?(key, interms = nil) key = key.to_sym if key.class == String @@ -302,11 +447,11 @@ } end end return 'local' if LocalDefaultExist?(key) # else key in application defaults - return 'default' if @oDefaults.exist?(key) + return 'default' if ForjDefault.exist?(key) false end def LocalDefaultExist?(key) LocalExist?(key) @@ -356,103 +501,14 @@ # Function to return in fatal error if a config data is nil. Help to control function requirement. def fatal_if_inexistent(key) Logging.fatal(1, "Internal error - %s: '%s' is missing" % [caller(), key]) if not self.get(key) end -end -def rhExist?(yVal, *p) - - if p.length() == 0 - return 0 + def meta_each + ForjDefault.meta_each { |section, key, value| + next if rhGet(value, :account_exclusive) + yield section, key, value + } end - return 0 if yVal.class != Hash - p=p.flatten - if p.length() == 1 - return 1 if yVal[p[0]] - return 0 - end - return 0 if not yVal or not yVal[p[0]] - ret = rhExist?(yVal[p[0]], p.drop(1)) if yVal[p[0]] - return 1 + ret -end -def rhGet(yVal, *p) - - if p.length() == 0 or not yVal - return nil - end - p=p.flatten - if p.length() == 1 - return yVal[p[0]] if yVal[p[0]] - return nil - end - return nil if not yVal - return rhGet(yVal[p[0]], p.drop(1)) if yVal[p[0]] - nil -end - -def rhSet(yVal, value, *p) - if p.length() == 0 - return yVal - end - p=p.flatten - if p.length() == 1 - if yVal - if value - yVal[p[0]] = value - else - yVal.delete(p[0]) - end - return yVal - end - if value - ret = { p[0] => value } - else - ret = {} - end - return ret - end - if yVal - yVal[p[0]] = {} if not yVal[p[0]] or yVal[p[0]].class != Hash - ret=rhSet(yVal[p[0]], value, p.drop(1)) - return yVal - else - ret = rhSet(nil, value, p.drop(1)) - return { p[0] => ret } - end -end - -def rhKeyToSymbol(yVal, levels = 1) - return nil if not yVal - yRes = {} - yVal.each { | key, value | - if key.class == String - if levels <= 1 - yRes[key.to_sym] = value - else - yRes[key.to_sym] = rhKeyToSymbol(value, levels - 1) - end - else - if levels <= 1 - yRes[key] = value - else - yRes[key] = rhKeyToSymbol(value, levels - 1) - end - end - } - yRes -end - -def rhKeyToSymbol?(yVal, levels = 1) - return false if not yVal - yVal.each { | key, value | - if key.class == String - return true - end - if levels >1 - res = rhKeyToSymbol?(value, levels - 1) - return true if res - end - } - false end