rcmdnk's blog

Release It!: Design and Deploy Production-Ready Software (English Edition)

OctopressのディレクトリをDropbox内で管理してるのですが、 そうするとgeneratedeployするたびにファイルが全て 更新されるので(.git内も含め)、 そのたびにCPUやネットワークがDropbox結構使われるのが 気になる様になってきたので外に出しました。

publicディレクトリ

Octopressのpublicディレクトリは Rakefilepublic_dir及び _config.ymldestinationで設定されている ディレクトリです。 _config.yml内の値はJekyllコマンド(rake generate等から呼ばれる)で使われます。 両方共等しくしておかないといけません。

sourceにあるファイル群からサイトを構築して 実際にサイトとして見れる形のhtmlに変換されたファイル等がおかれます。 ローカルで試しに見て見る時はここを参照してます。

このディレクトリは単にサイト構築時に作られるだけなので 途中で消したりしても特に問題ありません。

通常はOctopressのトップディレクトリにpublicとしてあります。

deployディレクトリ

Octopressのdeployディレクトリは Rakefiledeploy_dirで指定されている ディレクトリです。

このディレクトリはGitHub Pages等を使ってる場合に コミット用のディレクトリになります。 publicディレクトリから内容をコピーしてきてこのディレクトリからpushします。 最初にrake setup_github_pagesとした時に コミット用として初期化されてるはずです。

このディレクトリは別途Git管理されてるもので、.gitディレクトリを 確認出来ると思いますが、 消してしまったら次に作業作業する前にrake setup_github_pagesなどして きちんと登録し直してあげないといけません。 (直接cloneしてしまった方が楽な時もあると思います。)思

通常はOctopressのトップディレクトリに_deployとしてあります。

問題

現在、OctopressのディレクトリはDropbox下で管理してるんですが、 これだとrake generateなりrake deployなりすると 相当数のファイルが書き換わるので、 記事数が多くなってきたりするとこれらのコマンドの直後に 結構cpuやnetworkリソースを食います。 また、1つの端末で作業した後に他の端末で作業を始めようとするとき、 常時接続してない端末だと起動時に同期が行われて結構うざいです。

最近のDropboxでは各ディレクトリごとに同期する物を細かく設定できるので、 最初はこれらのディレクトリだけ同期しないようにしておこうか、と思ったんですが、 それだとdeployの方が履歴がつながらないので素直には出来ません。

その辺の問題もあるので、いっその事Dropboxの外に一時的に置いて さらにdeployディレクトリも毎回初期化して送るように push方法も変更しました。

Rakefileの変更

deploy時に使うタスクとして新たにpush_exというタスクを作ります。 これを使うため、deployタスクのデフォルト値としてdeploy_exを加えておきます。

1
2
3
4
 rsync_delete   = false
 rsync_args     = ""  # Any extra arguments to pass to rsync
 deploy_default = "push"
+deploy_ex      = "push_ex"

deploy先のurlをRakefileの中で直接指定できる様にするため、 deploy_urlという値でGitのurlを与えておきます。

1
2
3
4
-# This will be configured for you when you run config_deploy
+# This will be used for deploy
+deploy_url     = "[email protected]:rcmdnk/rcmdnk.github.io"
 deploy_branch  = "master"

Misc Configsの所でpublic/deployディレクトリを変更します。 共通のtmp_dirを親ディレクトリにして場所を指定します。

1
2
3
4
5
6
7
8
9
10
11
12
 ## -- Misc Configs -- ##
 
-public_dir      = "public"    # compiled site directory
+tmp_dir         = File.expand_path("~/tmp/octopress/") + "/"  # temporary directory for public/deploy
+public_dir      = "#{tmp_dir}public"  # compiled site directory
 source_dir      = "source"    # source file directory
 blog_index_dir  = 'source'    # directory for your blog's index page (if you put your index in source/blog/index.html, set this to 'source/blog')
-deploy_dir      = "_deploy"   # deploy directory (for Github pages deployment)
+deploy_dir      = "#{tmp_dir}_deploy" # deploy directory (for Github pages deployment)
 stash_dir       = "_stash"    # directory to stash posts for speedy generation
 posts_dir       = "_posts"    # directory for blog files
 themes_dir      = ".themes"   # directory for blog files

deployタスクの中でdeployに使うタスク名を上で加えてdeploy_exに置換します。

1
2
-  Rake::Task["#{deploy_default}"].execute
+  Rake::Task["#{deploy_ex}"].execute

最後に、pushタスクの下辺りにpush_exというタスクを作ります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
desc "deploy public directory to github pages through temporary deploy dir"
multitask :push_ex do
  puts "## Deploying branch to Github Pages "
  puts "## clone from ${deploy_url}"
  rm_rf deploy_dir
  mkdir_p deploy_dir
  cd "#{deploy_dir}" do
    system "git init"
    system "git remote add origin #{deploy_url}"
  end

  Rake::Task[:copydot].invoke(public_dir, deploy_dir)
  puts "\n## Copying #{public_dir} to #{deploy_dir}"
  cp_r "#{public_dir}/.", deploy_dir
  cd "#{deploy_dir}" do
    system "git add -A"
    puts "\n## Commiting: Site updated at #{Time.now.utc}"
    message = "Site updated at #{Time.now.utc}"
    system "git commit -m \"#{message}\" >/dev/null"
    puts "\n## Pushing generated #{deploy_dir} website"
    system "git push -f origin #{deploy_branch}"
    puts "\n## Github Pages deploy complete"
  end
end

push_exでは、毎回deployディレクトリをgitの履歴も含めて全て初期化して からpushしています 1

これで単にpublic/deployディレクトリをDropboxの外にだすだけでなく、 GitHub上のレポジトリで履歴を毎回リセット出来る事になります。

基本、GitHubに置いているサイトのソース部分の履歴は 自分にとっては必要のないもの (サイト構築前のソース部分は別に履歴管理しているはずなので 2 ) で、例えばちょっと間違えて載せた物を消した、と言う時にも、 実はGitHubで履歴が見えてしまって困ります。 サイトの細かい更新履歴も意図せず公開してるのも余り嬉しくないです。

そこで、上の様に毎回リセットして送るとサイトのレポジトリは常に その時のコミットの内容しか持たないようになるのでこの様な自体を防げます。 (まあ、googleにキャッシュ取られてたり誰かに魚拓をとられてれば どうしようもないわけですが。。。)

ついでに、もしその後push_exを辞めて 通常のpushタスクでやっていくためにsetup_github_pagesをする時にも deploy_urlを使えるようにsetup_github_pagesのタスクの中に

1
2
3
4
5
6
7
8
 task :setup_github_pages, :repo do |t, args|
   if args.repo
     repo_url = args.repo
+  elsif deploy_url
+    repo_url = deploy_url
   else
     puts "Enter the read/write url for your repository"
     puts "(For example, '[email protected]:your_username/your_username.github.io.git)"

な感じでdeploy_urlがあれば使う様に加えて置きます。

_config.ymlの変更

_config.ymlの方もdestinationでpublicディレクトリを変更します。

1
2
-destination: public
+destination: ~/tmp/octopress/public

これで後は普通にrake generaterake deploy等をするだけです。

おまけ: push前に禁止ワードをチェックする

ちょっとした書き間違いなどなら良いのですが、 例えばパスワードだとか間違えて書き記しておいたものを GitHubにpushしてしまうととても危険です。

GitHubをバックアップ代わりみたいにも使っていて、 定期的にpushするような事もしているので、 この際に変更をチェックせずに送ってしまうのは結構危険です。

そこで、少しでもその様な危険を回避するために 禁止ワードリストを作ってチェックを行っています。

禁止ワードリストは~/.gitavoidというファイル。 ここにパスワードの一部だとか(自分専用の端末だとしても テキストファイルに全部載せるのは危険なので) を書いて置きます。

Octopressの場合はpublicディレクトリをdeployする前にチェックするため こんな感じでRakefileに書いておきます。

1
2
3
4
5
6
 Rake::Task[:copydot].invoke(source_dir, public_dir)

+# Check if files are fine or not
+ok_failed_stop system("if [ -f ~/.gitavoid ];then while read a;do if ret=`grep -i -r -q $a #{public_dir}`;then echo \"avoid word $a is included!!!\"; echo $ret; exit 1;fi; done < ~/.gitavoid;else  echo \"WARNING: There is no ~/.gitavoid file!!!\";fi")
+
 Rake::Task["#{deploy_ex}"].execute

ここで途中でストップするためにok_failed_stopという関数を追加してるので これをok_failedという関数の下辺りにでも追加しておいて下さい。

1
2
3
4
5
6
7
+def ok_failed_stop(condition)
+  if (condition)
+    puts "OK"
+  else
+    raise "FAILD"
+  end
+end

これで、もし仮に間違ってパスワードが記入されていたとしても deployの前で止まります。

また、GitHubに自動でバックアップを取るシェルスクリプトには、

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
update=0
difffiles=`git status|grep -e "new file" -e "modified"|cut -d":" -f2`
if [ "$difffiles" ];then
  pwd
  if [ -f ~/.gitavoid ];then
    #for f in `echo $difffiles`;do
    for f in `git ls-files`;do
      echo $f
      if [ ! -f $f ];then
        continue
      fi
      while read a;do
        if ret=`grep -i -q $a $f`;then
          echo "avoid word $a is included in $f!!!"
          echo $ret
          return
        fi
      done < ~/.gitavoid
    done
  else
    echo "WARNING: There is no ~/.gitavoid file!"
  fi
  printf "\n"
  update=1
fi

こんな感じでレポジトリにあるファイルを全部チェック 3 するスクリプトを入れています。

Sponsored Links
  1. gitの空ブランチ等についてのまとめ

    gitのリモートレポジトリを上書きする

  2. GitHub pages + Octopressの導入

  3. 毎回全部チェックするのが冗長だと思えば上のfor文のところでコメントを 付け替えて

    1
    2
    3
    4
    
    -#for f in `echo $difffiles`;do
    -for f in `git ls-files`;do
    +for f in `echo $difffiles`;do
    +#for f in `git ls-files`;do
    

    difffilesの方をチェックするようにすればOK。

Sponsored Links

« You don't exist, go away! Octopress Tips: stylesheetsだけアップデートする »

}