Makefile
OriginalトレタDay 10

Makefile for dotfiles

この記事はトレタ Advent Calendar 2017の10日目の記事ですが、トレタの業務にはなーんも関係のない小ネタです。

ドットファイルを Git で管理するのは、ある種のソフトウェアエンジニアにとっては嗜みのひとつくらい当たり前のことになっている気がするけど、ドットファイルをどうホームディレクトリ直下にインストールするか?については語られることもなく(語るほどのものでもない、ともいう)、多くの場合で「まぁ動けばええやん?」くらいの感じで install.sh のようなシェルスクリプトに ln -s .gitconfig $HOME/.gitconfig みたいなやつを羅列したりなどなどされてる気がする。

ドットファイルをVCSで管理し始めた頃は自分もそうしてたが、今は以下のような Makefile を書いてその辺の処理をやってる。

home    = $(HOME)/
basedir = $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
sources = $(shell git ls-files | grep -Ev '(Makefile|\.gitmodules)$$')
targets = $(addprefix $(home),$(sources))

install: $(targets)

$(targets):
    @mkdir -m 700 -p $(dir $@)
    ln -s $(subst $(home),$(basedir),$@) $@

この Makefile ももちろんコミットしてあるので make と実行すれば、ホームディレクトリ直下にシンボリックリンクがはられる感じ。

これ自体はシェルスクリプトでやっつけるのとなんも変わらないけど、この Makefile には以下のようなコマンドなんかも一緒にまとめて、開発環境をいい感じにメンテできるようにしてて結構便利。

たまーにやるけどいざやろうとしたときにコマンド忘れてる Homebrew の一連の update とか↓、

update:
    brew update
    brew bundle
    brew bundle check
    brew cleanup

Mac 買い替えたときとかに1回設定すればおしまいなんだけど、前の設定なんだっけ?みたいなやつのメモも兼ねてとか↓、

keyrepeat:
    defaults write -g InitialKeyRepeat -int 15
    defaults write -g KeyRepeat -int 1

バイナリを管理するのではなく、もとのテキストファイルを管理してコマンド実行したい(それも忘れるしメモもかねて)以下のようなやつとか↓。

terminfo:
    tic -x xterm.terminfo
    tic -x tmux.terminfo

こういうのはドキュメントにするのも1つの手だけど、実行可能な状態で直接的に管理できるという点において Makefile のほうが優れてると思うし、依存関係がルールにのっとって記述できるという点でシェルスクリプトよりも優れてるので、個人的にちょいちょいいろんなところに忍ばせてる。Makefile という場があると記録しておこうという気にもなるし、そうなったときの敷居も低いし、共有もしやすい。なぜか Go のおかげで Makefile が見直されている気もするけど、せっかくなのでその場がもっと有効活用されるとよいなと思ったり。

最後に誰も得しないかもしれないフルバージョンを以下にコピペしておく。

## -*- mode: makefile-gmake; -*-
home    = $(HOME)/
basedir = $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
sources = $(shell git ls-files | grep -Ev '(Makefile|Brewfile|\.gitmodules|\.terminfo)$$')
targets = $(addprefix $(home),$(sources))

install: $(targets) ## Install dot files into $HOME as symlink (Default)

$(targets):
    @mkdir -m 700 -p $(dir $@)
    ln -s $(subst $(home),$(basedir),$@) $@

terminfo: ## Install extra terminfo for tmux
    tic -x xterm.terminfo
    tic -x tmux.terminfo

update: ## Update homebrew stuff
    brew update
    brew bundle
    brew bundle check
    brew cleanup

keyrepeat:
    defaults write -g InitialKeyRepeat -int 15
    defaults write -g KeyRepeat -int 1

help:
    @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'