Jekyllでgzipを生成してrsyncでデプロイする
以前、Jekyllを便利に使うためのRakefileと称して、Jekyllで生成したHTMLなどのgzipファイルを生成してrsyncでデプロイするコードを紹介しました。このコードで確かにデプロイできることはできるのですが、何も変更されていないファイルも含めて毎回転送されてしまうという問題があったため、対策しました。
まずは完成品をどうぞ。
require 'bundler'Bundler.require
task :new, :title do |t, args| title = args.title or exit config = Jekyll.configuration({})
open(File.join(config['source'], '_posts', "#{Time.now.strftime('%Y-%m-%d')}-#{title.to_url}.markdown"), 'w') do |f| f << <<-EOS---title: #{title}date: #{Time.now.strftime('%Y-%m-%d %H:%M')}published: false---EOS endend
task :build do config = Jekyll.configuration({}) Jekyll::Commands::Build.process(config) Parallel.each(Dir.glob(File.join(config['destination'], '**', '*.{css,html,js,xml}'))) do |f| system "gzip --rsyncable --keep --no-name #{f}" endend
task :rsync do config = Jekyll.configuration({}) system "rsync -avzr --compress --checksum --delete #{config['destination']}/ #{config['rsync']['destination']}"end
task :deploy => [ :build, :rsync ] doend
前回のコードの最大の問題は、Jekyllでビルドするとすべてのファイルが再生成されてタイムスタンプが変化することを考慮していない点です。これにより、ファイルの内容が変わっていないにも関わらず、ファイルが変更されたと見なされていました。今回のコードでは、--checksum
オプションを追加することで、ファイルの内容によって変更をチェックするようにしています。
しかし、これだけでは十分ではありません。gzip圧縮したファイルは、--checksum
オプションを追加しても毎回転送されてしまいます。これは、gzipファイルに圧縮前のファイルのタイムスタンプの情報が圧縮後のファイルに格納されていることに起因します。圧縮時に--no-name
オプションを追加することで、圧縮前のファイルのタイムスタンプ (とファイル名) が含められることを回避できます。
なお、上の例では--rsyncable
オプションを追加してrsyncでの変更の有無の確認を高速に行えるgzipファイルを生成しています。このオプションはGNUのgzipにしか含まれていないようなので、OS Xなどの環境ではオプションを削除するか、GNUのgzipをインストールしてください。