Browse files

Merge remote branch 'sos4nt/remove-orphaned-files'

  • Loading branch information...
2 parents 9bd4875 + 5b680f8 commit c1ed790534e6f0365fb5936beee8f4d0658f8694 @mojombo mojombo committed Dec 14, 2010
Showing with 94 additions and 26 deletions.
  1. +1 −0 History.txt
  2. +15 −14 lib/jekyll/page.rb
  3. +13 −10 lib/jekyll/post.rb
  4. +31 −0 lib/jekyll/site.rb
  5. +1 −2 lib/jekyll/static_file.rb
  6. +33 −0 test/test_site.rb
View
1 History.txt
@@ -3,6 +3,7 @@
* Use OptionParser's [no-] functionality for better boolean parsing.
* Add Drupal migrator (#245)
* Complain about YAML and Liquid errors (#249)
+ * Remove orphaned files during regeneration (#247)
== 0.8.0 / 2010-11-22
* Minor Enhancements
View
29 lib/jekyll/page.rb
@@ -93,24 +93,25 @@ def to_liquid
"url" => File.join(@dir, self.url),
"content" => self.content })
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.
- # +dest_prefix+ is the String path to the destination dir
- # +dest_suffix+ is a suffix path to the destination dir
+ # +dest+ is the String path to the destination dir
#
# Returns nothing
- def write(dest_prefix, dest_suffix = nil)
- dest = File.join(dest_prefix, @dir)
- dest = File.join(dest, dest_suffix) if dest_suffix
- 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
-
+ def write(dest)
+ path = destination(dest)
+ FileUtils.mkdir_p(File.dirname(path))
File.open(path, 'w') do |f|
f.write(self.output)
end
View
23 lib/jekyll/post.rb
@@ -177,22 +177,25 @@ def render(layouts, site_payload)
do_layout(payload, layouts)
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.
# +dest+ is the String path to the destination dir
#
# Returns nothing
def write(dest)
- FileUtils.mkdir_p(File.join(dest, dir))
-
- # 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
-
+ path = destination(dest)
+ FileUtils.mkdir_p(File.dirname(path))
File.open(path, 'w') do |f|
f.write(self.output)
end
View
31 lib/jekyll/site.rb
@@ -79,6 +79,7 @@ def process
self.read
self.generate
self.render
+ self.cleanup
self.write
end
@@ -151,6 +152,36 @@ def render
rescue Errno::ENOENT => e
# ignore missing layout dir
end
+
+ # Remove orphaned files and empty directories in destination
+ #
+ # Returns nothing
+ def cleanup
+ # all files and directories in destination, including hidden ones
@dashorst
dashorst added a line comment Dec 27, 2010

this is lethal when using SVN as a SCM instead of git. This removes the .svn folder in _site making it impossible to use jekyll in a SVN environment.

@beaucollins
beaucollins added a line comment Dec 27, 2010

You should be setting svn:ignore for your _site folder. You don't need to track it since it's generated.

@dashorst
dashorst added a line comment Dec 27, 2010

Not in a common usecase where _site is used by svnpubsub to push changes in SVN directly to a public_html folder where one doesn't get shell access, for example Wicket's website at apache.

@ivaynberg
ivaynberg added a line comment Jan 22, 2011

+1 to dashort's comments, i just got bitten by this as well. would be nice if jekyll would support an ignore list.

@geeksintraining
geeksintraining added a line comment Sep 26, 2011

Has anybody come up with a workaround? We need to use SVN to push production code live, and this will make it impossible to use Jekyll without extra 'intermediate' folders.

@ivaynberg
ivaynberg added a line comment Sep 26, 2011

$ cat regenerate.sh
#!/bin/bash

#workaround script for regenerating the site because jekyll completely wipes _site which causes problems for svn
echo Backing up .svn folders in _site
mkdir _tmp
tar cfT _tmp/archive.tar /dev/null
find _site -name ".svn"|xargs -I{} tar -rf _tmp/archive.tar {}
jekyll
echo Restoring .svn folders in _site
tar -xf _tmp/archive.tar
rm -rf _tmp

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ 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
#
View
3 lib/jekyll/static_file.rb
@@ -52,12 +52,11 @@ def modified?
# Returns false if the file was not modified since last time (no-op).
def write(dest)
dest_path = destination(dest)
- dest_dir = File.join(dest, @dir)
return false if File.exist? dest_path and !modified?
@@mtimes[path] = mtime
- FileUtils.mkdir_p(dest_dir)
+ FileUtils.mkdir_p(File.dirname(dest_path))
FileUtils.cp(path, dest_path)
true
View
33 test/test_site.rb
@@ -132,6 +132,39 @@ class TestSite < Test::Unit::TestCase
assert_equal includes, @site.filter_entries(excludes + includes)
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
should 'not throw an error at initialization time' do
bad_processor = 'not a processor name'

1 comment on commit c1ed790

@andyfowler

This seems to have broken all generators. How should a generator 'whitelist' files that it generates to prevent them from immediately being cleaned?

Please sign in to comment.