はじめに
少し前から話題になっているが、日本の労働生産性はG7で最も低いらしい。
日本生産性本部資料より https://www.jpc-net.jp/intl_comparison/intl_comparison_2018_press.pdf
日本は人口減少に突入していることもあって、「作業の効率化」や「自動化・省力化」をいうフレーズをあらゆる業種で聞くようになった。
ITエンジニアは、あらゆる職業の中でも最も効率化、自動化をして生産性を高められるといっても過言ではないだろう。プログラマの三大美徳(「怠惰」「短気」「傲慢」)にもあるように、同じことを何度もやらない、楽をするためにがんばるという生産性を意識した感性が重要視されているからだ。
生産性を高めることで、勉強する時間が作れたり、新しいことを経験したりするなどしてさらにスキルアップができ、さらに生産性が上がるという好循環を作り出すことができる。
この好循環を作り出すために必要な原動力、そうそれが dotfilesだ!
dotfilesとは?
dotfilesとは、ホームディレクトリに置いてあるドット(.)から始まる設定ファイル(.bashrcとか)を管理しているリポジトリのことである。シェルやエディタの設定からアプリケーションの設定まで幅白いものが置かれている。
dotfilesはGitなどでバージョン管理されており、GitHubで公開されていることが多い。(GitHub以前はオレの.bashrcを晒すぜ!などのブログタイトルでブログにそのまま貼り付けられている形式が多かった)
dotfilesを極めることで、どこで作業していても自分の環境を瞬時にサクっと作り出すことができ(ハッカーみたいでかっこいい)、いきなり快適な作業環境で、ストレスなく、生産性Maxの状態で開発をスタートできる。
まさにこれからの時代の働き方である。これからの働き方にはdotfilesが必要なのだ!
特におすすめな人
ここでどのような人がdotfilesを作るべきか具体的な対象を列挙してみよう。
- いろんなサーバー上で開発する人
- dockerとかの中で開発するのが好きな人
- 仕事柄新しいPCで作業することが多い人
- もっと効率的に作業できないかを考えている人
- 自分の環境じゃなきゃ生産性ガタ落ちする人
- パフォーマンス中毒な人
- 数ヶ月に1度そろそろOS入れ替えよかっなーってなる人
- すぐ新しいパソコンが欲しくなる人
- あれ?前も設定したと思うあれどうやるんだっけ??ってなる人
- 今日は働く気がしないけど仕事してるフリはしなくちゃいけなくて困ってる人
- 育成ゲームが好きだったり、育てがいのあるペットが欲しい人
- 次こそはミスしないぞ!と固く誓っている人
- 怠惰を極めすぎていて同じこと2回以上したくない人
- なんかハッカーっぽいおれおれ環境で周りにドヤ顔したい人
- dotfilerに「そんな非生産的な環境でよく仕事できてるね」って煽られたくない人
- 暇な人
まぁつまり全エンジニアが対象だ!!!
私の環境
あとの説明部分で環境による差異が発生する可能性が高いため、一応私の使っている環境を書いておく。
- ArchLinux
- Desktop(i3)
- zsh, tmux
- vim(neovim)
ちなみに私のdotfilesはこちら https://github.com/yutakatay/dotfiles
外部プラグインに依存していないシンプル版はこちら https://github.com/yutakatay/dotfiles-mini
今すぐにでも始められる最小dotfilesの作り方
ここからはdotfilesってのはわかったけど、具体的なはじめ方がわからないという人のために 今すぐにでも始められる簡単なやり方を書いていく。以下のとおり作業すれば、君も今日からdotfilerの仲間入りだ!
- GitHubにてdotfilesという名前のリポジトリを作成する(とりあえず、READMEだけでも作る)
- 自分のPCにdotfilesのリポジトリを
git clone
してくる(ここでは$HOME/dotfilesに置いたと想定する) - とりあえず、使っているシェルの設定(~/.bashrc)をdotfiles以下にコピーする
- 元の~/.bashrcを退避させる
mkdir backup && mv ~/.bashrc backup
- dotfilesの.bashrcにシンボリックリンクを貼る
ln -s ~/dotfiles/.bashrc ~
- あとはdotfiles以下でコミットしてpushしたら出来上がり
- 同じように管理したいものdotfilesディレクトリにコピーしてシンボリックリンクを貼っていく
dotfilesの使い方
更新時
- 作業をしているとき、ふと「なんか生産性落ちてる気がする。。。効率を上げられないかな」と考える・感じる (たとえば、ターミナルでコマンド履歴から前のコマンドを上矢印で探してくるのめんどくさいなーとか)
- ネットで調べて効率が上がる設定を見つけ出す! (fzfを使い履歴を簡単に検索する方法がヒット。なるほど、履歴をファジーサーチできるようにしてそれをショートカットとして登録すればいいのか!)
- 該当の方法を設定ファイルに入力する (この場合だとシェルの設定、.bashrc, .zshrcを更新する)
- シンボリックリンクとなっているはずなので、gitが差分を検知しているはず
- git add, commit, pushを行いremoteに反映する
構築時
- GitHubから
git clone https://github.com/xxx/dotfiles.git
でdotfilesを持ってくる - インストーラー(後述)を起動する
- はい、もう自分の環境が構築できている!
注意点
複数人でアカウントを共有している環境で作業している場合は他の人の許可を得た上でdotfilesを展開したほうがいい。(他の人がいきなり環境が変わってびっくりしてしまうため)
自分だけで使いたい場合は export HOME=/your/home/dir
と自分だけのディレクトリにHOMEを変更してそこで使えば他の人への影響を防ぐことができる。(ただしシェルにログインするたび毎回 export
を実行する必要がある)
あまりガチガチに設定したくない、他の人とも共有したいという環境用に別のdotfilesを作っておくのもおすすめ。たとえば、誰もが使いたいようなgitのステータス情報やコマンドの実行時刻の情報をシェルのプロンプトに出したものを共有用のdotfilesにしておくなど。
https://github.com/yutakatay/dotfiles-mini
何を管理すればよい?
dotfilesでよく管理されているものの例
- シェルの設定(~/.bashrc, ~/.zshrc, ~/.config/fish, etc)
- エディタの設定(~/.vimrc, ~/.emacs.el, ~/.config/Code/User, etc)
- ターミナルの設定(~/.config/alacritty, etc)
- CLIツールの設定(~/.tmux.conf, ~/.gdbinit, etc)
- アプリの設定(~/.i3, ~/.autokey, etc)
- gitの設定(~/.gitignore_global, etc)
dotfilesで管理しにくいもの
- .gitconfig(プライベートと会社でアカウントを分けている場合はUser情報が記述されているため共有しづらい)
- 環境によって動的に内容が変わるもの(シェルスクリプトで自動生成するようにする)
- シンボリックリンクを読み取ってくれないもの、ファイルで上書きしてしまうもの(~/.config/mimeapps.list etc)
- プログラムやプラグインやアプリケーション(管理してもよいが機能更新に追従できなくなるため、パッケージマネージャーやプラグインマネージャーを使ってできるだけ最新版をダウンロードするようにしたほうがいい)
[注意]dotfilesで絶対に管理してはいけないもの
- 認証情報が入っているディレクトリは 絶対に dotfilesにて管理しないこと
- .ssh, .aws等
dotfilesのディレクトリレイアウトの例
私が実際にdotfilesでどのようなものを管理しているか抜粋して記載しておく。
※ 簡略化のために実際の私のdotfilesと変更している箇所がある
dotfiles
├── .bin/ # dotfilesのインストールスクリプトとよく使う自作スクリプトを格納する│ ├── gitconfig.sh*│ ├── make_conkyrc.sh*│ ├── arch-extra-setup.sh*# メインで使っているOSの追加のインストールスクリプト│ └── install.sh*# dotfilesのインストールスクリプト├── .bin.local/ # .localがつくものはその環境でしか使わないものを格納する│ └── .gitkeep
├── .config/
│ ├── alacritty/ # ターミナルの設定ファイル│ │ └── alacritty.yml
│ ├── Code/ # みんなが大好きなVSCodeの設定ファイル│ │ ├── _install.sh*# だけどインストールした直後に設定が作られるためdotfilesとしては管理しずらいのでインストールスクリプトを用意しておく│ │ └── User/
│ │ ├── keybindings.json
│ │ └── settings.json
│ ├── nvim -> ../.vim/
│ └── systemd/ # ユーザー用のsystemdの常駐設定も管理しておくと便利│ └── user/
│ └── i3-cycle-focus.service
├── .gdbinit
├── .github/
│ └── workflows/
│ └── test.yml
├── .gitignore
├── .gitignore_global
├── .i3/ # デスクトップ環境の設定ファイル│ ├── config
│ └── i3blocks.conf
├── .ideavimrc
├── LICENSE
├── README.md
├── .tmux/
│ ├── conf/ # 行数が増えた設定ファイルで外部ファイルを読み込めるものは設定ごとに分割したほうが見通しがよくなる│ │ ├── base.tmux*│ │ ├── bind.tmux*│ │ ├── color.tmux*│ │ └── plugin.tmux*│ └── log/
├── .tmux.conf
├── .vim/
│ ├── after/
│ │ ├── ftplugin/
│ │ └── .gitkeep
│ ├── backup/
│ ├── coc-settings.json
│ ├── ftdetect/
│ ├── ftplugin/
│ ├── info/
│ │ └── .gitkeep
│ ├── init.vim -> ../.vimrc
│ ├── rc/
│ │ ├── autocmd.vim
│ │ ├── base.nvim
│ │ ├── base.vim
│ │ ├── coloring.vim
│ │ ├── command.vim
│ │ ├── display.vim
│ │ ├── init.vim
│ │ ├── keyconfig.vim
│ │ ├── mappings.vim
│ │ ├── pluginconfig.vim
│ │ ├── pluginlist.vim
│ │ └── statusline.vim
│ ├── sessions/
│ │ └── .gitkeep
│ ├── snippets/
│ │ └── .gitkeep
│ ├── swap/ # 使用しているときに一時ファイルができるディレクトリは後述のgitignoreの設定で差分が発生しないように管理する│ │ └── .gitkeep
│ ├── template/
│ │ └── .gitkeep
│ └── undo/
│ └── .gitkeep
├── .vimrc
├── .xinitrc
├── .Xmodmap
├── .xprofile*├── .Xresources
├── .xsessionrc
├── .zfunc/
│ └── .gitkeep
├── .zsh/
│ ├── completion/
│ │ └── .gitkeep
│ ├── dircolors│ └── rc/
│ ├── alias.zsh
│ ├── base.zsh
│ ├── bindkey.zsh
│ ├── commandconfig.zsh
│ ├── completion.zsh
│ ├── function.zsh
│ ├── option.zsh
│ ├── pluginconfig/
│ ├── pluginlist.zsh
│ └── prompt.zsh
├── .zshenv
└── .zshrc
- .vimrcや.zshrcなどは長くなったら(個人的には1500行超えるときつくなってくる)役割ごとでファイルを分けたほうが読みやすくなる
- .gitconfig(ユーザー名を別途入れたい)、.conkyrc(PCによってコア数等を変更したい),.i3/config(インストールされているパッケージ構成によって動的に生成したい)などのものは、生成するためのシェルスクリプトを.bin/で管理する
- 個別の環境で設定を変更したい場合に備えて設定ファイル内でローカルの設定ファイルがあれば読み込むようにしておく(.zshrc.local, .vimrc.local)
dotfiles用の.gitignoreの設定
エディタやシェルにプラグインを入れるなどし始めるとdotfiles管理下のディレクトリに勝手にファイルが作られることが多々ある。他のファイルが追加されても更新があるように見えないようにするため.gitignoreをホワイトリスト形式にする。
# 最初にすべての階層のファイルを無視します# 階層は必要なだけ追加する### all ignore ###
/*
/.*
/.*/*
/.*/*/*
/.*/*/*/*
/.*/*/*/*/*# .gitignoreは上から解釈されていくので# 管理対象のファイルをホワイトリストのように追記します### not ignore ###!/.zshrc
!/.zshenv
!/.zfunc/
/.zfunc/*# ディレクトリは管理したいけど中身はいらないときはこんな感じ!/.zsh/
!/.zsh/dircolors
!/.zsh/rc
!/.zsh/rc/*!/.zsh/rc/pluginconfig
!/.zsh/rc/pluginconfig/*!/.zsh/zkbd/
!/.zsh/zkbd/*!/.zsh/zfunc/
!/.zsh/zfunc/*!/.zsh/completion/
/.zsh/completion/*!/.virc
!/.vimrc
!/.vim/
!/.vim/*/
!/.vim/rc/*!/.vim/rc/myplugins/*!/.vim/rc/files/*!/.vim/ftplugin/*!/.vim/ftdetect/*!/.vim/template/*!/.vim/snippets/*!/.vim/after/*!/.vim/after/*/*!/.vim/after/*/*/*!/.vim/init.vim
!/.vim/coc-settings.json
!/.bin/
!/.bin/*!/.bin/*/*!/.bin/*/*/*!/.bin/*/*/*/*!/.bin.local
!/.tmux.conf
!/.tmux/
!/.tmux/conf/
!/.tmux/conf/*!/.tmux/conf/scripts/
!/.tmux/conf/scripts/*!/.tmux/log/
!/.tmux/powerline-rc/
!/.tmux/powerline-rc/*!/.gdbinit
!/.conkycolors/
!/.conkycolors/conkyrc
!/.i3/
!/.i3/*
/.i3/config
/.i3/config.local
!/.i3/scripts
!/.i3/scripts/*!/.i3/scripts/blocks
!/.i3/scripts/blocks/*!/.i3/systemd/
!/.i3/systemd/*!/.github
!/.github/*!/.github/*/
!/.github/*/*!/.ideavimrc
!/.Xmodmap
!/.Xresources
!/.xinitrc
!/.xprofile
!/.xsessionrc
!/.config
!/.config/*!/.config/*/*!/.config/*/*/*!/.gitignore_global
!/README.md
!/LICENSE
!.gitignore
!.gitkeep
シンプルなdotfilesインストーラーを作ってみよう
dotfilesを作ったが毎回手でシンボリックリンクを貼るのは面倒である。だからdotfiles用のインストーラーを作ったほうがいい。
インストーラーには、専用ツールやansibleを使う方法、Python,Rubyなどのスクリプト言語を使う方法などいろいろやり方は存在するが、今回は一番簡単なシェルスクリプトを使う方法を紹介しようと思う。
#!/usr/bin/env bashset-ue
helpmsg(){command echo"Usage: $0 [--help | -h]" 0>&2
command echo""}
link_to_homedir(){command echo"backup old dotfiles..."if[!-d"$HOME/.dotbackup"];then
command echo"$HOME/.dotbackup not found. Auto Make it"command mkdir"$HOME/.dotbackup"fi
local script_dir="$(cd"$(dirname"${BASH_SOURCE[0]}")"&&pwd)"local dotdir=$(readlink-f${script_dir}/..)if[["$HOME"!="$dotdir"]];then
for f in$dotdir/.??*;do[[`basename$f`==".git"]]&&continue
if[[-L"$HOME/`basename$f`"]];then
command rm-f"$HOME/`basename$f`"fi
if[[-e"$HOME/`basename$f`"]];then
command mv"$HOME/`basename$f`""$HOME/.dotbackup"fi
command ln-snf$f$HOMEdone
else
command echo"same install src dest"fi}while[$# -gt 0 ];do
case${1}in--debug|-d)set-uex;;--help|-h)
helpmsg
exit 1
;;*);;esacshift
done
link_to_homedir
command echo-e"\e[1;36m Install completed!!!! \e[m"
dotfilesでもCIしてみよう
dotfilesだってCIで質を高めたい!インストールしているパッケージ名称が変わったり、インストールしたプラグインの依存しているプログラムに変更があったり、インストーラーを変更したらピュアな環境でインストールが失敗するようになったり、更新してもしなくても壊れることは多い。
今回はGitHub Actionsで複数のOS(Linux Distribution)へのインストールできるか確認をする。
他にもLintや各種プラグインのインストールチェックを設定しても効果的かと思われる。
name:CIon:[push]jobs:ubuntu:runs-on:ubuntu-latestcontainer:ubuntu:lateststeps:-uses:actions/checkout@v1-name:Install required packagesrun:apt-get update && apt-get install -y git sudo-name:Install dotfilesrun:.bin/install.sh installcentos:runs-on:ubuntu-latestcontainer:centos:lateststeps:-uses:actions/checkout@v1-name:Install required packagesrun:yum install -y git sudo-name:Install dotfilesrun:.bin/install.sh installalpine:runs-on:ubuntu-latestcontainer:alpine:lateststeps:-uses:actions/checkout@v1-name:Install required packagesrun:apk add git sudo bash-name:Install dotfilesrun:.bin/install.sh installarch:runs-on:ubuntu-latestcontainer:archlinux/base:lateststeps:-uses:actions/checkout@v1-name:Update packagesrun:pacman -Syu --noconfirm-name:Install required packagesrun:pacman -S --noconfirm git sudo-name:Install dotfilesrun:.bin/install.sh installlint:runs-on:ubuntu-latestcontainer:ubuntu:lateststeps:-uses:actions/checkout@v1-name:Update packagesrun:apt-get update-name:Install packages for install repositoryrun:apt-get install -y git sudo software-properties-common-name:Install required repositoryrun:apt-add-repository "deb http://archive.ubuntu.com/ubuntu trusty-backports main restricted universe"-name:Install required packagesrun:apt-get update; apt-get install -y shellcheck-name:Execute shellcheckrun:test $(shellcheck -f gcc ~/.zshrc ~/.zsh/rc/* | grep -v "SC1036\|SC1056\|SC1070\|SC1072\|SC1073\|SC1083\|SC2034\|SC2139\|SC2148\|SC1090\|SC1117\|SC2206\|SC1009\|SC2016\|SC2046\|SC2154" | tee -a /dev/stderr | wc -l) -le 1
dotfilesを成長させていくためには?
dotfilesは作って終わりではない。しっかり育てて(メンテナンスし続けて)こそ価値がある。
他の人の作業の様子や設定を見たり、新しいツールを試したりすることであなたのdotfilesはどんどん進化していくだろう。
一般的なdotfiles関連の情報収集ができるサイトは
- GitHub topicのdotfiles https://github.com/topics/dotfiles
- Redditのr/doftiles, r/commandline, 自分の使っているシェル (例: r/zsh)
- vim-jpのSlack dotfilesチャンネル https://vim-jp.org/docs/chat.htmlに招待リンクがあります (今のところ専用のコミュニティスペースがない+人がどれくらい集まるかもわからないため、またvimmerにdotfilesが多かったため間借りしています。。。)
あたりだろう。
ただもっとも大事なのは、日々の作業の中でもう少し改善できないかな?、未来で楽をするために今できることはないかなと考え続ける心だと思う。
さいごに
dotfilesは今すぐ始められます!
日々育てていくものなので、はやく始めたほうがそれだけ生産性が上がりますよ。
dotfilesと一緒に日々成長していきましょう!!!