おはこんばんちは!! 尾藤 a.k.a. BTO です。
Unixライクシステムで環境設定に使われる dotfiles。 みなさんはどのように管理しているでしょうか。 dotfiles は単に $HOME に置けば終わりではなくて、外部からとってくるツール類のセットアップもしないといけません。
やり方はいろいろあるかと思いますが、個人的には dotfiles の設定はほとんど自動化しています。 今回は dotfiles 関連のタスクを、どのように自動化しているのか紹介したいと思います。
リポジトリ
リポジトリは、こちらで公開しています。
https://github.com/bto/dotfiles
初期化
dotfiles の初期化は git clone して、make を実行するだけです。 それで dotfiles の設定と、必要なソフトウェアのインストールを行います。
% git clone git@github.com:bto/dotfiles.git
% cd dotfiles
% make
スクリーンキャストを見ていただくとわかりますが、dotfiles を $HOME に symlink を張るだけでなく、oh-my-zsh や *env 系のツールのセットアップをしています。 全ての作業を自動化しています。
アップデート
アップデートは make update を実行するだけです。
% make update
コマンド一発で、利用している外部ツールが最新の状態になるようにしています。
(GNU)Makeでタスク管理
タスクは全て Make を使っています。 Make を使うのは環境依存性の排除を重視してのことです。 dotfiles のセットアップ時は、環境が整っていない状態なので、なるべくツールの依存関係を少なくしないといけません。 Make であれば、だいたいのUnixライクシステムでは入っていますし、インストールも簡単です。
GNU Autotools の時でもやりましたが、環境依存性を少なくするために、Bourne Shell, Make を使うのは王道です。
Makefile
こちらがタスク管理で使用している Makefile です。
TOP_DIR := $(realpath $(dir $(lastword $(MAKEFILE_LIST)))) BIN_DIR = $(TOP_DIR)/bin CONFIG_DIR = $(TOP_DIR)/config DATA_DIR = $(TOP_DIR)/data RC_DIR = $(TOP_DIR)/rc TEST_DIR = $(TOP_DIR)/test VAR_DIR = $(TOP_DIR)/var ALL_TARGETS += build BUILD_TARGETS += initialize CHECK_TARGETS += CLEAN_TARGETS += DISTCLEAN_TARGETS += clean INITIALIZE_TARGETS += install INSTALL_TARGETS += TEST_TARGETS += UPDATE_TARGETS += include config/Makefile.d/*/var.mk -include config/var.mk .PHONY: all all: $(ALL_TARGETS) .PHONY: build build: $(BUILD_TARGETS) .PHONY: check check: $(CHECK_TARGETS) .PHONY: clean clean: $(CLEAN_TARGETS) .PHONY: distclean distclean: $(DISTCLEAN_TARGETS) rm -rf $(VAR_DIR)/* .PHONY: initialize initialize: $(INITIALIZE_TARGETS) .PHONY: install install: $(INSTALL_TARGETS) .PHONY: test test: $(TEST_TARGETS) .PHONY: update update: $(UPDATE_TARGETS) include config/Makefile.d/*/task.mk -include config/task.mk
大元の Makefile では具体的なタスクは記述していません。 共通の基本的なタスクの記述のみにとどめて、具体的なタスクは別ファイルから include する形式をとっています。
include config/Makefile.d/*/var.mk -include config/var.mk
include config/Makefile.d/*/task.mk -include config/task.mk
上記 Makefile で重要なのは、include している部分です。 config/Makefile.d にある .mk ファイルを自動的に読み込むようになっています。
また config/var.mk, config/taks.mk が存在すれば読み込むようになっていて、何かあったときに、個別の環境で上書きができるようにしてあります。 この2つのファイルは gitignore に追加して、コミットしないようにしています。
config/Makefile.d
config/Makefile.d には、用途単位で個別のディレクトリを作って管理しています。 こうしておくと用途毎に完全にファイルが分かれているので、追加・編集・削除がし易くなります。
config/Makefile.d/oh-my-zsh
例として oh-my-zsh をあげてみます。
OH_MY_ZSH_DIR = ~/.oh-my-zsh OH_MY_ZSH_REPO = git://github.com/robbyrussell/oh-my-zsh.git INSTALL_TARGETS += oh-my-zsh-install UPDATE_TARGETS += oh-my-zsh-update
var.mk
最初の2行で oh-my-zsh の定数の定義をしています。
次の2行で、install, update それぞれのタスクに oh-my-zsh のタスクを登録しています。
* .PHONY: oh-my-zsh-install oh-my-zsh-install: $(OH_MY_ZSH_DIR) .PHONY: oh-my-zsh-update oh-my-zsh-update: $(OH_MY_ZSH_DIR) cd $< && git fetch -p && git pull $(OH_MY_ZSH_DIR): git clone $(OH_MY_ZSH_REPO) $@
task.mk
task.mk で先ほどの oh-my-zsh-instal, oh-my-zsh-update のタスクを定義しています。
rc
rc ディレクトリには、dotfiles 自体が入っています。 先頭の "." を外したファイル名で管理をしています。
rc ディレクトリを管理するタスクは、config/Makefile.d/rc に登録しています。
結論
オトバンクの近くにはランチがおいしいお店がいっぱいあります。