require 'singleton' require 'hash_deep_merge' require 'digest/md5' require 'json' module Docman class Config < Hash attr_reader :unmutable_config @loaded_scenario_sources def initialize(file) super @config = YAML::load_file(file) @loaded_scenario_sources = {} assign_to_self end def assign_to_self @config.each_pair do |k, v| self[k] = v end @unmutable_config = Marshal::load(Marshal.dump(@config)) end def normalize_config(config) temp_config = {} @config['uniconf'][@config_version]['keys'].each{|key,value| temp_config[value] (1..@config_version).each {|version| if config.has_key?(@config['uniconf'][version]['keys'][key]) tc = {} tc[value] = config[@config['uniconf'][version]['keys'][key]] config.delete(@config['uniconf'][version]['keys'][key]) temp_config.deep_merge!(tc) end } } return temp_config.deep_merge!(config) end def merge_config_from_file(docroot_dir, docroot_config_dir, config_file, options = nil) file = File.join(docroot_config_dir, config_file) if File.file?(file) yaml = YAML::load_file(file) @config_version = 1 if yaml.has_key?('config_version') @config_version = yaml['config_version'] end config = normalize_config(yaml) if config.has_key?(@config['uniconf'][@config_version]['keys']['include']) scenarios_path = File.join(docroot_dir, '.docman/scenarios') `rm -fR #{scenarios_path}` if File.directory? scenarios_path `mkdir -p #{scenarios_path}` unless config.has_key?(@config['uniconf'][@config_version]['keys']['sources']) config[@config['uniconf'][@config_version]['keys']['sources']] = {} end if ENV.has_key?('UNIPIPE_SOURCES') unipipe_sources = ENV['UNIPIPE_SOURCES'] puts "UNIPIPE_SOURCES: #{unipipe_sources}" sources = {} sources[@config['uniconf'][@config_version]['keys']['sources']] = JSON.parse(unipipe_sources) puts "UNIPIPE_SOURCES PARSED: #{sources}" config.deep_merge(sources) else puts "UNIPIPE_SOURCES not defined in environment. Additional sources may be not available." end config[@config['uniconf'][@config_version]['keys']['sources']]['root_config'] = {} config[@config['uniconf'][@config_version]['keys']['sources']]['root_config']['dir'] = docroot_config_dir @loaded_scenario_sources['root_config'] = config[@config['uniconf'][@config_version]['keys']['sources']]['root_config'] config = merge_scenarios_configs(config, {}, scenarios_path, 'root_config') end end unless config.nil? unless config['override_docman_default'].nil? self.clear @config = config else @config.deep_merge!(config) end @config['version'] = config['version'].nil? ? 1 : config['version'] end assign_to_self end def merge_scenarios_configs(config, temp_config = {}, scenarios_path = '', current_scenario_source_name = '') temp_config.deep_merge!(config) scenarios_config = {} if config.has_key?(@config['uniconf'][@config_version]['keys']['include']) config[@config['uniconf'][@config_version]['keys']['include']].each do |s| scenario = {} if s.is_a? String values = s.split(':') if values.size() > 1 scenario_source_name = values[0] scenario_name = values[1] else scenario_source_name = current_scenario_source_name scenario_name = values[0] end scenario['name'] = scenario_name if temp_config[@config['uniconf'][@config_version]['keys']['sources']].has_key?(scenario_source_name) scenario_source_path = File.join(scenarios_path, scenario_source_name) if temp_config[@config['uniconf'][@config_version]['keys']['sources']][scenario_source_name].has_key?('dir') and not temp_config[@config['uniconf'][@config_version]['keys']['sources']][scenario_source_name]['dir'].nil? scenario_source_path = temp_config[@config['uniconf'][@config_version]['keys']['sources']][scenario_source_name]['dir'] end if @loaded_scenario_sources.key? scenario_source_name scenario['source'] = @loaded_scenario_sources[scenario_source_name] else `rm -fR #{scenario_source_path}` if File.directory? scenario_source_path scenario['source'] = temp_config[@config['uniconf'][@config_version]['keys']['sources']][scenario_source_name] scenario['source']['ref'] = scenario['source']['ref'] ? scenario['source']['ref'] : 'master' GitUtil.clone_repo(scenario['source']['repo'], scenario_source_path, 'branch', scenario['source']['ref'], true, 1) @loaded_scenario_sources[scenario_source_name] = scenario['source'] end scenario_config_file = File.join(scenario_source_path, @config['uniconf'][@config_version]['dirs']['sources'], scenario['name'], 'config.yaml') if File.file? scenario_config_file lyaml = YAML::load_file(scenario_config_file) nyaml = normalize_config(lyaml) scenario_config = merge_scenarios_configs(nyaml, temp_config, scenarios_path, scenario_source_name) scenarios_config.deep_merge!(scenario_config) puts "Loaded scenario #{scenario['name']} from source #{scenario_source_name}" end end end end end scenarios_config.deep_merge!(config) end def config_hash Digest::MD5.hexdigest(Marshal::dump(@unmutable_config)) end def version @config['version'] end end end