lib/forj-config.rb in forj-0.0.36 vs lib/forj-config.rb in forj-0.0.37

- old
+ new

@@ -28,90 +28,81 @@ # @sDefaultsName='defaults.yaml' # @yDefaults = defaults.yaml file data hash attr_reader :yDefaults - + def initialize() # 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...') @sDefaultsName=File.join($LIB_PATH,'defaults.yaml') @yDefaults=YAML.load_file(@sDefaultsName) end end -class ForjConfig +class ForjConfig # Internal variables: # @sConfigName='config.yaml' # @yRuntime = data in memory. # @yLocal = config.yaml file data hash. # @yConfig = defaults.yaml + local_config data hash - + attr_reader :yLocal attr_reader :yConfig attr_reader :sConfigName def initialize(sConfigName=nil) # Load yaml documents (defaults + config) # If config doesn't exist, it will be created, empty with 'defaults:' only - if not $FORJ_DATA_PATH Logging.fatal(1, 'Internal $FORJ_DATA_PATH was not set.') end sConfigDefaultName='config.yaml' if sConfigName if File.dirname(sConfigName) == '.' sConfigName= File.join($FORJ_DATA_PATH,sConfigName) - end + end sConfigName = File.expand_path(sConfigName) if not File.exists?(sConfigName) Logging.warning("Config file '%s' doesn't exists. Using default one." % [sConfigName] ) @sConfigName=File.join($FORJ_DATA_PATH,sConfigDefaultName) - else + else @sConfigName=sConfigName end else @sConfigName=File.join($FORJ_DATA_PATH,sConfigDefaultName) end - @Default=ForjDefault.new - - + if File.exists?(@sConfigName) @yLocal=YAML.load_file(@sConfigName) else @yLocal={ 'default' => nil } - if not File.exists?(@sConfigName) - # Write the empty file - if not File.exists?($FORJ_DATA_PATH) - Dir.mkdir($FORJ_DATA_PATH) - end - Logging.info ('Creating your default configuration file ...') - self.SaveConfig() - end + # Write the empty file + Logging.info ('Creating your default configuration file ...') + self.SaveConfig() end - + BuildConfig() - + @yRuntime={} end - def SaveConfig() begin File.open(@sConfigName, 'w') do |out| YAML.dump(@yLocal, out) end @@ -120,11 +111,35 @@ return false end Logging.info ('Configuration file "%s" updated.' % @sConfigName) return true end - + + def ExtraSave(sFile, section, name) + hVal = rhGet(@Default.yDefaults, :extra_loaded, section, name) + if hVal + begin + File.open(sFile, 'w') do |out| + YAML.dump(hVal, out) + end + rescue => e + Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")]) + return false + end + Logging.info ('Configuration file "%s" updated.' % sFile) + return true + end + end + + def ExtraLoad(sFile, section, name) + if File.exists?(sFile) + hVal = YAML.load_file(sFile) + rhSet(@Default.yDefaults, hVal, :extra_loaded, section, name) + end + BuildConfig() + end + def LocalSet(key, value, section = 'default') if not key or not value return false end if @yLocal[section] == nil @@ -132,72 +147,189 @@ end if @yLocal.has_key?(section) @yLocal[section].merge!({key => value}) else @yLocal.merge!(section => {key => value}) - end + end BuildConfig() return true end - - def LocalDel(key,section = 'default') + + def LocalGet(key, section = 'default', default = nil) + if @yLocal.has_key?(key) + return @yLocal[key] + end + default + end + + def LocalDel(key, section = 'default') if not key return false end if not @yLocal.has_key?(section) return false - end + end @yLocal[section].delete(key) BuildConfig() return true end - - def setDefault(key, value) - if not key - return false - end - if not @yRuntime[key] - @yRuntime[key] = value - end - return true + + def ExtraExist?(section, name, key) + return nil if not section or not name + + return(rhExist?(@yConfig, :extra_loaded, section, name) == 3) if not key + return(rhExist?(@yConfig, :extra_loaded, section, name, key) == 4) end - - def set(key, value) - if not key - return false - end - if value - @yRuntime[key] = value - else - @yRuntime.delete(key) - end - return true + + def ExtraGet(section, name, key = nil, default = nil) + return nil if not section or not name + + if key + return default unless ExtraExist?(section, name, key) + rhGet(@yConfig, :extra_loaded, section, name, key) + else + return default unless rhExist?(@yConfig, :extra_loaded, section, name) == 3 + rhGet(@yConfig, :extra_loaded, section, name) + end end - - def get(key, default = @yConfig['default'][key]) - if @yRuntime.has_key?(key) - @yRuntime[key] - else - default - end + + def ExtraSet(section, name, key, value) + rhSet(@yConfig, value, :extra_loaded, section, name, key) end - + + def set(key, value, par = {}) + # Function to set a config key, but remove it if value is nil. + if not key + return false + end + if par[:section] and par[:name] + # Set data in extra_loaded + ExtraSet(par[:section], par[:name], key, value) + elsif par[:section] + # To set key=value on config.yaml, use LocalSet + if value + rhSet(@yRuntime, value, par[:section], key) + else + hVal = rhGet(@yRuntime, par[:section]) + hVal.delete(key) + end + else + if value + rhSet(@yRuntime, value, key) + else + @yRuntime.delete(key) + end + end + true + end + + def get(key, par = {}) + if par[:section] and par[:name] + # Get data only from extra_loaded + return ExtraGet(par[:section], par[:name], key, par[:default]) + elsif par[:section] + # If section/key is in runtime + return rhGet(@yRuntime, par[:section], key) if rhExist?(@yRuntime, par[:section], key) == 2 + # If section/key is in default config + return rhGet(@yConfig, par[:section], key) if rhExist?(@yConfig, par[:section], key) == 2 + else + # If key is in runtime + return rhGet(@yRuntime, key) if rhExist?(@yRuntime, key) == 1 + end + # else key in default config of default section. + return rhGet(@yConfig, 'default', key) if rhExist?(@yConfig, 'default', key) == 2 + # else default + par[:default] + end + + def exist?(key, par = {}) + if par[:section] and par[:name] + # section/name/key exist in extra_loaded ? + return ExtraExist?(par[:section], par[:name], key) + elsif par[:section] + # section/key exist in runtime? + return "runtime" if rhExist?(@yRuntime, par[:section], key) == 2 + # section/key exist in default config ? + return "default" if rhExist?(@yConfig, par[:section], key) == 2 + else + return "runtime" if rhExist?(@yRuntime, key) == 1 + return "default" if rhExist?(@yRuntime, 'default', key) == 2 + end + false + end + def BuildConfig() - # This function implements the logic to get defaults, superseed by local config. + # This function implements the logic to get defaults, superseed by local config. # Take care of ports array, which is simply merged. - - @yConfig={ 'default' => @Default.yDefaults['default'].clone } + + @yConfig = @Default.yDefaults.clone if @yLocal['default'] @yConfig['default'].merge!(@yLocal['default']) { |key, oldval, newval| key == 'ports'? newval.clone.push(oldval.clone).flatten: newval } - end - @yConfig.merge!(@yLocal) { |key, oldval, newval| key == 'default'? oldval: newval } + end + @yConfig.merge!(@yLocal) { |key, oldval, newval| (key == 'default' or key == :extra_load)? oldval: newval } end - + def LocalDefaultExist?(key) - if @yLocal['default'][key] - true - else - false - end + return true if @yLocal['default'][key] + false end + def fatal_if_inexistent(key) + # Function to return in fatal error if a config data is nil. Help to control function requirement. + 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 + 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 + 0 +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 + yVal[p[0]] = value + return yVal + end + ret = { p[0] => value } + 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