Quantcast
Channel: Vimタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 5608

dotfiles 駆動開発と GitHub で管理する運用方法

$
0
0

Dotfiles Driven Development

dotfiles とは Unix 系 OS で俗に言う設定ファイルのことです。.vimrc.zshrcなど設定ファイルの多くは隠しファイルとしてファイル名の頭にドットがつくことからそう呼ばれています。

 2015-01-16 3.55.10.png

ほとんどのエンジニアは CLI 環境での開発は避けては通れないものに思います。CLI 環境は「黒い画面」として嫌煙されがちで、CLI になると格段に作業効率がダウンする人も少なく無いです。その作業を効率化するキーとなるのは、設定ファイルの習熟度にあると思います。GUI 開発環境と比べてこちらはテキストベースでカスタマイズできるため、究極まで自分好みに合わせることが可能です。こうした dotfiles のカスタマイズ駆動で開発をすることで効率性は大きく向上します。

また、基本的にソフトウェアの設定は時間コストと学習コストがかかるものです。これらを失うのは大変なディスアドバンテージとなるので、変更履歴の保存とバックアップを兼ねて GitHub で管理しましょう。

リポジトリの作成手順

(GitHub のアカウント取得から ssh の設定などは割愛します)

  1. GitHub にて username/dotfilesというリポジトリ名で作成
  2. mkdir dotfiles && cd dotfiles
  3. ホームディレクトリに転がっているドットファイルを dotfiles/に移動する
  4. シンボリックリンク用のスクリプトファイルを用意する
  5. あとは git initから git pushまで

以上であなただけの dotfiles リポジトリは完成します。しかし、筆者がしばらくこの dotfiles を運用してみてわかったことや便利だと思ったことを後述する運用方法にて説明します。

参考:

dotfiles の運用方法

dotfiles をしばらく運用してきて分かったことがあります。それは以下のことに沿ってリポジトリを整備することです。

それでは一つずつ見ていきましょう。

ワンコマンドでインストールできる

GitHub にある dotfiles リポジトリの多くは以下のようなワンコマンドですべてがインストールできるような構成になっていることが多いです。

curl https://{URL}/install.sh | bash

例:Homebrew(ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

wgetcurlのワンライナーですべての作業(ダウンロード、デプロイ、イニシャライズ)が完結できるようにしましょう。ターミナルの設定とはいえ、環境の再構築は簡単にできるに越したことはないです。ワンコマンドですぐに再構築できるのは環境が壊れることを恐れさせない強みになります。

デプロイとイニシャライズは切り分ける

  • デプロイ1とは

    多くのソフトウェアはホームディレクトリにあるドットファイルを設定ファイルとして起動時に読み込みます(例:.vimrc)。つまり、ダウンロードした dotfiles リポジトリにあるドットファイルをホームディレクトリにリンクする必要があります。コピーするだけでも同等の効果を得ることが出来ますが、シンボリックリンクを貼ることでドットファイルを書き換えても自動的に本家(リポジトリでホスティングされているドットファイル)も更新され git pushするだけで済むからです。このリンクすることを便宜上、デプロイと呼ぶことにします。デプロイ用のスクリプトファイルは大抵 install.shlink.shsetup.shといった名前でホスティングされています。

  • イニシャライズ2とは

    dotfiles リポジトリには多くの場合、これらのドットファイルの他に環境設定用の *.shファイルが同梱されています。例えば、エディタのカスタムビルドや、パッケージマネージャを通したソフトウェアのインストールやその設定などです。便宜上、これら設定の実行をイニシャライズと呼びます。

このイニシャライズと、デプロイは完全に切り分けるべきです。なぜなら、イニシャライズはその名の通り、リポジトリをダウンロードしたときにしか実行しないからです。しかし、デプロイはリンクが切れてしまったり、リポジトリに新規ファイルがコミットされたときなど、デプロイし直すことは多々あります。
また、どこかのサーバを借りて開発にするときなど、大抵の場合は設定ファイルのデプロイさえできればよく、イニシャライズは必要ありません。

dotfiles のルートディレクトリのディレクトリ構造は簡潔にする

dotfiles のルートディレクトリは GitHub でのファーストビューです。ゴロゴロと規則性もなくディレクトリが多数配置されていては、どこに何があるのかがわかりにくくなり、管理も煩雑化しナンセンスです。UNIX 系 OS の慣習に倣ったディレクトリ命名で役目を明確化させるのがスマートです(例:bin)。

参考:ファイルの命名と整理のルール

実際の dotfiles を例に解説

筆者の環境を例に、以上のルールを当てはめて紹介します。

b4b4r07/dotfiles・GitHub

詳しくは README をご覧ください。

ワンコマンドでインストールできる

上の例に示したように、curlなどのダウンローダーで一発完了できます。

bash -c "$(curl -L dot.b4b4r07.com)"

(注:URL を短くするために dot.b4bb4r07.comは GitHub の dotfiles リポジトリにリダイレクトされるようになっています)

 2015-01-16 3.55.33.png

このワンライナーが一体何をするかは README にもありますが、

  1. リポジトリのダウンロード
  2. ドットファイルのデプロイ
  3. (任意で)イニシャライズ

です。
複数の処理ありますが、ワンコマンドをコピペ ENTER するだけで完了するのでめっちゃ簡単です。

仕組みとしては、etc/にある installという名前のスクリプトファイルを Web を介して実行しているだけです(ローカルでは make install3すると、アップデート・デプロイ・イニシャライズが可能です)。

デプロイとイニシャライズは切り分ける

筆者の場合、link.shのようなデプロイ用のスクリプトファイルの代わりに、Makefileを使用しています。Makefile とはプログラムのビルド作業を自動化するツールですが、決まったプロトコルを順番に実行する用途にはもってこいの代物です。これを make deploymake initとして利用することで、簡単に切り分けることが出来ます。

Makefile
DOTFILES_EXCLUDES:= .DS_Store .git .gitmodules .travis.yml
DOTFILES_TARGET:=$(wildcard .??*) bin
DOTFILES_DIR:=$(PWD)DOTFILES_FILES:=$(filter-out $(DOTFILES_EXCLUDES), $(DOTFILES_TARGET))deploy:
    @$(foreach val, $(DOTFILES_FILES), ln -sfnv $(abspath $(val))$(HOME)/$(val);)init:
    @$(foreach val, $(wildcard ./etc/init/*.sh), bash $(val);)

ドットファイルとして、$(wildcard .??*)として指定しています。これは ...などの要素を回避しつつ、すべてのドットファイルをワイルドカードで指定しています。さすがにこれでは関係のないドットファイル(.DS_Store.git)も含まれてしまうのでホワイトリスト方式でこれをフィルタリングします。
ドットファイルを一括でターゲットとすることで、新規ドットファイルが追加されてもこの Makefile を修正する必要がないので便利です(追加修正し忘れでリンクされないなどよくある)。

また、イニット用の *.shファイルはまとめて、etc/init/以下に配置しています。こうすることで、Makefile から foreachでまとめて実行することができます。
ちなみに、etc/init/には以下の様なスクリプトファイルが保存されています。

  • Vim のカスタムビルド
  • ホームディレクトリにあるディレクトリ名の英語化
  • Zsh プラグインマネージャ Antigen のインストール
  • シンタックスハイライタ Pygments のインストール
  • OS X の defaultsコマンド群の実行

dotfiles のルートディレクトリのディレクトリ構造は簡潔にする

 2015-01-16 4.02.16.png

筆者の場合、dotfiles のリポジトリルートには以下のディレクトリしか配置していません。

  • bin/

    自作のコマンドスクリプトやバイナリなどの保管場所。.zshrcなどでは PATH=$PATH:~/binなどとしてパスを通します。ドットファイルに加えて bin/もデプロイのリストにあるので、ホームディレクトリにリンクされます。make listでデプロイされるファイル・ディレクトリの列挙が可能です。

  • doc/

    ドキュメンテーションがメインですが、ある意味エクストラファイルの保存場所です。設定ファイルでも、自作コマンドでもないもの(マニュアル他、README 用の画像など)が配置されます。

  • etc/

    設定用のスクリプトファイルや、コード関連のファイルの保存場所です。また、etc/init以下にあるスクリプトは dotfiles のインストール時のイニシャライズに使用されます。doc/との違いは、コード片か非コード片かだけです。

以上の3ディレクトリと MakefileREADME.md以外はすべてドットファイルです。見渡し良好でどのディレクトリに何があるか、どんな役割のディレクトリかがすぐに分かります。

各種プラグインについて

Vim や Zsh などプラグインで設定をカスタマイズするソフトウェアも多く、そのプラグインの管理や扱いについても注意すべきでしょう。各種プラグインはリポジトリから切り離すことが必要です。

ただのディレクトリとして取り込む

ダウンロードしたプラグインを、それぞれのプラグインディレクトリ(~/.vim/bundle~/.antigen)にコピーするだけです。しかし、この方法は次のような欠点があります

  • プラグインのアップデートの取得が大変。自分で更新を確認して上書きコピーする必要がある
  • 大きいプラグインの場合、自分のリポジトリのサイズも肥大化する
  • プラグイン数が多いとダウンロードに時間が掛かる

Git のサブモジュールとして取り込む

プラグインは GitHub などで管理されていることが多いので、アップデートなどの更新を取得するために Git のサブモジュールとして取り込む方法です。
しかし、これも自分のリポジトリサイズを大きくしたりダウンロードに時間が掛かるだけでなく、複雑な Git 操作を強いられるため初心者にはお勧めできません。

プラグインマネージャを使用する

Vim も Zsh もそれぞれ、NeoBundleAntigenといった有名なプラグインマネージャがあるのでそれを利用しましょう。

  • Vim

    筆者の場合、Vim の起動時に NeoBundle がなかった場合にのみ実行できる :NeoBundleInitというコマンドを定義しています。

    .vimrc
    let $VIMBUNDLE ='~/.vim/bundle'let $NEOBUNDLEPATH = $VIMBUNDLE . '/neobundle.vim'if stridx(&runtimepath, $NEOBUNDLEPATH)!=-1" If the NeoBundle doesn't exist.
    command! NeoBundleInit try|calls:neobundle_init()
                \|catch/^neobundleinit:/
                    \|   echohl ErrorMsg
                    \|echomsgv:exception
                    \|   echohl None
                    \|endtryfunction!s:neobundle_init()redraw| echo "Installing neobundle.vim..."if!isdirectory($VIMBUNDLE)callmkdir($VIMBUNDLE,'p')
            echo printf("Creating '%s'.", $VIMBUNDLE)endifcd $VIMBUNDLE
    
        if executable('git')call system('git clone git://github.com/Shougo/neobundle.vim')ifv:shell_error
                throw'neobundleinit: Git error.'endifendifsetruntimepath& runtimepath+=$NEOBUNDLEPATH
        call neobundle#rc($VIMBUNDLE)try
            echo printf("Reloading '%s'", $MYVIMRC)
            source $MYVIMRC
        catch
            echohl ErrorMsg
            echomsg'neobundleinit: $MYVIMRC: could not source.'
            echohl None
            return0finallyechomsg'Installed neobundle.vim'endtryechomsg'Finish!'endfunctionautocmd!VimEnter * redraw
                \ | echohl WarningMsg
                \ | echo "You should do ':NeoBundleInit' at first!"
                \ | echohl None
    endif

    これは、NeoBundle がないときに Vim を起動すると :NeoBundleInitを実行するように促し、すると git cloneで NeoBundle をインストールし、そのまま大量のプラグインをインストールします。

    参考:dotfilesをGitHubで管理,vimプラグインをNeoBundleで管理する方法メモ

  • Zsh

    Zsh ではログイン時に起動されるべき項目などを zsh_at_startupとして関数化してあります。antigen の初期化や tmux の起動などです。tmux については別記事で詳細に解説してあるのでそちらも参考にしてみてください。

    .zshrc
    antigen_plugins=("brew""zsh-users/zsh-completions""zsh-users/zsh-history-substring-search""zsh-users/zsh-syntax-highlighting""hchbaw/opp.zsh"#"tarruda/zsh-autosuggestions""b4b4r07/enhancd""b4b4r07/favdir"#"b4b4r07/zsh-vi-mode-visual")function zsh_at_startup(){# ...(省略)...
    
        tmux_automatically_attach
    
        # Antigenif[[ -f ~/.antigen/antigen.zsh ]];thenecho -e "=> $fg[blue]Setup antigen....$reset_color"local plugin
    
            source ~/.antigen/antigen.zsh
            for plugin in "${antigen_plugins[@]}"doecho"checking... $plugin"
                antigen bundle "$plugin"done
    
            antigen apply
            echo -e "=> $fg[blue]done$reset_color\n"fi# Hello, Zsh!!echo -e "\n$fg_bold[cyan]This is ZSH $fg_bold[red]${ZSH_VERSION}$fg_bold[cyan] - DISPLAY on $fg_bold[red]$DISPLAY$reset_color\n"}if zsh_at_startup;then
        zsh_set_utilities
        zsh_set_prompt
        zsh_set_completion
        zsh_set_setopt
        zsh_set_alias
        zsh_set_keybind
    fi

プラグインを自分のリポジトリに取り込む利点は、ワンコマンドで dotfiles をインストールしたときにソフトウェアの設定を完全に再現できることにあります。しかし、プラグインの数が増えるごとに容量も増え、複雑になるのが欠点でした。
そこで重要なのが、シェルやエディタなどの CLI のインフラにあたるところはプラグインなしでも、最低限に快適な作業ができるような設定を心がけるべきです。筆者の場合、エディタに必ず必要と感じているプラグイン(MRU; 最近開いたファイルリストを表示する)を自分製に小型化し、設定ファイルに関数として記述しています。
そして、プラグインはリポジトリから切り離し、それぞれのソフトウェアの中でギリギリまで設定を高めるのがおすすめです。そうすることで、プラグインをインストール出来ない環境や、まったりとダウンロードやインストールが終わるのを待っていられない状況などに即座に開発が開始できます。

まとめ

  • dotfiles のインストールはワンコマンドでする
  • 3ステップのタスク、後者2つの独立性
    • 1.ダウンロード
    • 2.デプロイ
    • 3.イニシャライズ
  • デプロイは簡単にできる
  • プラグインはリポジトリから切り離す

dotfiles の設定は楽しい

冒頭にも述べたとおり、設定ファイルのカスタマイズは CLI 環境の生産性を高めることにつながります。とても便利な CLI ライフが手に入るので、GitHub で 「dotfiles」でスターの高いリポジトリを参考にしてみたり、筆者の環境b4b4r07/dotfilesを例にカスタマイズしてみてください。



  1. ドットファイルをホームディレクトリにシンボリックリンクすること; make deploy 

  2. etc/init/以下にあるインストールスクリプトを実行すること; make init 

  3. make install = make update + make deploy + make init; ワンコマンドと違って別途にリポジトリをダウンロードし、ローカルから make installする 


Viewing all articles
Browse latest Browse all 5608

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>