gitで管理しているvimrcをrakeで一発デプロイできるようにした
前々からだらしなく管理されていたvimrcを始めとするconfigsですが、中途半端にsubversionにコミットしていたり、どこかの環境だけ新しかったりしたので、なんとかしたくてconfigsを整理していました。
この機にgitに乗り換えるのは先日書いた通りなのですが、gitに乗り換えただけでは中途半端な状態は解消されないので、どうしたら良いか考えました。
問題だった事
- vimrcを書き換えで「ちょっと試してみよう」「一時的な設定」が多すぎた
- commitがおざなりになっていた。
- HOMEディレクトリのvimrcやpluginを編集してしまっていて、リポジトリとの整合性確認が面倒だった
- なにがどの状態だったか記憶できていない。
デプロイ or シンボリックリンク
皆さんconfigsの管理ってどうしているのかな??と気になって
http://www.lingr.com/room/vim-users.jp
でセオリーがあるのか質問してみた所、意見が2つに別れました*1。というか派が存在。*2
ujihisaさん派 => シンボリックリンク
kanaさん派 => デプロイ
話を聞く前にはシンボリックリンクが楽そうなイメージだったけど、話を聞いてBuildデプロイで自動化というのもいいなと思って、ujihisaさんの囁きでrakeを使って自動化する事に決めました。
rake
makeのruby版みたいなもの。
Rakefileでbuildのルールとかタスクとか色々書ける。
rakeを叩いた事はありますが、書いた事はなかったので調べながらこつこつと。
依存関係とかルールとか書けてすごく便利な印象です。
これからも使っていきたいツールになりました。
前提
- バージョン管理システムを使ってドットファイル等を一元管理している
- 必ずリポジトリ(リポジトリのワークディレクトリ)のファイルを正とする。
できること
タスク一覧
rakeコマンドを実行することでデプロイを実行することができます。
rake
デフォルトタスクはupdateタスクを実行します。
rake update
rakeを実行するカレントのconfigsワークディレクトリからBuildを行います。
rake rep_build
リポジトリから最新のソースコードを取得し、リポジトリの状態のファイルをBuildします。
configsリポジトリは編集中で、一時的にリポジトリの状態に戻したい時に使います。
rake rep_update
rep_buildとデプロイ条件は同じですが、こちらはcloneしたリポジトリをホームディレクトリのconfigs_workに残しておきます。
タスクを実行した日付のディレクトリが作成されます。
rake work_dir_remove
configs_workを削除します。
普段は単体であまり使うことがないサブタスクです。
rake package
違うホストにconfigsを移したい時に利用します。
ホームディレクトリのconfigs_work/pkg/にzipファイルが作成されます。
本来のpackageの使い方だとpackage→installコマンドでデプロイする形になると思うのですが、オレオレタスクになっています。。。
コード
とりあえず自分がしたい最低限のデプロイはできるようになりましたが、rakeっぽい書き方ができていなかったりとかコードの突っ込みどころも色々とあると思いますが、とりあえず公開します。
自分的にはこれでvim生活をLife Changingできました。
うひょー。
# Config Build Rakefile require "find" require 'rake/packagetask' # 定数値 NOW = Time.now.strftime("%Y%m%d%H%M%S").to_s HOME = File.expand_path("~") EXCLUDE_FILES = Regexp.new("pkg\/|\.git\/|\.DS_Store|\.swp$|\.swo$|\.back$|Rakefile.rb$") GIT_REPO = "git@guyon.unfuddle.com:guyon/configs.git" unless HOME p "Not found home direcotry. Please set home envroiment varibale." exit end # タスクの関連付け task :default => ["update"] task :rep_build => ["rep_clone","update","work_dir_remove"] task :rep_update => ["rep_clone","update"] desc "カレントディレクトリのConfigsからHOMEディレクトリにBuildする" task "update" do src_path = File.expand_path("./") dst_path = File.expand_path(HOME) # --配布 file_copy src_path, dst_path # --削除 # リポジトリ直下のディレクトリのみ削除対象とする Dir.foreach(src_path) {|file| if File.ftype(file) == "directory" && file.to_s !~ /^\.$|^\.\.$/ remove_src_path = src_path + "/" + file.to_s remove_dst_path = dst_path + "/" + file.to_s file_remove remove_src_path, remove_dst_path end } p "Update Finish." end desc "最新バージョンのconfigsリポジトリを作成する" task "rep_clone" do work_dir = HOME + "/configs_work/" + NOW mkdir_p work_dir cd work_dir sh "git clone #{GIT_REPO}" cd "./configs" end desc "workディレクトリを削除する" task "work_dir_remove" do remove_dir = HOME + "/configs_work/" rm_rf remove_dir end Rake::PackageTask.new("configs",NOW) do |p| p.package_dir = HOME + "/configs_work/pkg/" p.need_zip = true # リポジトリ直下のディレクトリのみ削除対象とする Dir.foreach("./") {|file| next if file.to_s =~ EXCLUDE_FILES if File.ftype(file) == "directory" && file.to_s !~ /^\.$|^\.\.$/ p.package_files.include(".*") p.package_files.include(file.to_s + "/**/*") p.package_files.exclude('**/*~') #TODO:パターンを定数値化する p.package_files.exclude("pkg/**",/^\.git$/,/\.git\//,".DS_Store",/\.swp$/,/\.swo$/,/\.back$/,"Rakefile.rb") end } end def file_copy(src_path,dst_path) Find.find(src_path){|src_file| next if src_file.to_s =~ EXCLUDE_FILES if File.file?(src_file) match = Regexp.new("^" + src_path) dst_file = dst_path + src_file.sub(match,"") if !File.exist?(dst_file) dir = File.dirname(dst_file) if !File.exist?(dir) FileUtils.mkdir_p(dir) end FileUtils.cp(src_file,dst_file,:preserve=>true) puts "copy new " + src_file + " => " + dst_file elsif FileUtils.cmp(src_file,dst_file)==false FileUtils.cp(src_file,dst_file,:preserve=>true) puts "copy rewrite " + src_file + " => " + dst_file end end } end def file_remove(src_path,dst_path) return unless File.exist?(dst_path) Find.find(dst_path){|dst_file| match = Regexp.new("^" + dst_path) src_file = src_path + dst_file.sub(match,"") if !File.exist?(src_file) FileUtils.rm_rf(dst_file) puts "remove " + dst_file end } end
10月26日追記
- buildの記述をデプロイに修正。buildはしてないよねと・・・
- rep_cloneは使わない方向に修正予定。
- 無駄にgitリポジトリをコピーをしてしまっているのと、オフラインで問題が発生する。