2020年も終わりなのでdotfiles整理する

この記事は[ユニークビジョン株式会社 Advent Calendar 2020](https://qiita.com/advent-calendar/2020/uniquevision) 20日目の記事です。

# はじめに
みなさん開発環境の設定ファイルはどのように管理していますか？いろいろ方法はあると思いますが、自分は設定ファイル(.bashrc, .config/fish, .vimrc)を集めたGitレポジトリを作成して管理しています。このdotfilesレポジトリをCloneすることで、開発環境が整う、という算段です。

GitHubで`dotfiles`というキーワードで検索すると数多のレポジトリが結果に出てきたり、[awesome-dotfiles](https://github.com/webpro/awesome-dotfiles)のようなまとめがあったりと、世界中のエンジニアが様々な工夫を凝らしている奥深い界隈なのです。

自分もGitLab(以前はGitHub)のプライベートレポジトリでdotfilesを数年間ずっとメンテナンスしており、Initスクリプト一発であらかたvimやshellなどの設定が利用可能になるようにまで整備しました。時たま思い立ったときに部分的に設定を大きく書き換えたりはしているものの、dotfiles自体はツギハギというような状態なのでいらないコードを掃除がてら見直していきます。(整理はできたらします...)


# dotfiles開発環境
開発環境のための開発環境というと意味がわかりませんが、Initスクリプトの動作確認のためにまっさらな環境を準備するために、Dockerコンテナ内でInitスクリプトが実行できると結構便利です。そのままdotfilesのためのCIも組めたりします。

```dockerfile:Dockerfile
FROM ubuntu:latest

ARG PASSWORD

RUN apt-get update && \
	apt-get install -y sudo git curl fish build-essential vim
RUN groupadd -r dot && \
  useradd -r -g dot dot && \
  echo "dot:$PASSWORD" | chpasswd && \
  echo 'dot  ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers && \
  mkdir /home/dot && \
  chown -R dot /home/dot
USER dot
COPY --chown=dot:dot ./ /home/dot/dotfiles/
WORKDIR /home/dot/dotfiles/
```

# Initスクリプト
まずは最低限のスクリプト、ここに色々な開発環境の設定を入れていきます。
`set -eu`してエラー時にその場で止めるようにしたり、とりあえずソースコード入れるためのディレクトリ(Workspace)を作成するのが好みです。

```bash:init.sh
#!/bin/bash

set -eu

cd `dirname $0`
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd)

# Make workspace
mkdir -p ~/Workspace
```

## Ruby
rbenvを使っています。GitHubのREADMEを参考にスクリプトを書き出していきます。

```bash:init.sh
# rbenv
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
cd ~/.rbenv && src/configure && make -C src

## rbenv-build
export PATH=$PATH:$HOME/.rbenv/bin
mkdir -p "$(rbenv root)"/plugins
git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build
```

## Go
curlでバイナリを拾って、binディレクトリにコピーする簡単なインストーラを書いています。バージョンアップも結構楽なので好きです。

```bash:go_installer.sh
#!/bin/bash

VERSION="${1:-1.14.4}"
OS=${2:-linux}
ARCH=${3:-amd64}
curl -L https://dl.google.com/go/go$VERSION.$OS-$ARCH.tar.gz -o /tmp/go$VERSION.$OS-$ARCH.tar.gz
sudo tar -C /usr/local -xzf /tmp/go$VERSION.$OS-$ARCH.tar.gz
```

使い方はこんな感じです。

```bash:init.sh
## go
mkdir -p ~/Workspace/go
$SCRIPT_DIR/go_installer.sh 1.15.6 linux amd64
```

## Rust
こちらも公式の手順どおりです。

```bash:init.sh
## rust
curl https://sh.rustup.rs -sSf | sh
```

## OCaml
```bash:init.sh
## opam
sh <(curl -sL https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh)
```

## Nodebrew
```bash:init.sh
# nodebrew
curl -L git.io/nodebrew | perl - setup
```

## 各種設定ファイルを有効化(.vimrcとか)
自分はシンボリックリンクを$HOMEに貼ってdotfilesディレクトリ側で設定を管理しています。普段は以下のような環境で作業しています。これらの設定ファイル周りは別途まとめようと思います。

- fish
- vim
- tmux

```bash:init.sh
ln -s $SCRIPT_DIR/.zshrc $HOME
ln -s $SCRIPT_DIR/.bashrc $HOME
ln -s $SCRIPT_DIR/.emacs.d $HOME
ln -s $SCRIPT_DIR/.vimrc $HOME
ln -s $SCRIPT_DIR/.tmux.conf $HOME
# .configディレクトリが存在しないときに作成
if [ ! -d $HOME/.config ]; then
    mkdir $HOME/.config
fi
ln -s $SCRIPT_DIR/.config/nvim $HOME/.config/
ln -s $SCRIPT_DIR/.config/fish $HOME/.config/
```

# 動作確認
https://github.com/tokikokoko/dotfiles

```bash
docker build --progress=plain --build-arg PASSWORD=hoge -t dot:latest .
docker run --rm -it dot:latest bash -c './init.sh && bash'

# プロンプトを進めていくとインストールが終わって、コンテナ内のbashシェルにログインできるのでvim-plugの動作確認
vim +PlugInstall +qa
vim
```

# さいごに

新しくdotfilesレポジトリを切ってメンテナンスしていくつもりです。.vimrcや.bashrc、config.fishは全然まだ掃除できていないので適宜更新していきたいです。
また自分が普段利用しているfishはインストールした直後の設定ですでに補完が有効だったり、とても便利なシェルなので、設定などを記事にできたらと思っています。