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