lib/autobuild/config.rb in autobuild-0.1 vs lib/autobuild/config.rb in autobuild-0.2

- old
+ new

@@ -3,13 +3,105 @@ require 'autobuild/logging' require 'autobuild/package' require 'autobuild/importer' +class Regexp + def each_match(string) + string = string.to_str + while data = match(string) + yield(data) + string = data.post_match + end + end +end + +class UndefinedVariable < Exception + attr_reader :name + def initialize(name); @name = name end +end + +class Interpolator + VarDefKey = 'defines' + InterpolationMatch = Regexp.new('\$\{([^}]+)\}|\$(\w+)') + + def self.interpolate(config, parent = nil) + Interpolator.new(config, parent).interpolate + end + + def initialize(node, parent = nil, variables = {}) + @node = node + @variables = {} + @defines = {} + @parent = parent + end + + def interpolate + case @node + when Hash + @defines = (@node[VarDefKey] || {}) + + interpolated = Hash.new + @node.each do |k, v| + next if k == VarDefKey + interpolated[k] = Interpolator.interpolate(v, self) + end + + interpolated + + when Array + @node.collect { |v| Interpolator.interpolate(v, self) } + + else + if @node.respond_to?(:to_str) + do_string(@node.to_str) { |varname| value_of(varname) } + else + @node + end + end + end + + def value_of(name) + if @defines.has_key?(name) + value = @defines.delete(name) + @variables[name] = do_string(value) { |varname| + begin + value_of(varname) + rescue UndefinedVariable => e + if e.varname == name + raise "Cyclic reference found in definition of #{name}" + else + raise + end + end + } + elsif @variables.has_key?(name) + @variables[name] + elsif @parent + @parent.value_of(name) + else + raise UndefinedVariable.new(name), "Interpolated variable #{name} is not defined" + end + end + + def do_string(value) + return value if value.empty? + + interpolated = '' + data = nil + InterpolationMatch.each_match(value) do |data| + varname = data[1] || data[2] + interpolated << data.pre_match << yield(varname) + end + return data ? (interpolated << data.post_match) : value + end +end + module Config def self.load(conffile, user_options) data = YAML.load( File.open(conffile) ) + data = Interpolator.interpolate(data) get_autobuild_config(data, user_options) get_package_config(data) rescue ConfigException => error error(error, "Error in config file '#{conffile}'") @@ -35,19 +127,21 @@ FileUtils.mkdir_p $SRCDIR if !File.directory?($SRCDIR) FileUtils.mkdir_p $LOGDIR if !File.directory?($LOGDIR) if setup["clean-log"] puts "Cleaning log dir #{$LOGDIR}" - FileUtils.rm_rf Dir.glob("#{$LOGDIR}/*") + FileUtils.rm_rf Dir.glob("#{$LOGDIR}/*.log") end $MAIL = setup["mail"] - $NOUPDATE = (options.noupdate or setup["noupdate"] or false) + $UPDATE = options.update + $UPDATE = setup["update"] if $UPDATE.nil? + $UPDATE = true if $UPDATE.nil? envvars = setup["environment"] envvars.each { |k, v| - ENV[k] = ( v.to_a.collect { |path| path.to_a.join("") }.join(":") ) + ENV[k] = v.to_a.join(":") } end def self.add_package(name, config) # Get the package type @@ -98,10 +192,10 @@ v1.to_s + " " + v2.to_str end } # Remove p -> p dependency which may come from common_config if config.has_key?(:depends) - config[:depends] = config[:depends].to_a.find_all { |el| el != p } + config[:depends] = config[:depends].to_a.reject { |el| el == p } end add_package(p, config) end end