remove orphaned files in destination

This commit is contained in:
Stefan Schüßler 2010-12-01 17:25:56 +01:00
parent 31901ee15b
commit 5b680f8dd8
5 changed files with 93 additions and 26 deletions

View File

@ -94,23 +94,24 @@ module Jekyll
"content" => self.content }) "content" => self.content })
end end
# Obtain destination path.
# +dest+ is the String path to the destination dir
#
# Returns destination file path.
def destination(dest)
# The url needs to be unescaped in order to preserve the correct filename
path = File.join(dest, @dir, CGI.unescape(self.url))
path = File.join(path, "index.html") if self.url =~ /\/$/
path
end
# Write the generated page file to the destination directory. # Write the generated page file to the destination directory.
# +dest_prefix+ is the String path to the destination dir # +dest+ is the String path to the destination dir
# +dest_suffix+ is a suffix path to the destination dir
# #
# Returns nothing # Returns nothing
def write(dest_prefix, dest_suffix = nil) def write(dest)
dest = File.join(dest_prefix, @dir) path = destination(dest)
dest = File.join(dest, dest_suffix) if dest_suffix FileUtils.mkdir_p(File.dirname(path))
FileUtils.mkdir_p(dest)
# The url needs to be unescaped in order to preserve the correct filename
path = File.join(dest, CGI.unescape(self.url))
if self.url =~ /\/$/
FileUtils.mkdir_p(path)
path = File.join(path, "index.html")
end
File.open(path, 'w') do |f| File.open(path, 'w') do |f|
f.write(self.output) f.write(self.output)
end end

View File

@ -178,21 +178,24 @@ module Jekyll
do_layout(payload, layouts) do_layout(payload, layouts)
end end
# Obtain destination path.
# +dest+ is the String path to the destination dir
#
# Returns destination file path.
def destination(dest)
# The url needs to be unescaped in order to preserve the correct filename
path = File.join(dest, CGI.unescape(self.url))
path = File.join(path, "index.html") if template[/\.html$/].nil?
path
end
# Write the generated post file to the destination directory. # Write the generated post file to the destination directory.
# +dest+ is the String path to the destination dir # +dest+ is the String path to the destination dir
# #
# Returns nothing # Returns nothing
def write(dest) def write(dest)
FileUtils.mkdir_p(File.join(dest, dir)) path = destination(dest)
FileUtils.mkdir_p(File.dirname(path))
# The url needs to be unescaped in order to preserve the correct filename
path = File.join(dest, CGI.unescape(self.url))
if template[/\.html$/].nil?
FileUtils.mkdir_p(path)
path = File.join(path, "index.html")
end
File.open(path, 'w') do |f| File.open(path, 'w') do |f|
f.write(self.output) f.write(self.output)
end end

View File

@ -79,6 +79,7 @@ module Jekyll
self.read self.read
self.generate self.generate
self.render self.render
self.cleanup
self.write self.write
end end
@ -152,6 +153,36 @@ module Jekyll
# ignore missing layout dir # ignore missing layout dir
end end
# Remove orphaned files and empty directories in destination
#
# Returns nothing
def cleanup
# all files and directories in destination, including hidden ones
dest_files = []
Dir.glob(File.join(self.dest, "**", "*"), File::FNM_DOTMATCH) do |file|
dest_files << file unless file =~ /\/\.{1,2}$/
end
# files to be written
files = []
self.posts.each do |post|
files << post.destination(self.dest)
end
self.pages.each do |page|
files << page.destination(self.dest)
end
self.static_files.each do |sf|
files << sf.destination(self.dest)
end
# adding files' parent directories
files.each { |file| files << File.dirname(file) unless files.include? File.dirname(file) }
obsolete_files = dest_files - files
FileUtils.rm_rf(obsolete_files)
end
# Write static files, pages and posts # Write static files, pages and posts
# #
# Returns nothing # Returns nothing

View File

@ -52,12 +52,11 @@ module Jekyll
# Returns false if the file was not modified since last time (no-op). # Returns false if the file was not modified since last time (no-op).
def write(dest) def write(dest)
dest_path = destination(dest) dest_path = destination(dest)
dest_dir = File.join(dest, @dir)
return false if File.exist? dest_path and !modified? return false if File.exist? dest_path and !modified?
@@mtimes[path] = mtime @@mtimes[path] = mtime
FileUtils.mkdir_p(dest_dir) FileUtils.mkdir_p(File.dirname(dest_path))
FileUtils.cp(path, dest_path) FileUtils.cp(path, dest_path)
true true

View File

@ -132,6 +132,39 @@ class TestSite < Test::Unit::TestCase
assert_equal includes, @site.filter_entries(excludes + includes) assert_equal includes, @site.filter_entries(excludes + includes)
end end
context 'with orphaned files in destination' do
setup do
clear_dest
@site.process
# generate some orphaned files:
# hidden file
File.open(dest_dir('.htpasswd'), 'w')
# single file
File.open(dest_dir('obsolete.html'), 'w')
# single file in sub directory
FileUtils.mkdir(dest_dir('qux'))
File.open(dest_dir('qux/obsolete.html'), 'w')
# empty directory
FileUtils.mkdir(dest_dir('quux'))
end
teardown do
FileUtils.rm_f(dest_dir('.htpasswd'))
FileUtils.rm_f(dest_dir('obsolete.html'))
FileUtils.rm_rf(dest_dir('qux'))
FileUtils.rm_f(dest_dir('quux'))
end
should 'remove orphaned files in destination' do
@site.process
assert !File.exist?(dest_dir('.htpasswd'))
assert !File.exist?(dest_dir('obsolete.html'))
assert !File.exist?(dest_dir('qux'))
assert !File.exist?(dest_dir('quux'))
end
end
context 'with an invalid markdown processor in the configuration' do context 'with an invalid markdown processor in the configuration' do
should 'not throw an error at initialization time' do should 'not throw an error at initialization time' do
bad_processor = 'not a processor name' bad_processor = 'not a processor name'