From 04baeefaa8d922e8d99c3b2abf59b5c3a1e22a9b Mon Sep 17 00:00:00 2001 From: Renaud Martinet Date: Tue, 27 May 2014 18:06:52 +0200 Subject: [PATCH 1/3] Make sure Cleaner doesn't remove dirs if they only contain subdirs Closes #2204 --- lib/jekyll/cleaner.rb | 14 +++++++++++++- test/test_cleaner.rb | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 test/test_cleaner.rb diff --git a/lib/jekyll/cleaner.rb b/lib/jekyll/cleaner.rb index 583fc844..ec385cbc 100644 --- a/lib/jekyll/cleaner.rb +++ b/lib/jekyll/cleaner.rb @@ -49,7 +49,19 @@ module Jekyll # # Returns a Set with the directory paths def new_dirs - new_files.map { |file| File.dirname(file) }.to_set + new_files.map { |file| parent_dirs(file) }.flatten.to_set + end + + # Private: The list of parent directories of a given file + # + # Returns an Array with the directory paths + def parent_dirs(file) + parent_dir = File.dirname(file) + if parent_dir == site.dest + return [] + else + return [parent_dir] + parent_dirs(parent_dir) + end end # Private: The list of existing files that will be replaced by a directory during build diff --git a/test/test_cleaner.rb b/test/test_cleaner.rb new file mode 100644 index 00000000..968d8f67 --- /dev/null +++ b/test/test_cleaner.rb @@ -0,0 +1,38 @@ +require 'helper' + +class TestCleaner < Test::Unit::TestCase + context "directory containing no files and non-empty directories" do + setup do + clear_dest + stub(Jekyll).configuration do + Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir}) + end + + FileUtils.mkdir_p(source_dir('no_files_inside/child_dir')) + FileUtils.touch(File.join(source_dir('no_files_inside/child_dir'), 'index.html')) + + @site = Site.new(Jekyll.configuration) + @site.process + + @cleaner = Site::Cleaner.new(@site) + @cleaner.cleanup! + end + + teardown do + FileUtils.rm_rf(source_dir('no_files_inside')) + FileUtils.rm_rf(dest_dir('no_files_inside')) + end + + should "keep the parent directory" do + assert File.exist?(dest_dir('no_files_inside')) + end + + should "keep the child directory" do + assert File.exist?(dest_dir('no_files_inside/child_dir')) + end + + should "keep the file" do + assert File.exist?(File.join(dest_dir('no_files_inside/child_dir'), 'index.html')) + end + end +end From 72c410363c0774e7eb80314e923c979a05717b91 Mon Sep 17 00:00:00 2001 From: Renaud Martinet Date: Tue, 27 May 2014 18:10:15 +0200 Subject: [PATCH 2/3] Keep parents of directories in keep_files Closes #1297 --- lib/jekyll/cleaner.rb | 10 +++++++++- test/test_cleaner.rb | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/lib/jekyll/cleaner.rb b/lib/jekyll/cleaner.rb index ec385cbc..1d1519ba 100644 --- a/lib/jekyll/cleaner.rb +++ b/lib/jekyll/cleaner.rb @@ -30,7 +30,7 @@ module Jekyll def existing_files files = Set.new Dir.glob(File.join(site.dest, "**", "*"), File::FNM_DOTMATCH) do |file| - files << file unless file =~ /\/\.{1,2}$/ || file =~ keep_file_regex + files << file unless file =~ /\/\.{1,2}$/ || file =~ keep_file_regex || keep_dirs.include?(file) end files end @@ -71,6 +71,14 @@ module Jekyll new_dirs.select { |dir| File.file?(dir) }.to_set end + # Private: The list of directories that need to be kept because they are parent directories + # of files specified in keep_files + # + # Returns a Set with the directory paths + def keep_dirs + site.keep_files.map{|file| parent_dirs(File.join(site.dest, file))}.flatten.to_set + end + # Private: Creates a regular expression from the config's keep_files array # # Examples diff --git a/test/test_cleaner.rb b/test/test_cleaner.rb index 968d8f67..e9bcc0f5 100644 --- a/test/test_cleaner.rb +++ b/test/test_cleaner.rb @@ -1,6 +1,45 @@ require 'helper' class TestCleaner < Test::Unit::TestCase + context "directory in keep_files" do + setup do + clear_dest + stub(Jekyll).configuration do + Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir}) + end + + FileUtils.mkdir_p(dest_dir('to_keep/child_dir')) + FileUtils.touch(File.join(dest_dir('to_keep'), 'index.html')) + FileUtils.touch(File.join(dest_dir('to_keep/child_dir'), 'index.html')) + + @site = Site.new(Jekyll.configuration) + @site.keep_files = ['to_keep/child_dir'] + + @cleaner = Site::Cleaner.new(@site) + @cleaner.cleanup! + end + + teardown do + FileUtils.rm_rf(dest_dir('to_keep')) + end + + should "keep the parent directory" do + assert File.exist?(dest_dir('to_keep')) + end + + should "keep the child directory" do + assert File.exist?(dest_dir('to_keep/child_dir')) + end + + should "keep the file in the directory in keep_files" do + assert File.exist?(File.join(dest_dir('to_keep/child_dir'), 'index.html')) + end + + should "delete the file in the directory not in keep_files" do + assert !File.exist?(File.join(dest_dir('to_keep'), 'index.html')) + end + end + context "directory containing no files and non-empty directories" do setup do clear_dest From a324eafac4bcb965099de67b31aa9969c27b8e4e Mon Sep 17 00:00:00 2001 From: Renaud Martinet Date: Fri, 30 May 2014 08:46:31 +0200 Subject: [PATCH 3/3] Using implicit returns to conform to coding style --- lib/jekyll/cleaner.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/jekyll/cleaner.rb b/lib/jekyll/cleaner.rb index 1d1519ba..0aa3cdfd 100644 --- a/lib/jekyll/cleaner.rb +++ b/lib/jekyll/cleaner.rb @@ -58,9 +58,9 @@ module Jekyll def parent_dirs(file) parent_dir = File.dirname(file) if parent_dir == site.dest - return [] + [] else - return [parent_dir] + parent_dirs(parent_dir) + [parent_dir] + parent_dirs(parent_dir) end end