環境構築メモ(homesick/prezto/anyenv)


自宅PCと会社PCの環境にかなりの差(インストール物/設定)が出てきてしまったため、環境の構築/共有について考えてみることにした。
現状を整理したのが以下。

- 自宅PC
  - Homebrewにインストールをかなり寄せている
  - Pythonはpybrewで複数バージョンを管理している
  - pybrewでインストールしたPythonをベースとして、バージョン毎にvirtualenv環境(ex. py2.7, py3.4などの名前)を構築している
  - ドットファイルをGithub+自前スクリプトで管理している
  - ベースはかなり前に作成しており、よく意味が分からずにコピペで追加した設定もかなりある

- 会社PC
  - Homebrewにインストールをかなり寄せている
  - バイナリについても可能な限り、Homebrew Caskに寄せている
  - Python, Ruby, JavaはHomebrewで複数バージョンを管理している
  - HomebrewでインストールしたPythonをベースとして、バージョン毎にvirtualenv環境を構築している
  - zsh関係のドットファイルはpreztoを使って管理、その他のドットファイルは特に管理していない
  - 自分にとって必要最低限の設定のみ行うことを意識している

これらを踏まえ、以下の方針を立てた。

- 今までどおり、できる限りHomebrew/Homebrew Caskに寄せる
- ただしプログラミング言語回りのインストールについては一部はHomebrewで管理しない
  - Homebrewでバージョンを管理するのが予想外に面倒
- 今までどおり、バージョン毎にvirtualenv環境を構築する
- 会社のPCの設定をベースとする
  - できる限り設定回りを圧縮したい

## Homebrew/Homebrew Caskのインストール内容はBrewfileで管理する

Homebrew/Homebrew Caskでインストールする内容をBrewfileにまとめておくことで、`brew bundle Brewfile`で一度にインストールできる。
後述のanyenvで管理するもの以外は可能な限り、Brewfileに記載してHomebrew経由で管理することとする。
`ruby`, `python`, `python3`などいくつかのパッケージがanyenv管理のものと重なっているが、これはHomebrewの他パッケージの依存関係だったり(`python`, `python3`)、後述のhomesickで必要になるもの(`ruby`(gem))をHomebrewでもインストールしている。(OS Xであれば、はじめから入っている`ruby`, `python`で事足りるかも知れない。)

```:Brewfile
update

tap homebrew/versions
install vim --with-lua --with-perl --with-python3 --without-python
# https://github.com/tomaz/appledoc/issues/435
install appledoc
install the_silver_searcher
install maven
install ant
install android-sdk
install git
install hub
install mercurial
install wget
install ruby
install --devel groovy
install sqlite3
install gradle
install jq
install ctags
install global --with-exuberant-ctags
install zsh
install z
install icu4c
install jenkins

# custom
tap FGtatsuro/homebrew-custom
install --HEAD python
install --HEAD python3
install --HEAD git-flow-noff

tap caskroom/homebrew-cask
tap caskroom/versions
tap FGtatsuro/customcask
install brew-cask
cask install iterm2
cask install quicksilver
cask install skype
cask install hipchat
cask install google-chrome
cask install firefox
cask install dropbox
cask install virtualbox
cask install vagrant
cask install evernote
cask install genymotion
cask install skitch
cask install kobito
cask install yorufukurou
cask install eclipse-ide
cask install unity
cask install java6
cask install java7
cask install java
cask install android-studio-bundle
cask install mono-mdk
cask install xamarin-studio
cask install gimp
```

### 追記(2014/11/04)

`brew bundle`使えなくなっているみたい...以前のBrewfileを転記しただけでちゃんと確かめてなかったorz

```bash:
$ brew --version
0.9.5
$ brew bundle Brewfile
Error: Unknown command: bundle
```

(ref) http://unasuke.com/info/2014/brewfile-is-outdated/
(ref) http://rochefort.hatenablog.com/entry/2014/08/09/080000


## プログラミング言語はanyenvで管理する

以前はHomebrewで複数バージョンの言語を管理していたのだが、以下の理由によりHomebrewで管理するのをやめることにした。

- Homebrew本家のリボジトリは複数バージョンの言語をサポートしていない(ことが多い?)。そのため[別リポジトリ](https://github.com/Homebrew/homebrew-versions)を追加する必要があるが、必要なものが無いと結局自分のカスタムリポジトリで処理することに([以前の記事](http://qiita.com/FGtatsuro/items/bb6dd4d1d7ef2e59b8e6)参照)
- ↑と多少重なるが、カスタムリポジトリを作成するのが面倒になり結局*env(*brew)系のツール(ex. pyenv, rbenv, nodebrew)をHomebrew経由でインストールして、そちらで管理することがあった。

代わりに[anyenv](https://github.com/riywo/anyenv)を使用することとした。anyenvはrbenv, pyenvなどの*env系のツールのラッパーであり、*env系ツールのインストール方法/設定を一本化してくれる。インストールも簡単であり`.anyenv`にリポジトリをクローンして、シェルのプロファイルに設定を追加するだけ。(本家のREADME参照)。

設定後、自分が使う*envをインストールする。

```bash:
$ anyenv install pyenv
$ anyenv install rbenv
$ anyenv install ndenv
$ anyenv install jenv
```

*envインストール後、それぞれ必要なバージョンをインストールしていく。

```bash:
$ pyenv install 2.7.8
$ pyenv install 3.4.2
$ pyenv rehash
$ pyenv global 3.4.2

$ rbenv install 2.1.4
$ rbenv rehash
$ rbenv global 2.1.4

$ ndenv install v0.10.25
$ ndenv rehash
$ ndenv global v0.10.25
```

jenv(Java)に関してはJDKをインストールする機能がないため、別口でインストールしたJDKをjenvに教えてやる必要がある。自分の環境ではHomebrew Cask経由でOracleJDKをインストールしている。(Java6/Java7は、[caskroom/versions](https://github.com/caskroom/homebrew-versions)を追加(tap)する必要あり)

```bash:
$ jenv add `/usr/libexec/java_home -v 1.6`
$ jenv add `/usr/libexec/java_home -v 1.7`
$ jenv add `/usr/libexec/java_home -v 1.8`
$ jenv rehash
$ jenv global 1.8.0.25
```

各バージョンがインストール/デフォルトに設定されていることを確認する。

```bash:
$ anyenv versions
jenv:
  system
  1.6
  1.6.0.65
  1.7
  1.7.0.67
  1.8
* 1.8.0.25 (set by /Users/FGtatsuro/.anyenv/envs/jenv/version)
  oracle64-1.6.0.65
  oracle64-1.7.0.67
  oracle64-1.8.0.25
ndenv:
  system
* v0.10.25 (set by /Users/FGtatsuro/.anyenv/envs/ndenv/version)
pyenv:
  system
  2.7.8
* 3.4.2 (set by /Users/FGtatsuro/.anyenv/envs/pyenv/version)
rbenv:
  system
* 2.1.4 (set by /Users/FGtatsuro/.anyenv/envs/rbenv/version)
```

Pythonについては、更にvirtualenvでバージョン毎のvirtualenv環境を作っておく。

```bash:virtualenv
$ mkvirtualenv -p `which python2.7` py2.7
$ mkvirtualenv -p `which python3.4` py3.4
```

毎回`workon`するのは面倒なので、`.zlogin`にデフォルトの環境で`workon`する設定を追加する。

```zsh:.zlogin
if [ -f $WORKON_HOME/.defaultver ];then
    DEFAULT_VER=`cat "$WORKON_HOME/.defaultver"`
    workon py${DEFAULT_VER}
fi
```

## ドットファイルはhomesickで管理する

[homesick](https://github.com/technicalpickles/homesick)はドットファイルにまつわる様々な処理を提供するユーティリティ。今まではシェルスクリプトで独自に処理していた部分をhomesick経由で行う。

インストールはgem経由で。

```bash:
$ gem install homesick
```

homesickを使う際には、特定のディレクトリ構成を含むリポジトリ(homesickはcastleと呼ぶ)を用意する必要がある。といっても、手順は以下のとおり難しくない。

1. Github上にリポジトリを作成する。
2. `home`という名前のディレクトリを作成する。
3. `home`以下にドットファイルを置く。

自分の環境での例は[こちら](https://github.com/FGtatsuro/dotfiles)。前述のanyenv(`.anyenv`)やzsh関連の設定を扱うprezto(`.zprezto`)などはサブモジュールとして管理して、`home`以下に追加している。

リポジトリ作成後、`homesick clone (Githubユーザ名)/(リポジトリ名)`を実行する。これで`~/.homesick/repos/(リポジトリ名)`に先程作成したリポジトリがcloneされる。

```bash:
$ homesick clone FGtatsuro/dotfiles
$ ls ~/.homesick/repos/dotfiles
README.md home
```

またリポジトリ内に`.homesickrc`が存在する場合、`homesick clone`時に後処理を走らせることができる。(走らせるかの確認が出る)
`.homesickrc`はRubyで記述する。

```ruby:.homesickrc
# For prezto
# https://github.com/sorin-ionescu/prezto#installationの手順3相当の処理を行っている。
# ただしリンクは~/以下ではなく、(リポジトリ)/home/以下におく。(homesickで処理するため)
for org in Dir.glob("#{Dir.getwd}/home/.zprezto/runcoms/z*") do
  link = "#{Dir.getwd}/home/.#{File.basename(org)}"
  File.symlink(org, link) unless File.symlink?(link)
end
```

その後、ホームディレクトリ配下に`~/.homesick/repos/(リポジトリ名)/home`以下のファイルのシンボリックリンクを貼る必要がある。これは`homesick symlink (リポジトリ名)`一発で実現できる。リンクを作成しようとしているパスに既にファイルがある場合、上書きするかの確認が出る。以前の設定をバックアップした上で、`homesick symlink`で上書きするのが良いだろう。

```bash:
$ homesick symlink dotfiles
   identical  /Users/FGtatsuro/.anyenv
   identical  /Users/FGtatsuro/.gitconfig
   identical  /Users/FGtatsuro/.gitignore_global
   identical  /Users/FGtatsuro/.vim
   identical  /Users/FGtatsuro/.vimperatorrc
   identical  /Users/FGtatsuro/.vimrc
   identical  /Users/FGtatsuro/.virtualenvs
   identical  /Users/FGtatsuro/.zlogin
   identical  /Users/FGtatsuro/.zlogout
   identical  /Users/FGtatsuro/.zprezto
   identical  /Users/FGtatsuro/.zpreztorc
   identical  /Users/FGtatsuro/.zprofile
   identical  /Users/FGtatsuro/.zshenv
   identical  /Users/FGtatsuro/.zshrc
```

### 追記(2014/11/04)

[こちら](http://qiita.com/yu_suke1994/items/830c7ab8a6bf75044001)の記事で紹介されている`homeshick`は`homesick`をBashベースで書き直したものらしい。Rubyへの依存関係が気になるのであれば、こちらを使うのも良いか。
ただ少し気になる点としては、ディレクトリやサブモジュールが上手く扱えずに手動でリンクを張る必要があるかも、という点。(注: 実際に試していません)
(ref. http://qiita.com/yu_suke1994/items/830c7ab8a6bf75044001#2-6)
`homesick`の方はディレクトリもサブモジュールも意識せずに`home`以下に放り込めばよかったので楽だった。Rubyへの依存関係も自分の環境ではあまり気にならないため、自分には`homesick`の方があっているかなと考えている。