Refactor `Site#cleanup`

Move the cleanup logic out into a separate class,
`Jekyll::Cleaner`.
This commit is contained in:
maul.esel 2013-08-17 17:12:27 +02:00
parent ac4ca1edc3
commit 5da13d2b66
3 changed files with 73 additions and 39 deletions

View File

@ -42,6 +42,7 @@ require 'jekyll/filters'
require 'jekyll/static_file' require 'jekyll/static_file'
require 'jekyll/errors' require 'jekyll/errors'
require 'jekyll/related_posts' require 'jekyll/related_posts'
require 'jekyll/cleaner'
# extensions # extensions
require 'jekyll/plugin' require 'jekyll/plugin'

69
lib/jekyll/cleaner.rb Normal file
View File

@ -0,0 +1,69 @@
require 'set'
module Jekyll
# Handles the cleanup of a site's destination before the site is built.
class Cleaner
def initialize(site)
@site = site
end
# Cleans up the site's destination directory
def cleanup!
obsolete_files = existing_files - new_files - new_dirs + replaced_files
FileUtils.rm_rf(obsolete_files.to_a)
end
private
# Private: The list of existing files, except those included in keep_files and hidden files.
#
# Returns a Set with the file paths
def existing_files
files = Set.new
Dir.glob(File.join(@site.dest, "**", "*"), File::FNM_DOTMATCH) do |file|
if @site.keep_files.length > 0
files << file unless file =~ /\/\.{1,2}$/ || file =~ keep_file_regex
else
files << file unless file =~ /\/\.{1,2}$/
end
end
files
end
# Private: The list of files to be created when the site is built.
#
# Returns a Set with the file paths
def new_files
files = Set.new
@site.each_site_file { |item| files << item.destination(@site.dest) }
files
end
# Private: The list of directories to be created when the site is built.
# These are the parent directories of the files in #new_files.
#
# Returns a Set with the directory paths
def new_dirs
new_files.map { |file| File.dirname(file) }.to_set
end
# Private: The list of existing files that will be replaced by a directory during build
#
# Returns a Set with the file paths
def replaced_files
new_dirs.select { |dir| File.file?(dir) }.to_set
end
# Private: creates a regular expression from the config's keep_files array
#
# Examples
# ['.git','.svn'] creates the following regex: /\/(\.git|\/.svn)/
#
# Returns the regular expression
def keep_file_regex
or_list = @site.keep_files.join("|")
pattern = "\/(#{or_list.gsub(".", "\.")})"
Regexp.new pattern
end
end
end

View File

@ -1,5 +1,3 @@
require 'set'
module Jekyll module Jekyll
class Site class Site
attr_accessor :config, :layouts, :posts, :pages, :static_files, attr_accessor :config, :layouts, :posts, :pages, :static_files,
@ -89,6 +87,8 @@ module Jekyll
self.converters = instantiate_subclasses(Jekyll::Converter) self.converters = instantiate_subclasses(Jekyll::Converter)
self.generators = instantiate_subclasses(Jekyll::Generator) self.generators = instantiate_subclasses(Jekyll::Generator)
@site_cleaner = Cleaner.new(self)
end end
# Internal: Setup the plugin search path # Internal: Setup the plugin search path
@ -228,43 +228,7 @@ module Jekyll
# #
# Returns nothing. # Returns nothing.
def cleanup def cleanup
# all files and directories in destination, including hidden ones @site_cleaner.cleanup!
dest_files = Set.new
Dir.glob(File.join(self.dest, "**", "*"), File::FNM_DOTMATCH) do |file|
if self.keep_files.length > 0
dest_files << file unless file =~ /\/\.{1,2}$/ || file =~ keep_file_regex
else
dest_files << file unless file =~ /\/\.{1,2}$/
end
end
# files to be written
files = Set.new
each_site_file { |item| files << item.destination(self.dest) }
# adding files' parent directories
dirs = Set.new
files.each { |file| dirs << File.dirname(file) }
files.merge(dirs)
# files that are replaced by dirs should be deleted
files_to_delete = Set.new
dirs.each { |dir| files_to_delete << dir if File.file?(dir) }
obsolete_files = dest_files - files + files_to_delete
FileUtils.rm_rf(obsolete_files.to_a)
end
# Private: creates a regular expression from the keep_files array
#
# Examples
# ['.git','.svn'] creates the following regex: /\/(\.git|\/.svn)/
#
# Returns the regular expression
def keep_file_regex
or_list = self.keep_files.join("|")
pattern = "\/(#{or_list.gsub(".", "\.")})"
Regexp.new pattern
end end
# Write static files, pages, and posts. # Write static files, pages, and posts.