puma-devをproxyで使う際の便利コマンドを作った

普段のRailsアプリケーション開発にpuma-devを使っています。僕の場合はもっぱらproxyとして使っています。

そもそもpuma-devとは何かというのはこちらに書きました。

[puma-devを使ってRailsの開発サーバーをhttps対応にする - Qiita](http://qiita.com/pi_chan/items/6860b2520ed1089e7741)

（本当はこの投稿に入れる形で書いてたんだけど、puma-devの説明書いてたら長くなってきたから分けました）

# tl;dr

puma-devでproxy使うとポート番号忘れて困るので、ポート番号を調べて`rails s`してくれるコマンド作ったよ。

[pi-chan/puman](https://github.com/pi-chan/puman)

（※Linux未確認です）

# puma-devのproxyとは

## Railsのデバッグ

proxyの話の前に、関連するデバッグの話を書きます。

puma-devは`~/.puma-dev`ディレクトリにアプリケーションのRootディレクトリへのシンボリックリンクを置くことで、`http://シンボリックリリンク名.dev`でアクセスできるというものです。

この方法を使うと`rails s`する必要がなくなる分楽ではあるのですが、コード中にデバッガーで止めるためのコードを書いても止まってくれません（というか、裏で止まるのかな？）。

puma-devやpowを知る前の僕は、ターミナルで`rails s`してサーバーを起動しデバッグには`pry`を使っていました。`binding.pry`を書いた行にさしかかると、`rails s`しているサーバーの出力が止まってpryのREPLが使えるようになるわけです。

pryを使う方法に慣れていたので、puma-devのような仕組みだと困ってしまいました。pry-remoteのような方法（うろ覚え）もありそうだったのですが難しく、うまくいきませんでした。

ちなみに同僚の@jnchitoがこんなアンケートを取ってて、僕は一番上のpryにいれました。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Ruby/Railsプログラマのみなさんにアンケートです。RubyやRailsでデバッグするときは、どのデバッガを使っていますか？（最もよく使うものを選択）<br>選択肢になければリプライで回答をお願いします～。</p>&mdash; Junichi Ito (伊藤淳一) (@jnchito) <a href="https://twitter.com/jnchito/status/819356682497032196">2017年1月12日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

## そんなときのproxy機能

puma-devのproxyではdevドメインは活かしつつ、サーバーの起動は自分で`rails s`するというものです。

`~/.puma-dev`ディレクトリにはシンボリックリンクではなく、ポート番号を書いたテキストファイルを配置します。

```~/.puma-dev/railsapp
3001
```

こう書いておくと`http://railsapp.dev`へのアクセスが3001番ポートにいきます。サーバーはターミナルで動いているので`binding.pry`等で簡単に止めることができます。

puma-devのdevやxip.io、https対応のメリットは活かしつつ、サーバーを自分で動かすことができました。

# ポート番号問題

自分で`rails s`するので、複数アプリケーションを同時に立ち上げる場合はポート番号を指定してあげる必要があります。このときのポート番号は`~/.puma-dev/`以下においたファイルに書いたものでないと正しくプロキシされません。

このアプリケーションは3001番、こっちは3002番など起動時に指定してあげなければならず覚える必要がでてきます。アプリケーションが増えていくと、覚えきれるものではありません。

## 最初の対応策

最初は簡単なスクリプトで回避しようと考えていました。覚えきれないので簡単に一覧できるようにしようという発想です。

```ruby
#!/usr/bin/env ruby
portmaps = {}
Dir.chdir "~/.puma-dev" do
  Dir.glob('*').each do |file|
    unless File.symlink?(file)
      port = File.read(file)
      portmaps[port] = file
    end
  end
end

portmaps.sort.each do |port, proj|
  puts "#{port.strip} => #{proj}"
end
```

そうするとこんな風に出力されます。少ないうちはこれでなんとかなっていました。

```
3004 => aaaa
3005 => bbbb
3006 => cccc
3007 => dddd
3008 => eeee
```

最近は30個近くなってきて一覧にしても見つけるのが大変で結局面倒になってきました。

## コマンドにした

ようやく本題。

ポートを指定するのは`rails s`するときだけだな、ということでポート番号を読んで勝手に`rails s`してくれるコマンドにすればいいんじゃないか？と気がつきました。

そして、コマンドラインツールを簡単に作れるThorを使ってpumanというコマンドのgemを作りました。名前がちょっといい加減すぎるかなと思いましたが、まあいいです。

[pi-chan/puman](https://github.com/pi-chan/puman)

Usageはこんな感じ。

```
Commands:
  puman help [COMMAND]  # Describe available commands or one specific com...
  puman list            # list all apps linked with puma-dev
  puman server          # run rails server
  puman symlink DIR     # create symlink into puma-dev directory.
  puman version         # version
```

該当のプロジェクトのRootディレクトリ以下にいる状態で`puman`と叩けばポート番号を調べてくれて勝手に`rails s -p 30xx`としてくれます。はっきり言って僕はめちゃくちゃ楽です。

ついでに`~/.puma-dev`にをシンボリックリンクを置いたり(`puman symlink .`)、`~/.puma-dev`の中身を一覧したり（`puman list`）など、サブコマンドもいくつか用意してあります。

proxy用に適当なポート番号を決めて新たに`~/.puma-dev`に追加するコマンド（`puman proxy DIR`）も作ろうと思っていましたが、まだやっていません。今度作ります。

マニアックな用途ですが困っている人が他にもいるかも、と思い書いてみました。

## デバッグに関する参考

[printデバッグにさようなら！Ruby初心者のためのByebugチュートリアル - Qiita](http://qiita.com/jnchito/items/5aaf323ab4f24b526a61)