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!

Returns:
  • (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)

Returns:
  • (Boolean) -

Parameters:
  • directory (String, Pathname) --
def directory_empty?(directory)
  Pathname(directory).children.empty?
end

def execute!

Returns:
  • (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={})

Parameters:
  • 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!

Returns:
  • (void) -
def invoke!
  queue_current_paths if should_clean?
  execute!
  clean! if should_clean?
end

def queue_current_paths

Returns:
  • (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)

Returns:
  • (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?

Returns:
  • (Boolean) -
def should_clean?
  @config[:clean]
end