[Go] Realizeが便利なので、もう少し仲良くなってみる

[realize](https://github.com/tockins/realize)、使ってますか？

Goで開発を進めていくと、毎度毎度 `go run ...` などするのは面倒なので、Goな人は何かしらのホットリロード（ライブリロード）ツールを使っていると思いますが、その中で今のところ一番使いやすいなーと思っているrealizeの使い方をざっくりまとめてみました。

## なにはともあれ install

```shell
$ go get -u github.com/oxequa/realize
```

## 使い方

プロジェクトルートで以下のコマンドを打つと、`.realize.yaml` が出来上がります。

```shell
$ realize start
```

中身はこんな感じ。

```.realize.yaml
settings:
  legacy:
    force: false
    interval: 0s
server:
  status: false
  open: false
  port: 5002
  host: localhost
schema:
- name: realize-sample
  path: .
  commands: {}
  watcher:
    paths:
    - /
    extensions:
    - go
    ignored_paths:
    - .git
    - .realize
    - vendor
```

一度 `ctl+C` で閉じて、次は --serverオプションを付けて実行してみます。

```shell
$ realize start --server
```

http://localhost:5002 にアクセス出来るようになるので開いてみると、対象プロジェクトの各状況を確認することが出来ます。

試しにファイルへ追記したり修正してみたりすると、どのファイルをいじったのかが分かると思います。

<img width="1207" alt="Realize.png" src="https://qiita-image-store.s3.amazonaws.com/0/92359/efb3a1a8-c8b9-405f-ccb2-d9fc830a8cab.png">

ちなみに、--openオプションをつけて実行すると、勝手にブラウザで開いてくれます。

## go run を監視する

僕は普段、echoを使ったサービスを扱うことが多いので、echoサーバーを起動した状態でホットリロードが効く状態にしてみましょう。

.realize.yamlに以下を追記します。

```.realize.yaml
schema:
- name: realize-sample
  path: .
  # 修正ここから
  commands: 
    run:
      status: true
  # 修正ここまで
  watcher:
    paths:
    - /
```

再度、 `realize start --server` を実行してみましょう。すると、echo起動時のおなじみなAAが、realize管理画面の `Outputs` に一行ずつ表示されると思います。

ちなみに、 realizeの内部でもechoが使われています。
（Freshに置き換えたい、みたいなissueが立ってますが）


## Goファイル以外もホットリロード対象にする

デフォルトではgoのみの監視しかされていません。その他のファイルを監視対象とする場合は、extensionsに追加していきましょう。例えば、htmlとyamlを対象とする場合は、以下のように書けばOKです。

```.realize.yaml
watcher:
  paths:
  - /
  extensions:
  - go
  - html
  - yaml
```

## 複数のプロジェクトをrealizeの管理下に置く

現在はプロジェクトルートに `.realize.yaml` を置いていますが、複数のプロジェクトを一括管理することが出来ます。その場合は、pathを以下のように設定します。

```.realize.yaml
schema:
- name: realize-sample
  path: /path/to/realize-sample
  commands:
```

これで、毎度リポジトリごとに設定ファイルを置かずに済むので、各々でのカスタマイズした設定で扱うことができます。

ちなみに、管理下においたプロジェクトの設定を消す場合は、以下のようにします。

```shell
$ realize remove --name="realize-sample"
```


## 対話式に設定する

`realize init`をすると、対話式に `.realize.yaml`を作成することができます。

聞かれる内容は以下のとおりです。（抜け漏れがありましたらコメントいただけると嬉しいです :pray: ）

| Question                                 |   Default   | 補足                |
| ---------------------------------------- | :---------: | ----------------- |
| Would you want to customize settings? [y/n] |      n      | nにすると、プロジェクトの設定のみ |
| Set max number of open files (root required) [int] | os default  |                   |
| Force polling watcher? [y/n]             |      n      |                   |
| Enable logging files [y/n]               |      n      |                   |
| Enable web server [y/n]                  |      n      |                   |
| Server port [int]                        |    5002     |                   |
| Server host [string]                     |  localhost  |                   |
| Open in current browser [y/n]            |      n      | —openと同じ          |
| Would you want to add a new project? (insert '!' to stop) [y/n] |      y      |                   |
| Project name [string]                    | プロジェクトのフルパス |                   |
| Project path [string]                    | プロジェクトのフルパス |                   |
| Enable go vet [y/n]                      |      n      |                   |
| Vet additional arguments [string]        |    none     |                   |
| Enable go fmt [y/n]                      |      n      |                   |
| Enable go test [y/n]                     |      n      |                   |
| Enable go clean [y/n]                    |      n      |                   |
| Enable go generate [y/n]                 |      n      |                   |
| Enable go install [y/n]                  |      y      |                   |
| Install additional arguments [string]    |    none     |                   |
| Enable go build [y/n]                    |      n      |                   |
| Enable go run [y/n]                      |      y      |                   |
| Customize watching paths [y/n]           |      n      | 監視するパスを設定する       |
| Customize ignore paths [y/n]             |      n      |                   |
| Add an additional argument [y/n]         |      n      |                   |
| Add a 'before' custom command (insert '!' to stop) [y/n] |    none     |                   |
| Insert a command [string]                |             | ex ls -al         |
| Launch from a specific path [string]     |      n      |                   |
| Tag as global command [y/n]              |      n      |                   |
| Display command output [y/n]             |      n      |                   |
| Add an 'after' custom commands  (insert '!' to stop) [y/n] |    none     |                   |
| Insert a command [string]                |             | ex. pwd           |
| Launch from a specific path [string]     |      n      |                   |
| Tag as global command [y/n]              |      n      |                   |
| Display command output [y/n]             |      n      |                   |
| Set an error output pattern [string]     |    none     |                   |



## 複数の設定ファイルがあるときは？

と言っても、`realize start`したとき、設定ファイルがあれば使うし、無ければ作るので、 カレントディレクトリの `.realize.yaml` を元に、realizeは起動します。


## その他
現在も開発は行われていて、度々仕様変更が起きています。

例えば、 `realize start` も、以前は `realize run` でした。
また、README.mdも若干古く、現状では設定ファイルでログファイルの出力を以下のように設定する例がありますが、

```.realize.yaml
settings:
    legacy:
    resources:
        outputs: outputs.log
        logs: logs.log
        errors: errors.log
...
```

現在は、次のような出力結果となっています。

```.realize.yaml
settings:
    files:
        outputs:
            status: false
            path: ""
            name: .r.outputs.log
        logs:
            status: false
            path: ""
            name: .r.logs.log
        errors:
            status: false
            path: ""
            name: .r.errors.log
...
```

## まとめ
現在公開されている情報と使い勝手が異なる部分は多少あるものの、それでも既存のホットリロードツールと比べてみると、

- 設定の自由度が高い
- 複数プロジェクトに対して同じ設定でホットリロードの管理下に置くことができる
- Goを始めた人ばかりの方にとって学ぶにはうってつけ

という点で使いやすいと感じています。

ただ、他のツールを使い込んだわけでもないので、もっといいツールをご存知の方は、こっそり下のコメントで教えていただけると嬉しいです :sparkles: 

それでは！


## 補足

ちなみに僕がrealizeを `go get` したときに、以下のパッケージで怒られたので、realize/Gopkg.lockに書かれているブランチに合わせて、よしなに `git pull ...` しました。

```
# cd /path/to/go/src/golang.org/x/sys; git pull --ff-only
You are not currently on a branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.

    git pull <remote> <branch>

package golang.org/x/sys/unix: exit status 1
# cd /path/to/go/src/golang.org/x/crypto; git pull --ff-only
You are not currently on a branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.

    git pull <remote> <branch>

package golang.org/x/crypto/acme/autocert: exit status 1
# cd /path/to/go/src/golang.org/x/net; git pull --ff-only
You are not currently on a branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.

    git pull <remote> <branch>

package golang.org/x/net/websocket: exit status 1
# cd /path/to/go/src/gopkg.in/yaml.v2; git pull --ff-only
You are not currently on a branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.

    git pull <remote> <branch>

package gopkg.in/yaml.v2: exit status 1
```