標記の力を高められるかもしれないいくつかのTipsを。

なお、あまりRailsと関係ないデプロイでも使えるTips多めです。CapstranoはRailsとの連携以外でも強力なデプロイツール。もっともっと評価されてもいいですね。

Capistrano::CLI.ui.ask でデフォルト値を設定する

1
2
3
4
set :user do
  default_user = `whoami`.chomp
  Capistrano::CLI.ui.ask("[cap] SSH User: ") {|q| q.default = default_user}
end

Capistrano::CLI.ui.ask では、デフォルトではHighLineのaskを呼び出します。なので、そこで使用できるオプションがすべて使えます。
公式Rdocがわかりやすいです。

Capistrano::CLI.ui.ask でバリデーションする

1
2
3
Capistrano::CLI.ui.ask("Choose your environment: ") do |q|
  q.in = ["development", "test", "production"]
end

ハッシュの key を入力させて、変数代入時にはvalueに変換する

1
2
3
4
5
6
7
8
envs = {
  "1" => 'development', "2" => 'test', "3" => 'production'
}
set :env do
  str = "[cap] Choose environment #{envs.keys.sort.map{|v| v.to_s + ') ' + envs[v] }.join(', ')} : "
  converter = lambda {|a| envs[a] || a }
  Capistrano::CLI.ui.ask(str, converter)
end
1
2
3
$ cap deploy
[cap] Choose environment 
  ... 1) development, 2) test, 3) production :

Capistrano::CLI.ui.ask(str, converter)

  • `converter` にInteger、Stringなどクラスを指定するとキャストします。
  • procを指定すると、そのprocを適用してくれます。 参照

デフォルト値の表示方法のデフォルト値が “|default|” な感じなのでちょっと分かり辛い、何とかしたい

モンキーパッチしましょう。

1
2
3
4
5
class HighLine::Question
  def append_default()
    @question << "(default: #{@default.inspect} ) "
  end
end

本来のコードと少し違いますが、まあ困りません。困った方は #{GEM_PATH}/gems/highline-#{v}/lib/highline/question.rb の451行目辺りをご参照ください。

適用前

[cap] Choose environment 
  ... 1) development, 2) test, 3) production : |1|

適用後

[cap] Choose environment 
  ... 1) development, 2) test, 3) production : (default: "1" )

C-cで中断したい、それも綺麗に

普通にC-cすると、非常に長大なバックトレースが出力されてしまう。。。
SIGINTをtrapすればいいと思った。なお、 Interrupt はうまくrescueできなかった。

1
2
3
Signal.trap(:INT) do
  abort "\n[cap] Inturrupted..."
end

これをdeploy.rbの頭の方にでも入れる。abortメッセージの頭に改行コードを入れた方が見やすくなります。

beforeでProcを呼ぶ

用途が分かり辛いかもしれませんが、例えば変数設定の箇所などをまとめて一つのタスクにして、いろんなタスクで使いまわしたい。できればbeforeとかのフックで呼びたい。
でも一つのタスクにしてしまうと、 cap -T で見えてしまいますね。

本来、プライベートタスクとかは作れませんが、lambda(Procオブジェクト)にすることで同じような使いまわしが可能です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
namespace :hoge do
  configure = lambda do
    set :user, "udzura"
    server "hoge.udzura.com", :app
    # ......
  end
 
  before "hoge:deploy", &configure
  before "hoge:deploy:cron", &configure
  before "hoge:deploy:backend", &configure
 
  namespace :deploy do
    desc "あとは通常どおりのタスク記述、共通の変数が使える"
    task :default do
      ...
    end
  end
end

&記法便利ですね。

実は結構限定的にしか使えませんが(タスクのチェインができないとか)、使いこなせばdeploy.rbがすっきりすると思います。

sudoやrunコマンドの表示を少しでも綺麗に

1
2
3
4
5
6
7
8
cmd = <<-"EOC"
  mkdir -p \
    /usr/local/hoge \
    /usr/local/fuga \
    /usr/local/piyo/poyo \
    /var/www/foo
EOC
sudo cmd

こういうことをしたい日が、皆さんにもきっと来ると思うんです。 でもこれをやると、deploy.rbは見やすいんですけど、capしたときのログがひどく見づらくなります。

  * executing "sudo -p 'sudo password: '         mkdir -p           /usr/local/hoge      
       /usr/local/fuga           /usr/local/piyo/poyo           /var/www/foo"

スペースを詰めればかなりマシになります。なので:

1
2
3
4
5
6
7
8
cmd = (<<-"EOC").split.join(" ")
  mkdir -p \
    /usr/local/hoge \
    /usr/local/fuga \
    /usr/local/piyo/poyo \
    /var/www/foo
EOC
sudo cmd
  * executing "sudo -p 'sudo password: ' mkdir -p /usr/local/hoge
  /usr/local/fuga /usr/local/piyo/poyo /var/www/foo"

Capstranoの機能っていうかRuby自体な感じですが、まあ「書き方さえ知っていれば」レベルのコロンブスの卵です。