require 'fileutils' require 'erb' module PowerStencil module Engine module DirectoryProcessor include PowerStencil::Utils::DirectoryProcessor def render_source(source_dir, destination_dir, overwrite_files: false, main_entry_point: nil) compiled_universe = root_universe.compile scenario: config[:scenario] puts_and_logs 'Entities analysis completed.' logger.info 'Generating target...' setup_files_not_to_render source_dir setup_files_not_to_rename source_dir process_directory source: source_dir, destination: destination_dir, ignore_files_pattern: config[:ignore_filename_for_files_to_skip] do |src_file, dest_file| dest_file = detemplatized_file_name(dest_file, main_entry_point) unless main_entry_point.nil? if File.directory? src_file check_or_build_target_directory dest_file next else process_file src_file, dest_file, compiled_universe, overwrite_files: overwrite_files, main_entry_point: main_entry_point end end ensure @rendering_context = nil @files_not_to_render = nil end private def detemplatized_file_name(filename, replacement_text) replacement_text = replacement_text.tr '- /', '___' filename.gsub '{entity}', replacement_text end attr_reader :files_not_to_render, :files_not_to_rename def setup_files_not_to_render(source_dir) @files_not_to_render = DirGlobIgnore::IgnoreFileLists.new source_dir files_not_to_render.ignore_file_name = config[:ignore_filename_for_files_to_copy] files_not_to_render.load_ignore_files end def setup_files_not_to_rename(source_dir) @files_not_to_rename = DirGlobIgnore::IgnoreFileLists.new source_dir files_not_to_rename.ignore_file_name = config[:ignore_filename_for_files_to_rename] files_not_to_rename.load_ignore_files end def process_file(src_file, dest_file, universe, overwrite_files: false, main_entry_point: nil) unless files_not_to_rename.ignore_file? src_file config[:file_renaming_patterns].each do |regexp_str, replacement| regexp = Regexp.new regexp_str next if (src_file =~ regexp).nil? dest_file = dest_file.gsub regexp, replacement break end end if File.exist? dest_file unless overwrite_files logger.info "Skipping file '#{dest_file}'..." return end end check_or_build_target_directory File.dirname dest_file source_mode = File.stat(src_file).mode File.open(dest_file, 'w') do |f| if files_not_to_render.ignore_file? src_file logger.debug "Copying file '#{src_file}' to '#{dest_file}' (ignored for substitutions)." f.write File.read src_file else logger.debug "Rendering file '#{src_file}' to '#{dest_file}'." f.write render_template(src_file, universe, main_entry_point: main_entry_point) end end File.chmod source_mode, dest_file end def check_or_build_target_directory(dir) FileUtils.mkpath dir end def render_template(source, universe, main_entry_point: nil) config[:templating_engines_map].each do |engine_name, file_pattern| unless (source =~ /#{file_pattern}/).nil? templating_engine_method_name = "render_#{engine_name}_template".to_sym unless private_methods.include? templating_engine_method_name raise PowerStencil::Error, "File '#{source}' is supposed to be rendered using '#{engine_name}', but seems not to be supported !" end context = running_context universe, main_entry_point: main_entry_point begin return send templating_engine_method_name, source, context rescue StandardError, SyntaxError => e logger.puts_and_logs "Error rendering #{engine_name} template '#{source}'", logs_as: :error, check_verbose: false raise e end end end logger.warn "File '#{source}' was supposed to be processed but there is no template engine defined ! Applying simple copy." File.read source end end end end