こんにちは。突然ですけど、マシン間でのドットファイルの共有ってどうしてますか?
最近ではドットファイルをGitHubやBitBucket上のリポジトリでバージョン管理している人は珍しくありませんし、Dropboxを活用している人もいるようです。何にせよ、インターネットにつながっていれば自分の作業環境を再現できたり、変更を同期できたりするのは非常に便利ですよね。
ところで、これらのファイルを管理するdotfilesプロジェクトのディレクトリ構造や初期化スクリプトの機能などは人によってバラバラなようです。実際に身の回りの数人に聞いてみたのですが、特に他人のdotfilesプロジェクトをベースにしたりせず、自分だけの仕組みを使っている人が多い印象でした。それほど難しい内容ではありませんから、自作の方が自由度が高くて便利なこともあるでしょう。
一方で、他人のドットファイル管理を見ると気づきがあったりします。私自身、以前は独自の仕組みを使っていましたが、最近は「Zach Holman's dotfiles」をカスタマイズして使っています。本稿では他人のdotfilesプロジェクトに乗っかってみてのメリット・デメリットを紹介します。
Zach Holman's dotfilesはStar数3000・Fork数2000と、GitHub上で公開されているdotfilesプロジェクトの中でも有名なものの一つです。
また、作者のZach Holmanさんは5年前にブログ記事「Dotfiles Are Meant to Be Forked(dotfilesはforkされるべき)」という記事を書いて最近でも話題にされたりしています(参考:redditのスレッド)。
この記事自体は賛否両論ある内容なのですが、「リファクタリングやコードの最小化に知見があるソフトウェアエンジニアが200行のグチャグチャな.bashrcを使っていて平気なのが理解できない、他人が再利用できるように整理して公開しよう」という主張はわからなくもありません。
このZach Holman's dotfilesを手元で使う方法を紹介します。
新しいマシンにログインしたら、次のようにgit clone
して初期化スクリプトを実行するだけで普段の設定ファイルが使えるようになります。
$ git clone https://github.com/[自分のユーザー名]/dotfiles.git ~/.dotfiles
(略)
$ cd ~/.dotfiles
$ script/bootstrap
[ OK ] linked /home/hnw/.dotfiles/zsh/zshrc.symlink to /home/hnw/.zshrc
[ OK ] linked /home/hnw/.dotfiles/emacs.d.symlink to /home/hnw/.emacs.d
[ OK ] linked /home/hnw/.dotfiles/tmux/tmux.conf.symlink to /home/hnw/.tmux.conf
[ OK ] linked /home/hnw/.dotfiles/ruby/gemrc.symlink to /home/hnw/.gemrc
[ OK ] linked /home/hnw/.dotfiles/ruby/irbrc.symlink to /home/hnw/.irbrc
[ ? ] File already exists: /home/hnw/.profile (profile.symlink), what do you want to do?
[s]kip, [S]kip all, [o]verwrite, [O]verwrite all, [b]ackup, [B]ackup all B
[ OK ] moved /home/hnw/.profile to /home/hnw/.profile.backup
[ OK ] linked /home/hnw/.dotfiles/bash/profile.symlink to /home/hnw/.profile
[ OK ] moved /home/hnw/.bash_logout to /home/hnw/.bash_logout.backup
[ OK ] linked /home/hnw/.dotfiles/bash/bash_logout.symlink to /home/hnw/.bash_logout
[ OK ] linked /home/hnw/.dotfiles/atom.symlink to /home/hnw/.atom
[ OK ] linked /home/hnw/.dotfiles/git/gitconfig.symlink to /home/hnw/.gitconfig
[ OK ] linked /home/hnw/.dotfiles/git/gitconfig.local.symlink to /home/hnw/.gitconfig.local
[ OK ] linked /home/hnw/.dotfiles/git/gitignore.symlink to /home/hnw/.gitignore
[ OK ] linked /home/hnw/.dotfiles/git/git_templates.symlink to /home/hnw/.git_templates
[ OK ] linked /home/hnw/.dotfiles/vim/vimrc.symlink to /home/hnw/.vimrc
[ OK ] linked /home/hnw/.dotfiles/system/inputrc.symlink to /home/hnw/.inputrc
[ OK ] linked /home/hnw/.dotfiles/system/dir_colors.symlink to /home/hnw/.dir_colors
All installed!
$
ホームディレクトリに大量のシンボリックリンクが作られるという、ありがちな挙動です。既存ファイルを上書きするか、バックアップファイルするかなど聞いてくれるのは親切ですが、自作できないほど高機能というわけでもありません。
また、Macの場合は初期化スクリプト中でHomebrewからgrc
やspark
をインストールされたりします。試す前にbootstrap
の中身を追いかけておいた方が良いでしょう。
私が自前のdotfilesプロジェクトを管理していたころは、当初は管理対象としてファイルしか想定しておらず、後から~/.atom/
のようなディレクトリを管理したくなったタイミングで初期化スクリプトを書き直す、などということがありました。
既存のdotfilesプロジェクトであれば既に多くの人のニーズに応えているため、後から不満が出てくるようなことは滅多にないはずです。
また、初期化スクリプトも自作出来る程度の内容とはいえ、既に多くの人の手元で動いているものを使えるのは安心感があります。過去に私が自作したスクリプトは手元の環境に依存していたりして、新しい環境で動かずにデバッグする羽目になったりしました。
新しい環境で普段と同じドットファイルを素早く使う目的であれば、どの環境でも即座に動くのは地味ながら重要です。その意味で、他人の成果物を利用するのは良い手のように思います。
Zach Holman's dotfilesの特徴的なところは、関係の深い設定を同じサブディレクトリにまとめて管理するというポリシーです。
たとえば私の~/.dotfiles/git
には次のようなファイルがあります。
-rw-r--r-- 1 hnw staff 616 4 26 11:37 aliases.zsh
-rw-r--r-- 1 hnw staff 289 4 26 11:37 completion.zsh
drwxr-xr-x 3 hnw staff 102 6 26 00:08 git_templates.symlink
-rw-r--r-- 1 hnw staff 658 9 23 17:48 gitconfig.local.symlink
-rw-r--r-- 1 hnw staff 1395 10 19 12:20 gitconfig.symlink
-rw-r--r-- 1 hnw staff 179 4 26 11:56 gitignore.symlink
このように、gitの設定ファイルとzshの設定ファイルの断片とが共存しています。特定のプログラムに関する設定が同じディレクトリにまとまっていると多少は保守性が上がるように思います。
また、この仕組みに乗っかることで長大だったzshの設定ファイルが多少整理されたのも事実です。
以前自分でdotfileを管理していたころは設定を複数マシンで共有することだけが目的で、整理するという観点は無かったので、その意味では良かったと言えそうです。
実は私がZach Holman's dotfilesを導入して一番気に入ったものは設定ではなく、git wtf
という独自サブコマンドだったりします。これは、gitのワーキングディレクトリ上で打つと今どういう状況かを教えてくれるものです(ソースコード:dotfiles/bin/git-wtf)。
$ git wtf
Local branch: master
[x] in sync with remote
Remote branch: origin/master (git@github.com:hnw/dotfiles.git)
[ ] NOT in sync with local (you should merge)
- init-loader.elでinit.elを分割 [39bece5]
$
たとえば上の出力例は、git fetch
だけしてgit merge
していない状況です。ローカルリポジトリとワーキングディレクトリの同期が取れてないよ、というのをズレているコミットのコミットログと合わせて教えてくれています。他にもgit push -f
して歴史がひどいことになったときなど、状況を把握するのに便利だと思います。
他にも独自のgitサブコマンドや他の便利コマンドがbin/
以下に含まれており、$PATH
に入れて使う前提になっています。設定と密接に関わるようなスクリプトをドットファイルと一緒に管理するのも良いアイデアですよね。
このZach Holman's dotfilesの狙いはわかりますが、得られるメリットに対して若干大げさな印象があります。
確かに、設定ファイルをディレクトリ分けして整理できるのは良いことですが、その代わりにファイル数が増え、ディレクトリ階層が深くなってしまいます。ファイル数が増えると心理的にもメンテナンスのハードルは上がります。また、「この設定どこに入れりゃいいんだ?」みたいな状況になって悩みが増えたりもします。
設定ファイルを公開しようとするプロセスで、グチャグチャだった設定ファイルが他人に見せられる程度に整理されるというのは確かにメリットかもしれません。
しかし、設定ファイルは整理さえすれば公開できるというものではありません。外部に公開していないホスト名など、設定ファイル中には公開に向かない内容も含まれているはずです。こうした公開できない設定をどう取り扱うかがZach Holman's dotfilesでは示されていません。
このあたりがクリアにならないと、「メリットはわからなくもないけど面倒だからプライベートリポジトリで管理しよう」という発想になる方が自然な気がします。
この記事を読んで「いっちょdotfilesリポジトリ作るかな」と思った方も、公開すべきでない内容をうっかり公開しないよう、注意してください。ちなみに私は公開できない情報は別ファイルにしてgit update-index --skip-worktree
でcommitの対象にしないようにしていますが、あまりスマートではないと感じています。
そもそも論として、他人の環境を使ってみると何かしら気づきがあると思うので、まずは試してみるだけでも価値があると思います(環境設定まわりは時間泥棒なので、ほどほどが大切ですが…)。
今回紹介したZach Holman's dotfilesは合わなさそうだなと思われた方も、dotfiles.github.ioで紹介されている他のdotfilesプロジェクトの中には合うものがあるかもしれません。良いものがあったら私にも教えてください!
@hnw
KLabのゲーム開発・運用で培われた技術や挑戦とそのノウハウを発信します。
合わせて読みたい
KLabのゲーム開発・運用で培われた技術や挑戦とそのノウハウを発信します。