require 'application' require 'fileutils' require 'docman/info' module Docman class DocrootConfig attr_reader :structure, :deploy_target, :docroot_dir, :docroot_config_dir, :config_dir, :root, :raw_infos def initialize(docroot_dir, deploy_target_name = nil, options = nil) @override = {} if options && options['config'] @override = JSON.parse(options['config']) end @docroot_dir = docroot_dir #@deploy_target = deploy_target @docroot_config_dir = File.join(docroot_dir, 'config') Dir.chdir @docroot_config_dir update('origin') config_files = Docman::Application.instance.config_dirs(options).collect{|item| File.join(@docroot_config_dir, item, 'config.{yaml,yml}') } config_file_path = Dir.glob(config_files).first raise "Configuration file config.{yaml,yml} not found." if config_file_path.nil? @config_dir = File.dirname(config_file_path) @config_file = File.basename(config_file_path) Docman::Application.instance.config.merge_config_from_file(docroot_dir, @config_dir, @config_file, options) if deploy_target_name @deploy_target = Application.instance.config['deploy_targets'][deploy_target_name] raise "Wrong deploy target: #{deploy_target_name}" if @deploy_target.nil? @deploy_target['name'] = deploy_target_name end @names = {} @raw_infos = {} master_file = File.join(@docroot_config_dir, 'master') if File.directory? master_file @structure = structure_build(File.join(@docroot_config_dir, 'master')) else @structure = structure_build_from_config_file(File.join(@docroot_config_dir, 'master')) end end def update(options = '') Dir.chdir @docroot_config_dir GitUtil.exec("reset --hard", false) branch = GitUtil.branch GitUtil.update @docroot_config_dir, "#{options} #{branch.strip}" end def structure_build_from_config_file(path, prefix = '', parent = nil, parent_key = 'master') config = Docman::Application.instance.config return if config['components'][parent_key].nil? children = [] info = config['components'][parent_key] @raw_infos[parent_key] = info unless info['status'].nil? return if info['status'] == 'disabled' end name = parent_key prefix = prefix.size > 0 ? File.join(prefix, name) : name info['full_path'] = path info['docroot_config'] = self info['build_path'] = prefix info['full_build_path'] = File.join(@docroot_dir, prefix) info['temp_path'] = File.join(@docroot_dir, '.docman/tmp', info['build_path']) info['states_path'] = File.join(@docroot_dir, '.docman/states', info['build_path']) info['name'] = name info['parent'] = parent info['order'] = info.has_key?('order') ? info['order'] : 10 info['children'] = children if @override['projects'] && @override['projects'].key?(info['name']) info.merge! @override['projects'][info['name']] end i = Docman::Info.new(info) @root = i if parent.nil? i['root'] = @root @names[name.to_s] = i # Dir.foreach(path) do |entry| # next if (entry == '..' || entry == '.') # full_path = File.join(path, entry) # if File.directory?(full_path) # dir_hash = structure_build(full_path, prefix, i) # unless dir_hash == nil # children << dir_hash # end # end # end i end def structure_build(path, prefix = '', parent = nil) return unless File.file? File.join(path, 'info.yaml') children = [] info = YAML::load_file(File.join(path, 'info.yaml')) @raw_infos[File.basename path] = YAML::load_file(File.join(path, 'info.yaml')) unless info['status'].nil? return if info['status'] == 'disabled' end name = File.basename path prefix = prefix.size > 0 ? File.join(prefix, name) : name info['full_path'] = path info['docroot_config'] = self info['build_path'] = prefix info['full_build_path'] = File.join(@docroot_dir, prefix) info['temp_path'] = File.join(@docroot_dir, '.docman/tmp', info['build_path']) info['states_path'] = File.join(@docroot_dir, '.docman/states', info['build_path']) info['name'] = name info['parent'] = parent info['order'] = info.has_key?('order') ? info['order'] : 10 info['children'] = children if @override['projects'] && @override['projects'].key?(info['name']) info.merge! @override['projects'][info['name']] end i = Docman::Info.new(info) @root = i if parent.nil? i['root'] = @root @names[name.to_s] = i Dir.foreach(path) do |entry| next if (entry == '..' || entry == '.') full_path = File.join(path, entry) if File.directory?(full_path) dir_hash = structure_build(full_path, prefix, i) unless dir_hash == nil children << dir_hash end end end i end def chain(info) chain = {} chain[info['name']] = info while info['parent'] do chain[info['parent']['name']] = info['parent'] info = info['parent'] end Hash[chain.to_a.reverse!] end def info_by(name) @names[name] end def project(name) raise "There is no project with name '#{name}' exists in config" unless @names.has_key? name @names[name] end def states_dependin_on(name, version) states = {} project(name).states.each do |state, info| states[state] = info if info['version'] == version end states end def config_hash Digest::MD5.hexdigest(Marshal::dump(@raw_infos)) end def deploy_target_name @deploy_target.name end end end