module PowerStencil module Engine module BuildHandling include Climatic::Utils::SafeExec attr_reader :last_build_report def build(entities_to_build, fail_on_error: false, parallelized: false) logger.debug 'Starting build process...' raise PowerStencil::Error, 'Parallel builds are not yet supported !' if parallelized build_target_seed = entities_to_build.map(&:as_path).map do |entity_full_name| entity_full_name.tr '/', '_' end .join '_' build_target_path = project.build_run_path build_target_seed @last_build_report = {} entities_to_build.each do |entity_to_build| begin entity_build_report = [] unless entity_to_build.buildable? msg = "Entity '#{entity_to_build.as_path}' is not buildable !" entity_build_report << msg raise PowerStencil::Error, msg end build_entity_target_path = if config[:'target-path'] specified_target_path = File.expand_path config[:'target-path'] if File.exists? specified_target_path raise PowerStencil::Error, "Specified target path '#{specified_target_path}' already exists ! Aborting..." end specified_target_path else File.join build_target_path, entity_to_build.as_path.tr('/', '_') end build_entity entity_to_build, build_entity_target_path entity_build_report << 'Ok' rescue SyntaxError, StandardError => e entity_build_report << e.message if fail_on_error raise e else logger.debug PowerStencil::Error.report_error e end ensure last_build_report[entity_to_build.as_path] = entity_build_report end end end def generate_build_files(entity_to_build, target_path) logger.info "Rendering '#{entity_to_build.as_path}' templates in '#{target_path}'" render_source entity_to_build.templates_path, target_path, main_entry_point: entity_to_build.as_path logger.info "Detemplatized files generated in '#{target_path}'" manage_build_links target_path end def post_build_hook(entity_to_build, files_path) case entity_to_build.type when :simple_exec script_to_execute = File.expand_path File.join(files_path, entity_to_build.post_process.process) exec_options = {message: "Running '#{script_to_execute}'"} exec_options[:show_output] = true if config[:verbose] process_report = safely_exec_command "'#{script_to_execute}'", exec_options unless process_report.exit_status.exitstatus == 0 raise PowerStencil::Error, "Process `#{process_report.command}` failed and returned exit code '#{process_report.exit_status.exitstatus}'" end process_report end end private def manage_build_links(last_build_path) if PowerStencil::Utils::Os.windows? logger.info 'Cannot create link to last build folder under Windows !' return end last_build_link_path = project.last_build_stable_link_path previous_build_link_path = project.previous_build_stable_link_path current_last_build_link_target_path = (File.symlink? last_build_link_path) ? File.readlink(last_build_link_path) : nil safely_remove_link previous_build_link_path unless current_last_build_link_target_path.nil? File.symlink current_last_build_link_target_path, previous_build_link_path unless File.exists? previous_build_link_path end safely_remove_link last_build_link_path File.symlink last_build_path, last_build_link_path unless File.exists? last_build_link_path if config[:'tag-build'] build_tag_path = File.join project.build_root_path, config[:'tag-build'] safely_remove_link build_tag_path File.symlink last_build_path, build_tag_path unless File.exists? build_tag_path end end def safely_remove_link(link) if File.exists? link if File.symlink? link File.unlink link else logger.warn "Warning '#{link}' is not a symlink !!" return false end else logger.debug "No file/link to delete ('#{link}')" end true end def build_entity(entity_to_build, target_path) initial_directory = Dir.pwd target_plugin_name = entity_to_build.buildable_by.to_s # Files generation if target_plugin_name.empty? generate_build_files entity_to_build, target_path else target_plugin = project.plugins[target_plugin_name] raise PowerStencil::Error, "Could not find plugin '#{target_plugin_name}' !" if target_plugin.nil? if target_plugin.capabilities[:generate_build_files] target_plugin.generate_build_files entity_to_build, target_path else logger.info 'Falling back to PowerStencil core build files generation process...' generate_build_files entity_to_build, target_path end end # Post processing executed from generated directory (#11) Dir.chdir target_path # Post generation action if target_plugin_name.empty? post_build_hook entity_to_build, target_path else target_plugin = project.plugins[target_plugin_name] raise PowerStencil::Error, "Could not find plugin '#{target_plugin_name}' !" if target_plugin.nil? raise PowerStencil::Error, "Plugin '#{target_plugin_name}' has no post build capability !" unless target_plugin.capabilities[:post_build] target_plugin.post_build_hook entity_to_build, target_path end ensure Dir.chdir initial_directory end end end end