挫折しないdotfiles運用 〜Windows・MacOSで使える設定ファイルを目指して〜

# きっかけ
今まで何度かdotfiles運用をおこなったことがあるのですが、理解が中途半端で運用が煩雑でそのたびに挫折してきました。

しかし、下記記事に出会ったことで今までが嘘のように理解することができたので今のうちに記事にしてしまおうと思いました。

少しでもこの記事でdotfiles運用で挫折する人が減るといいなーと思います。

[優れた dotfiles を設計して、最速で環境構築する話 \- Qiita](https://qiita.com/b4b4r07/items/24872cdcbec964ce2178)
[最強の dotfiles 駆動開発と GitHub で管理する運用方法 \- Qiita](https://qiita.com/b4b4r07/items/b70178e021bef12cd4a2)


# 対象
dotfiles運用に憧れてるけど、うまくいかない人
Windows・MacOSで使える設定ファイルを運用していきたい人

# 私のdotfiles
[snyt45/dotfiles](https://github.com/snyt45/dotfiles)
※日々育成中・・・

# 「挫折しない」dotfiles運用
## 挫折の要因
自分の場合は、以下のようなことがよくありました・・・
![挫折の要因.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163887/bdf027fb-04b5-4033-f196-43eab9dd27a1.png)

**ひとつ言えるのは、運用イメージつまり運用の流れが理解できていなかったのは挫折の大きな要因かなと思います。**
とりあえずGitHubでドットファイルをホスティングしておいてほしいときに持ってくればいいんでしょ。くらいでした。
これだと運用がうまくいかずに挫折するのは当たり前ですね。

## dotfilesの運用サイクル
運用でよく行うのは、**「インストール(初回のみ)」「アップデート」「デプロイ」**の3つになります。

初回のみインストールで.dotfilesを落としてきて、それをホームディレクトリ配下にシンボリックリンクとして展開します。
こうすることで、インストール後即座に設定が有効になります。

設定に手を加えたら、変更内容をリモートリポジトリに反映させます。

別のPCで作業をするときは、アップデートでリモートリポジトリから最新の設定内容を~/.dotfilesに反映させます。
次に、デプロイで最新の設定内容を~/配下に反映させます。

![dotfiles運用サイクル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163887/53e8b329-4fe9-cd9d-1199-f8f0b865c376.png)

## dotfiles運用イメージ
運用でよく行う**「インストール(初回のみ)」「アップデート」「デプロイ」**の3つについては、コマンド化して定型化させることで複雑な運用をシンプルにします。

そして、**重要なのがどの環境でも動くことが一番大事になります。**コマンドについては次で説明します。

![dotfiles運用イメージ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163887/b9e2b08b-6eba-c7f5-0c60-91cc64a3c0ca.png)

## dotfiles運用コマンド
インストールコマンドには**シェルスクリプト**を、アップデートとデプロイコマンドは**make**を採用しています。

シェルスクリプトはwindows、Macともbashで実行することを想定します。**bashさえあれば、動かすことができるのでプラットフォームの差を無視することができます**(あくまでも、windowsのbashはLinuxコマンドに近いwindowsコマンドを実行しているだけなので、シンボリックリンクなど一部コマンドは違う挙動になります。WSLを使えば100%Linux上で動作するので、同じ環境で動かすことができます)。

makeは昔からあるビルドツールで、Macはmakeがデフォルトで入っています。**windowsもmakeをインストールさえすれば、すぐに使えるのでこれもプラットフォームの差を無視することができます。**

### インストール
シェルスクリプトで作ります。

下記コマンドでgithubにホスティングしてあるinstallを実行できます。

```
bash -c "$(curl -L raw.githubusercontent.com/snyt45/dotfiles/master/etc/install)"
```


インストールでやっているのは、大きく2つです。

1つ目は、dotfilesをホームディレクトリにgit cloneしています。

**実行前に、gitコマンドが使えるかを確認し、gitコマンドが使えればgitコマンドを使う。
gitコマンドがなければcurlまたはwgetコマンドを使うようにすることによってプラットフォームの差を無視することができます。**

```shell

##############################################################################
# dotfilesをホームディレクトリに複製
##############################################################################
# gitコマンドが存在すれば、gitを使う
if is_exists "git"; then
    git clone --recursive "$DOTFILES_GITHUB" "$DOTPATH"
# curl または wget が存在すれば、それを使う
elif is_exists "curl" || is_exists "wget"; then
    local tarball="https://github.com/snyt45/dotfiles/archive/master.tar.gz"
    if is_exists "curl"; then
        curl -L "$tarball"
    elif is_exists "wget"; then
        wget -0 - "$tarball"
    fi | tar zxv
    command mv -f dotfiles-master "$DOTPATH"
else
    log_fail "curl または wget が必要です"
    exit 1
fi
```


2つ目は、落としてきた~/.dotfiles/の中で`.`がつくものを列挙して、シンボリックリンクを作成しています。
これによって、~/配下に`.`がつく`.vimrc`や`.bashrc`が配置されるので設定が反映するようになります。
また、このとき~/配下に展開したくないものは`[ "$f" = ".git" ] && continue`としてシンボリックリンクを作成せずに次の処理に移るようになっています。

```shell

##############################################################################
# /Users/[ユーザー名] 配下にシンボリックリンク(参照)を作成
##############################################################################
# 移動
command cd ~/.dotfiles
# コマンド実行時の終了ステータスが正常(0)でなければエラー
if [ $? -ne 0 ]; then
    log_fail "not found: $DOTPATH"
    exit 1
fi
# ドットファイルを列挙して、シンボリックリンクを作成
for f in .??*
do
    # 一致したら、シンボリックリンクを作成せずに次の処理に移る
    # 不要なドットファイルを対象から除外する
    [ "$f" = ".git" ] && continue
    [ "$f" = ".DS_Store" ] && continue

    ln -snfv "$DOTPATH/$f" "$HOME/$f"
done
```

### デプロイ
Makefileで作ります。

~/.dotfilesに移動して使います。

```
make deploy
```

インストールで2つ目にやっていることのみを切り出したものです。
(ここでは、~/.dotfilesの`.`がつくファイルを~/配下に展開することをデプロイと呼んでいます。)

Makefileの書き方があるので、見た目は変わってますがやっていることはインストール時と同じです。

```Makefile
# デプロイ
deploy:
	@$(foreach val, $(DOTFILES_FILES), ln -sfnv $(abspath $(val)) $(HOME)/$(val);)
```

### アップデート
Makefileで作ります。

~/.dotfilesに移動して使います。

```
make update
```

やっていることは、git pullです。
makeコマンドにすることで運用がとても楽になります。

```Makefile
# 更新
update:
	git pull origin master
```


# この記事で説明していないこと
dotfilesの管理・運用手法はさまざまですが、下記記事を参考にしています。

* dotfilesで管理するもの
* vimプラグインの運用

[優れた dotfiles を設計して、最速で環境構築する話 \- Qiita](https://qiita.com/b4b4r07/items/24872cdcbec964ce2178)
[最強の dotfiles 駆動開発と GitHub で管理する運用方法 \- Qiita](https://qiita.com/b4b4r07/items/b70178e021bef12cd4a2)

* .gitignoreの運用

[ようこそdotfilesの世界へ \- Qiita](https://qiita.com/yutakatay/items/c6c7584d9795799ee164#dotfiles%E7%94%A8%E3%81%AEgitignore%E3%81%AE%E8%A8%AD%E5%AE%9A)

# さいごに
この記事で紹介しているコードは全体の一部です。
実際に自分で作る方はGitHubを参考にしてもらえればと思います。
元記事をみたら一発でわかることも多いのでそちらを参照していただけると嬉しいです。

一度、運用が回ればあとは設定ファイルの育成に集中ができて、どのプラットフォームでもすぐにいつもと同じ環境で作業できるという快適ライフが待っているのでぜひお試しあれ。