バージョン管理スクリプト on Ruby

プログラマにとって、ソースコードのバックアップやバージョン管理は重要です。しかし、個人の小さなプロジェクトなど、CVSSubversion・Gitといった大掛かりなソフトを使うほどでもない、でも手作業は面堂・・。そんな私のために、バックアップおよびバージョン管理用スクリプトを書きました。

require "fileutils"

def backup(to_root_path)
  bak_dir_name = Time.now.strftime("%Y%m%d%H%M%S")
  Dir.glob("**/*").each do |from_file_path|
    next if File.directory?(from_file_path)
    to_file_path = File.join([to_root_path, from_file_path])
    to_dir_path = File.dirname(to_file_path)
    if !File.exist?(to_file_path) ||
       !FileUtils.cmp(from_file_path, to_file_path)
      FileUtils.mkdir_p(to_dir_path) unless File.exist?(to_dir_path)
      if File.exist?(to_file_path)
        to_bak_path = File.join([to_root_path,
                                 bak_dir_name,
                                 File.dirname(from_file_path)])
        FileUtils.mkdir_p(to_bak_path)
        FileUtils.cp_r(to_file_path, to_bak_path, :preserve => true)
      end
      FileUtils.cp_r(from_file_path, to_dir_path, :preserve => true)
    end
  end
end

■動作概要

・カレントディレクトリ以下の全ファイルを、引数のパスにコピーします。

・同じ名前のファイルがあった場合、ファイルの内容を比較します。

・内容が異なっていれば、ディレクトリを作成して古いファイルをバックアップします。



■使用例

・C:\backup.rb に上記のスクリプトを保存します。

・以下の内容のバッチファイルを作成します。

ruby -r "C:\backup.rb" -e "backup('D:\backup')"
pause

・実行すると、バッチファイルのあるディレクトリの内容が、D:\backup にコピーされます。



■特徴

・ファイルをそのままバックアップするため、可用性が高い

・テキストファイルだけでなく、バイナリファイルもバックアップ可能

USBメモリなど、外部記憶にもバックアップ可能
・ただのスクリプトなので、柔軟性が柔軟



■今後

ロールバック機能をつける

・コメントをつける

・Green(now)→Refactor(tommorow)

クラウドに対応したい



■感想

「標準添付ライブラリ fileutils のつかいかた」のようなコードになってしまった。感謝。



■おまけ・テストコード

かなり適当。

require "test/unit"
require "fileutils"
include FileUtils

class TC_Backup < Test::Unit::TestCase
  def setup
    cd "test"
    touch "cpt.rb"
    mkdir_p "from"
    touch "from/cpt_deep.rb"
    mkdir_p "../ttt"
    require "../../backup.rb"
    backup "../ttt"
  end
  
  def test_cp
    assert(File.exist?("../ttt/cpt.rb"))
    assert(File.exist?("../ttt/from/cpt_deep.rb"))
  end
end



■最優先事項

まともなテストを書く。



■参考

module FileUtils - Ruby 1.8.7 リファレンスマニュアル
http://doc.okkez.net/static/187/class/FileUtils.html