rscons-try1/lib/rscons/environment.rb

106 lines
2.8 KiB
Ruby

module Rscons
class Environment
# Values:
# :none - do not print anything
# :short - rscons will print a short representation of the step
# being performed
# :command (default) - print the full command being executed
attr_accessor :echo
# Hash of Builder Name => Builder Class
attr_reader :builders
def initialize(options = {})
@echo = :command
@variables = options.reject { |key, val| not key[0] =~ /[A-Z]/ }
@builders = {}
@build_dirs = {}
unless @variables[:omit_default_builders]
DEFAULT_BUILDERS.each do |builder_class|
add_builder(builder_class)
end
end
@echo = options[:echo] if options[:echo]
end
def add_builder(builder_class)
@builders[builder_class.to_s.split(':').last] = builder_class
var_defs = builder_class.default_variables(self)
if var_defs
var_defs.each_pair do |var, val|
unless @variables.has_key?(var)
@variables[var] = val
end
end
end
end
def [](key)
@variables[key]
end
def []=(key, val)
@variables[key] = val
end
def build_dir(src_dir, build_dir)
@build_dirs[src_dir] = build_dir
end
def execute(short_desc, command, extra_vars)
merged_variables = @variables.merge(extra_vars)
expand_varref = proc do |varref|
if varref.is_a?(Array)
varref.map do |ent|
expand_varref.call(ent)
end
else
if varref =~ /^(.*)\$\[(\w+)\](.*)$/
# expand array with given prefix, suffix
prefix, varname, suffix = $1, $2, $3
varval = merged_variables[varname]
unless varval.is_a?(Array)
raise "Array expected for $#{varname}"
end
varval.map {|e| "#{prefix}#{e}#{suffix}"}
elsif varref[0] == '$'
# expand a single variable reference
varname = varref[1, varref.size]
varval = merged_variables[varname]
if varval
expand_varref.call(varval)
else
raise "Could not find variable #{varname.inspect}"
end
else
varref
end
end
end
command = expand_varref.call(command.flatten).flatten
if @echo == :command
puts command.join(' ')
elsif @echo == :short
puts short_desc
end
system(*command)
end
def stem(fname)
fname.sub(/\.[^.]*$/, '')
end
alias_method :orig_method_missing, :method_missing
def method_missing(method, *args)
if @builders.has_key?(method.to_s)
# TODO: build sources if necessary
builder = @builders[method.to_s].new
builder.run(self, *args)
else
orig_method_missing(method, *args)
end
end
end
end