class Middleman::Cli::BuildAction
A Thor Action, modular code, which does the majority of the work.
def binary_encode(string)
def binary_encode(string) string.force_encoding('ascii-8bit') if string.respond_to?(:force_encoding) string end
def build_resource(resource)
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
def clean!
-
(void)
-
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
def directory_empty?(directory)
-
(Boolean)
-
Parameters:
-
directory
(String, Pathname
) --
def directory_empty?(directory) Pathname(directory).children.empty? end
def execute!
-
(void)
-
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
def handle_error(file_name, response, e=Thor::Error.new(response))
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
def initialize(base, config={})
-
config
(Hash
) -- -
base
(Middleman::Cli::Build
) --
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
def invoke!
-
(void)
-
def invoke! queue_current_paths if should_clean? execute! clean! if should_clean? end
def queue_current_paths
-
(void)
-
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
def render_to_file(resource)
-
(Pathname)
- The full path of the file that was written
Parameters:
-
resource
(Middleman::Sitemap::Resource
) --
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
def should_clean?
-
(Boolean)
-
def should_clean? @config[:clean] end