dotfilesを育てよう!
dotfilesはエンジニア人生と切っても切れない関係です。
そんなdotfilesを理想の形に育てていく方法について紹介したいと思います。
dotfilesとは
`.`(ドット)から始まるファイルの総称です。 Unix系OSでは`.`から始まるファイルは**隠しファイル**として扱われ、`ls`コマンド等にはオプションを指定しないと表示されない仕組みになっています[^1]。 古来より、この特徴を利用して、ホームディレクトリ直下に`.`から始まる設定ファイルを配置するという文化があります。 例えば、筆者のホームディレクトリで`ls`を実行した場合、下記のような出力となります。![dotfiles01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214526/90e5f04c-45c4-0c2a-3d8a-1f0b3596b43e.png) 隠しファイルも表示する`-a`オプションを加えて実行した結果は下記のようになります。 ![dotfiles02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214526/11701cbd-88fa-541e-c092-83171267eb15.png) `.`で始まるファイルが大量に表示されています。 要はこれらがdotfilesです。Lv.1 Gitで管理しよう
まずは最初の一歩として、dotfilesをGit管理するところから始めましょう。
履歴管理やポータビリティの向上等様々な恩恵があります。(草を生やせたりも)
dotfilesというリポジトリを作成し、.bashrc
等の各種dotfilesをリポジトリ配下にコミットします。
ホームディレクトリにはln
コマンドを用いてシンボリックリンクで配置します。
シンボリックリンクを作成することで、リポジトリ内のファイルで一元管理できるため、更新や最新化が簡単にできるようになります。
# リンクの作成
$ cd path/to/dotfiles
$ ln -s .bashrc ~/.bashrc
# リンクを確認
$ ls -l ~/.bashrc
lrwxrwxrwx 1 reireias reireias 59 6月 8 22:30 /home/reireias/.bashrc -> /home/reireias/dev/src/github.com/reireias/dotfiles/.bashrc
なお、GitHubでは実に多くのdotfilesリポジトリが公開されています。
https://github.com/topics/dotfiles
ちなみに、AWS_ACCESS_KEY_ID
等の認証情報が公開されてしまわないように注意しましょう
Lv.2 deployを簡単にしよう
シンボリックリンクの作成は、その環境に対して1度しか実施しませんが、対象となるdotfileが増えれば、その作業も効率化したくなるのがエンジニアの性というものです。
簡単なshell scriptで実装することができます。
shell script以外で実装してもよいのですが、クリーンな環境にインストールする際に依存するパッケージが少ないほど楽なので、大抵の環境で利用できるshell scriptがよく採用されています。
以下のスクリプトでは、dotfilesリポジトリ直下の.
ではじまるファイル全てのシンボリックリンクをホームディレクトリに作成します。
#!/bin/bash -e
IGNORE_PATTERN="^\.(git|travis)"
echo "Create dotfile links."
for dotfile in .??*; do
[[ $dotfile =~ $IGNORE_PATTERN ]] && continue
ln -snfv "$(pwd)/$dotfile" "$HOME/$dotfile"
done
echo "Success"
Lv.3 インストールスクリプトを書こう
dotfileによっては、パッケージやライブラリのインストールが必要となるものもあるでしょう。
例えば、
-
.tmux.conf
があるので、tmuxをインストールしたい -
peco
コマンドを利用する自作関数が.bashrc
に定義してある - vimの特定のプラグインがpythonのライブラリに依存している
等があげられます。
はじめのうちはREADMEに依存パッケージの一覧を記載したりしているでしょう。
やっぱり自動化するのがエンジニアですね。
例えばshell scriptであれば下記のようにシンプルにコマンドを列挙していくだけでも、立派なインストールスクリプトになります。
#!/bin/bash
brew install tmux peco neovim
pip install neovim
Lv.4 インストールスクリプトの冪等性を意識しよう
冪等性を意識したインストールスクリプトにしてみましょう。
何度実行しても同じ結果になるようにすることで、新たにインストールスクリプトで行う処理を追加した場合でも既存の環境に対してインストールスクリプトを実行することが可能です。
簡単な例を下記に示します。
# 冪等性なし
mv config /etc/hoge/config
echo "some setting" >> ~/.hogerc
# 冪等性あり
cp config /etc/hoge/config
if ! grep -q "^some setting$" ~/.hogerc; then
echo "some setting" >> ~/.hogerc
fi
インストールスクリプトが大きくなるほど、冪等性をshell scriptで担保するのは難しくなってくるので、AnsibleやChef等の構成管理ツールを使ってインストールスクリプトを記述するのも良い選択と言えるでしょう。
ただ、shell script以外のツールを利用し始めると、まっさらな環境にインストールする際の手順が多少増えてしまうので、注意が必要です。
Lv.5 CIをまわそう
猫も杓子もCIな世の中です。
dotfilesにおいてもCIを回しましょう。
インストールするパッケージやライブラリのバージョンを指定せず、最新版をインストールするようなスクリプトの場合、非互換な更新によりインストールスクリプトが失敗するようになることもあるでしょう。
インストールスクリプトの実行や適切にファイルが配置されたか等を確認するのがよいでしょう。
GitHub Actionsでのごくごくシンプルなサンプルコードを記載しておきます。
---
name: main
on: [push]
jobs:
main:
runs-on: ubuntu-latest # or macOS-latest
steps:
- uses: actions/checkout@v1
- name: install dotfiles
run: bash install.sh
- name: test
run: # some tests
Lv.6 ファイルを分割しよう
dotfilesが順調に成長していくと、.bashrc
(.zshrc
)や.vimrc
なんかはかなり巨大になっていきます。
巨大な1ファイルは条件反射で悪とみなすのがエンジニアの常なので、なんとか分割したいものです。
幸い、.bashrc
や.vimrc
等は別ファイルを読み込む機能を搭載しているので、分割が容易です。
例えば以下のように.bashrc
から別ファイルを読み込むことができます。
source ${HOME}/.bash/keybind.sh
source ${HOME}/.bash/alias.sh
Lv.7 READMEを整備しよう
dotfilesは人に見られることでも成長します(?)
READMEを整備し、イケてるdotfilesリポジトリに仕立てましょう。
個人的には以下が記載されていると、パクリたく参考にしたくなります。
- 対象のエディタ、shell、ツール
- ターミナルのスクリーンショット
- コンセプト
- 依存するパッケージやライブラリ
番外編 様々な環境に対応しよう
LinuxとMac OSの両方を利用することのある変態珍しい人は、両方の環境に対応した設定やインストールスクリプトを用意すると幸せになれるのではないでしょうか?
CIもマトリックスビルド等を活用し、LinuxとMac OSの両方の環境で実行するとよいでしょう。
ちなみに、筆者は最近、AnsibleでLinuxのaptとMac OSのbrewをwhenによる分岐を利用せずに書く方法がなくて困っています。
さいごに
じゃあ、お前のdotfilesはどうなんだよ?と言われそうなので、いちおう掲載しておきます。
そんなに期待しないでくださいね。