diff --git a/.travis.yml b/.travis.yml index 416e8f3a..b6b39b7d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,6 @@ +language: ruby rvm: - 1.9.3 - 1.9.2 - 1.8.7 +script: bundle exec rake diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..fa6fb807 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,45 @@ +Contribute +========== + +So you've got an awesome idea to throw into Jekyll. Great! Please keep the following in mind: + +* **Contributions will not be accepted without tests.** +* If you're creating a small fix or patch to an existing feature, just a simple test will do. Please stay in the confines of the current test suite and use [Shoulda](http://github.com/thoughtbot/shoulda/tree/master) and [RR](http://github.com/btakita/rr/tree/master). +* If it's a brand new feature, make sure to create a new [Cucumber](https://github.com/cucumber/cucumber/) feature and reuse steps where appropriate. Also, whipping up some documentation in your fork's wiki would be appreciated, and once merged it will be transferred over to the main wiki. + +Test Dependencies +----------------- + +To run the test suite and build the gem you'll need to install Jekyll's dependencies. Jekyll uses Bundler, so a quick run of the bundle command and you're all set! + + $ bundle + +Before you start, run the tests and make sure that they pass (to confirm your environment is configured properly): + + $ rake test + $ rake features + +Workflow +-------- + +Here's the most direct way to get your work merged into the project: +* Fork the project +* Clone down your fork ( `git clone git://github.com//jekyll.git` ) +* Create a topic branch to contain your change ( `git checkout -b my_awesome_feature` ) +* Hack away, add tests. Not necessarily in that order. +* Make sure everything still passes by running `rake` +* If necessary, rebase your commits into logical chunks, without errors +* Push the branch up ( `git push origin my_awesome_feature` ) +* Create an issue with a description and link to your branch + +Gotchas +------- + +* If you want to bump the gem version, please put that in a separate commit. This way, the maintainers can control when the gem gets released. +* Try to keep your patch(es) based from the latest commit on mojombo/jekyll. The easier it is to apply your work, the less work the maintainers have to do, which is always a good thing. +* Please don't tag your GitHub issue with [fix], [feature], etc. The maintainers actively read the issues and will label it once they come across it. + +Finally... +---------- + +Thanks! Hacking on Jekyll should be fun, and if for some reason it's a pain to do let us know so we can fix it. diff --git a/History.txt b/History.txt index d65aad87..260c2661 100644 --- a/History.txt +++ b/History.txt @@ -1,5 +1,7 @@ == HEAD * Minor Enhancements + * "Keep files" feature (#685) + * Output full path & name for files that don't parse (#745) * Add source and destination directory protection (#535) * Better YAML error message (#718) * Bug Fixes diff --git a/README.textile b/README.textile index 529e1e7d..80ca6220 100644 --- a/README.textile +++ b/README.textile @@ -1,5 +1,7 @@ h1. Jekyll +!https://travis-ci.org/mojombo/jekyll.png?branch=master!:https://travis-ci.org/mojombo/jekyll + By Tom Preston-Werner, Nick Quaranto, and many awesome contributors! Jekyll is a simple, blog aware, static site generator. It takes a template directory (representing the raw form of a website), runs it through Textile or Markdown and Liquid converters, and spits out a complete, static website suitable for serving with Apache or your favorite web server. This is also the engine behind "GitHub Pages":http://pages.github.com, which you can use to host your project's page or blog right here from GitHub. diff --git a/lib/jekyll.rb b/lib/jekyll.rb index 12a8ca92..477247dd 100644 --- a/lib/jekyll.rb +++ b/lib/jekyll.rb @@ -59,6 +59,7 @@ module Jekyll 'plugins' => File.join(Dir.pwd, '_plugins'), 'layouts' => '_layouts', + 'keep_files' => ['.git','.svn'], 'future' => true, # remove and make true just default 'pygments' => false, # remove and make true just default diff --git a/lib/jekyll/convertible.rb b/lib/jekyll/convertible.rb index dab0545c..e71fe1bf 100644 --- a/lib/jekyll/convertible.rb +++ b/lib/jekyll/convertible.rb @@ -33,9 +33,9 @@ module Jekyll self.data = YAML.load($1) end rescue => e - puts "Error reading file #{name}: #{e.message}" + puts "Error reading file #{File.join(base, name)}: #{e.message}" rescue SyntaxError => e - puts "YAML Exception reading #{name}: #{e.message}" + puts "YAML Exception reading #{File.join(base, name)}: #{e.message}" end self.data ||= {} diff --git a/lib/jekyll/site.rb b/lib/jekyll/site.rb index 7dbf1336..6afa3c9e 100644 --- a/lib/jekyll/site.rb +++ b/lib/jekyll/site.rb @@ -5,7 +5,8 @@ module Jekyll class Site attr_accessor :config, :layouts, :posts, :pages, :static_files, :categories, :exclude, :include, :source, :dest, :lsi, :pygments, - :permalink_style, :tags, :time, :future, :safe, :plugins, :limit_posts + :permalink_style, :tags, :time, :future, :safe, :plugins, :limit_posts, + :keep_files attr_accessor :converters, :generators @@ -26,6 +27,7 @@ module Jekyll self.include = config['include'] || [] self.future = config['future'] self.limit_posts = config['limit_posts'] || nil + self.keep_files = config['keep_files'] || [] self.reset self.setup @@ -222,8 +224,12 @@ module Jekyll def cleanup # all files and directories in destination, including hidden ones dest_files = Set.new - Dir.glob(File.join(self.dest, "**", "*")) do |file| - dest_files << file + 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 @@ -244,10 +250,21 @@ module Jekyll files.merge(dirs) obsolete_files = dest_files - files - 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 + # Write static files, pages, and posts. # # Returns nothing. diff --git a/test/test_convertible.rb b/test/test_convertible.rb index b9a9e41c..82e4d27f 100644 --- a/test/test_convertible.rb +++ b/test/test_convertible.rb @@ -20,20 +20,24 @@ class TestConvertible < Test::Unit::TestCase end should "not parse if there is syntax error in front-matter" do + name = 'broken_front_matter2.erb' out = capture_stdout do - ret = @convertible.read_yaml(@base, 'broken_front_matter2.erb') + ret = @convertible.read_yaml(@base, name) assert_equal({}, ret) end assert_match(/YAML Exception|syntax error/, out) + assert_match(/#{File.join(@base, name)}/, out) end if RUBY_VERSION >= '1.9.2' should "not parse if there is encoding error in file" do + name = 'broken_front_matter3.erb' out = capture_stdout do - ret = @convertible.read_yaml(@base, 'broken_front_matter3.erb') + ret = @convertible.read_yaml(@base, name) assert_equal({}, ret) end assert_match(/invalid byte sequence in UTF-8/, out) + assert_match(/#{File.join(@base, name)}/, out) end end end diff --git a/test/test_site.rb b/test/test_site.rb index 03f1886e..5462fd6e 100644 --- a/test/test_site.rb +++ b/test/test_site.rb @@ -200,12 +200,22 @@ class TestSite < Test::Unit::TestCase File.open(dest_dir('qux/obsolete.html'), 'w') # empty directory FileUtils.mkdir(dest_dir('quux')) + FileUtils.mkdir(dest_dir('.git')) + FileUtils.mkdir(dest_dir('.svn')) + FileUtils.mkdir(dest_dir('.hg')) + # single file in repository + File.open(dest_dir('.git/HEAD'), 'w') + File.open(dest_dir('.svn/HEAD'), 'w') + File.open(dest_dir('.hg/HEAD'), 'w') end teardown do FileUtils.rm_f(dest_dir('obsolete.html')) FileUtils.rm_rf(dest_dir('qux')) FileUtils.rm_f(dest_dir('quux')) + FileUtils.rm_rf(dest_dir('.git')) + FileUtils.rm_rf(dest_dir('.svn')) + FileUtils.rm_rf(dest_dir('.hg')) end should 'remove orphaned files in destination' do @@ -213,8 +223,23 @@ class TestSite < Test::Unit::TestCase assert !File.exist?(dest_dir('obsolete.html')) assert !File.exist?(dest_dir('qux')) assert !File.exist?(dest_dir('quux')) + assert File.exist?(dest_dir('.git')) + assert File.exist?(dest_dir('.git/HEAD')) end + should 'remove orphaned files in destination - keep_files .svn' do + config = Jekyll::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir, 'keep_files' => ['.svn']}) + @site = Site.new(config) + @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')) + assert !File.exist?(dest_dir('.git')) + assert !File.exist?(dest_dir('.git/HEAD')) + assert File.exist?(dest_dir('.svn')) + assert File.exist?(dest_dir('.svn/HEAD')) + end end context 'with an invalid markdown processor in the configuration' do