class Middleman::Cli::BuildAction
A Thor
Action, modular code, which does the majority of the work.
Attributes
logger[R]
source[R]
Public Class Methods
new(base, config={})
click to toggle source
Setup the action
@param [Middleman::Cli::Build] base @param [Hash] config
Calls superclass method
# File lib/middleman-core/cli/build.rb, line 112 def initialize(base, config={}) @app = base.class.shared_instance @source_dir = Pathname(@app.source_dir) @build_dir = Pathname(@app.build_dir) @to_clean = Set.new @logger = @app.logger @rack = ::Rack::Test::Session.new(@app.class.to_rack_app) super(base, @build_dir, config) end
Public Instance Methods
invoke!()
click to toggle source
Execute the action @return [void]
# File lib/middleman-core/cli/build.rb, line 126 def invoke! queue_current_paths if should_clean? execute! clean! if should_clean? end
Protected Instance Methods
binary_encode(string)
click to toggle source
# File lib/middleman-core/cli/build.rb, line 281 def binary_encode(string) string.force_encoding('ascii-8bit') if string.respond_to?(:force_encoding) string end
build_resource(resource)
click to toggle source
# File lib/middleman-core/cli/build.rb, line 218 def build_resource(resource) return if @config[:glob] && !File.fnmatch(@config[:glob], resource.destination_path) output_path = render_to_file(resource) return unless should_clean? && output_path.exist? if RUBY_PLATFORM =~ /darwin/ # handle UTF-8-MAC filename on MacOS @to_clean.delete(output_path.realpath.to_s.encode('UTF-8', 'UTF-8-MAC')) else @to_clean.delete(output_path.realpath) end end
clean!()
click to toggle source
Remove files which were not built in this cycle @return [void]
# File lib/middleman-core/cli/build.rb, line 136 def clean! @to_clean.each do |f| base.remove_file f, force: true end Dir[@build_dir.join('**', '*')].select { |d| File.directory?(d) }.each do |d| base.remove_file d, force: true if directory_empty? d end end
directory_empty?(directory)
click to toggle source
Whether the given directory is empty @param [String, Pathname] directory @return [Boolean]
# File lib/middleman-core/cli/build.rb, line 155 def directory_empty?(directory) Pathname(directory).children.empty? end
execute!()
click to toggle source
Actually build the app @return [void]
# File lib/middleman-core/cli/build.rb, line 179 def execute! # Sort order, images, fonts, js/css and finally everything else. sort_order = %w(.png .jpeg .jpg .gif .bmp .svg .svgz .ico .woff .otf .ttf .eot .js .css) # Pre-request CSS to give Compass a chance to build sprites logger.debug '== Prerendering CSS' @app.sitemap.resources.select do |resource| resource.ext == '.css' end.each(&method(:build_resource)) logger.debug '== Checking for Compass sprites' # Double-check for compass sprites @app.files.find_new_files((@source_dir + @app.images_dir).relative_path_from(@app.root_path)) @app.sitemap.ensure_resource_list_updated! # Sort paths to be built by the above order. This is primarily so Compass can # find files in the build folder when it needs to generate sprites for the # css files logger.debug '== Building files' resources = @app.sitemap.resources.sort_by do |r| sort_order.index(r.ext) || 100 end if @build_dir.expand_path.relative_path_from(@source_dir).to_s =~ /\A[.\/]+\Z/ raise ":build_dir (#{@build_dir}) cannot be a parent of :source_dir (#{@source_dir})" end # Loop over all the paths and build them. resources.reject do |resource| resource.ext == '.css' end.each(&method(:build_resource)) ::Middleman::Profiling.report('build') end
handle_error(file_name, response, e=Thor::Error.new(response))
click to toggle source
# File lib/middleman-core/cli/build.rb, line 270 def handle_error(file_name, response, e=Thor::Error.new(response)) base.had_errors = true base.say_status :error, file_name, :red if base.debugging raise e elsif base.options['verbose'] base.shell.say response, :red end end
queue_current_paths()
click to toggle source
Get a list of all the file paths in the destination folder and save them for comparison against the files we build in this cycle @return [void]
# File lib/middleman-core/cli/build.rb, line 162 def queue_current_paths return unless File.exist?(@build_dir) paths = ::Middleman::Util.all_files_under(@build_dir).map(&:realpath).select(&:file?) @to_clean += paths.select do |path| path.to_s !~ /\/\./ || path.to_s =~ /\.(htaccess|htpasswd)/ end return unless RUBY_PLATFORM =~ /darwin/ # handle UTF-8-MAC filename on MacOS @to_clean = @to_clean.map { |path| path.to_s.encode('UTF-8', 'UTF-8-MAC') } end
render_to_file(resource)
click to toggle source
Render a resource to a file.
@param [Middleman::Sitemap::Resource] resource @return [Pathname] The full path of the file that was written
# File lib/middleman-core/cli/build.rb, line 238 def render_to_file(resource) output_file = @build_dir + resource.destination_path.gsub('%20', ' ') if resource.binary? if !output_file.exist? base.say_status :create, output_file, :green elsif FileUtils.compare_file(resource.source_file, output_file) base.say_status :identical, output_file, :blue return output_file else base.say_status :update, output_file, :yellow end output_file.dirname.mkpath FileUtils.cp(resource.source_file, output_file) else begin response = @rack.get(URI.escape(resource.request_path)) if response.status == 200 base.create_file(output_file, binary_encode(response.body)) else handle_error(output_file, response.body) end rescue => e handle_error(output_file, "#{e}\n#{e.backtrace.join("\n")}", e) end end output_file end
should_clean?()
click to toggle source
Whether we should clean the build @return [Boolean]
# File lib/middleman-core/cli/build.rb, line 148 def should_clean? @config[:clean] end