個人・本業・副業などで、認証アカウントや設定の異なる複数のプロジェクトを間違いを起こさず便利に使い分けるための Tips 集です。
使えそうなものをつまみ食いしてもらえると幸いです。
(前提)
作業環境
普段使っている作業環境です。必須要件ではありません。
- Mac
- bash
ディレクトリ構成
認証アカウントは大体案件毎に共通になり、その中に複数のプロジェクト(リポジトリ)があることも多いので、大体このような形にしています。
~/
.bashrc
.gitconfig
Work/
CompanyA/
ProjectA-1/
.git/
ProjectA-2/
.git/
CompanyB/
ProjectB-1/
.git/
ProjectB-2/
.git/
シェル操作関連の Tips
プロジェクト毎に環境変数を切り替える。
direnv を使います。他の使い分け設定のベースとなるアプリケーションです。
# インストールして Hook を設定します。
$ brew install direnv
$ echo 'eval "$(direnv hook bash)"' >> $HOME/.bashrc
$ source $HOME/.bashrc
# git リポジトリ内で設定するかもしれないので、グローバルに無視されるようにしてあります。
# グローバルの .gitignore については後述します。
$ echo '.envrc' >> $HOME/.gitignore
インストールしたら、必要な環境変数を各ディレクト内の .envrc
ファイルに書き込みます。
$ cd ~/Work/CompanyA
$ direnv edit .
# direnv に edit コマンドが用意されていますが、直接 .envrc ファイルを作成しても大丈夫です。
エディタが開くので以下のような内容に編集して保存します。
export FOO=foo
export BAR=bar
direnv allow
しろという警告が表示されたら素直に従ってコマンドを実行して下さい。
デフォルトでは、遡って一番近い親ディレクトリの .envrc
しか読み込んでくれないので、プロジェクト毎に定義しつつ親の案件毎のものも参照して欲しいような場合は、子の方に source_up
と書いておきます。
source_up
export FOOBAR=foobar
重複した場合は、子の方で上書きされます。
これで、そのディレクトリ配下に移動するだけで、さまざまな作業環境が一度に切り替わることになります。(後述する設定を追加していくことで)
~/.bashrc
などに移動コマンドの alias を登録しておくと Tab 補完も効いて便利です。
alias company_a='cd ~/Work/CompanyA'
(TIPS) Xcode をプロジェクト毎に使い分ける。
プロジェクト毎に使用している Xcode のバージョンが異なる場合に、コマンドライン上では xcode-select -s
で適切なバージョンを使用するように変更することができますが、これを毎回行うのは大変です。
man xcode-select
に記載されている内容になりますが、DEVELOPER_DIR
環境変数を用意することで上記コマンドの処理の代替とすることができます。
ENVIRONMENT
DEVELOPER_DIR
Overrides the active developer directory. When DEVELOPER_DIR is set, its value will be
used instead of the system-wide active developer directory.
なので、direnv で指定してあげれば、プロジェクト毎に使い分けることができます。
export DEVELOPER_DIR=/Applications/Xcode11_2_1.app/Contents/Developer
.bashrc を分けて管理する。
案件固有のシェル設定は .bashrc
を分けておいて、本体の方では以下のようにファイルを読むこむだけにしておけば、~/.bashrc
が散らからずプロジェクト終了時にメンテナンスもしやすいです。
for rc in $(ls $HOME/work/*/.bashrc 2>/dev/null); do
source $rc
done
自動的にファイルを探しにいくので、案件が追加された場合は(必要に応じて)ディレクトリ直下に .bashrc
を作るだけで OK です。
Git 関連の Tips
いつも使う Git 設定をグローバル化する。
~/.gitconfig
を用意しておけば、グローバルに設定が反映されます。
git config --global
で設定した内容が書き込まれる場所なので、こちらのコマンドで設定しても OK です。
使い勝手の向上や、いつも付けておきたいコマンドオプションを書いておきます。
例えば以下のようなものです。
[alias]
st = status
ci = commit
co = checkout
br = branch
[color]
ui = true
[merge]
tool = vimdiff
ff = false
[pull]
ff = only
[core]
autocrlf = false
quotepath = false
いつもリポジトリに Commit しないファイルを、グローバルの設定で自動的に無視する。
自分の環境だけに生成されるファイルを Git から無視したいことはよくあります。しかし、プロジェクトの .gitignore に書き込むのは抵抗があったり、毎回 .git/info/exclude
に追記するのが面倒だったりします。
毎回無視しても大丈夫という確信のあるものについては、グローバルに設定してしまいます。
# ホームにある .gitignore をグローバルの無視設定ファイルにします。
$ git config --global core.excludesfile ~/.gitignore
あとは無視したい内容を ~/.gitignore
に書いておけば以降は自動的に無視されます。direnv の設定ファイルもここに書いてあります。
.DS_Store
.envrc
確信がない場合は、リポジトリ毎に .git/info/exclude
をメンテするようにします。
Git のユーザー情報(など)を自動的に使い分ける。
よくあるのが Git ログに書き込まれる名前とメールアドレスの使い分けです。
仕事用の新しいリポジトリで、誤ってグローバルに設定してあるプライベートなメールアドレスを入れてしまったり、リポジトリ毎に毎回設定するのが面倒だったりします。
案件毎に作った親ディレクトリで一括管理し、配下のリポジトリは自動的に同じ設定が適用されるようにしたいと思います。
git config の Conditional includes を使います。
-
案件毎のディレクトリ直下に専用の設定ファイル
~/Work/CompanyA/.gitconfig.inc
を用意します。~/Work/CompanyA/.gitconfig.inc[user] name = name_on_work email = name_on_work@example.c0m
-
~/.gitconfig
にディレクトリごとのファイルを読みに行くよう設定を追加します。~/.gitconfig[user] name = name_in_private email = user_name_in_private@users.noreply.github.c0m [includeIf "gitdir:~/Work/CompanyA/"] path = ~/Work/CompanyA/.gitconfig.inc [includeIf "gitdir:~/Work/CompanyB/"] path = ~/Work/CompanyB/.gitconfig.inc
これで direnv のように、特定のディレクトリ配下では専用の設定が適用されるようになります。
ユーザー情報以外に、独自の Git 規約があるような場合にも使えます。
GitHub の複数アカウントを使い分ける。
GitHub ではアカウント間で SSH Key を使い回すことができないので、複数の SSH Key を管理することになります。
この状態では少し手を加えないと SSH 認証での git コマンドが通らないアカウントが出てきます。
アカウントが異なるのは大体案件単位なので、前項で作った ~/Work/CompnayA/.gitconfig.inc
内で設定を行います。
[core]
sshCommand = "ssh -i ~/.ssh/id_rsa_company_a
~/.ssh/id_rsa
などの、 ssh がデフォルトで読みに行くキーを使っているアカウントは設定不要です。
クラウドサービス関連の Tips
主に CLI ツールを使ったクラウドサービスの操作に関する手順です。
意図せず本番環境を書き換えてしまったりすることがないよう、設定切り替えをなるべく自動化したいと思います。
GCP 環境を自動で切り替える。
gcloud
や bq
コマンドでの、操作を行うアカウントや対象のプロジェクトを切り替えます。
これらコマンドを含む Google Cloud SDK には、アカウントやプロジェクトなどのプロパティを保持する「構成」を複数作成して、適宜切り替え可能な仕組みが用意されています。
SDK 構成の管理 | Cloud SDK のドキュメント | Google Cloud
単純には以下のような流れになります。
# 好きな名前を付けて、新しい構成を作成します。
$ gcloud config configurations create [NAME]
# 構成のプロパティを設定していきます。(以下は例)
$ gcloud auth login
$ gcloud config set project [PROJECT_ID]
# 別の構成に切り替えるのは activate コマンドになります。
$ gcloud config configurations activate [NAME]
# 作成された全ての構成のリストは、以下で確認できます。
$ gcloud config configurations list
gcloud config configurations activate
で切り替えていく仕組みも十分便利なのですが、全コンソールセッションで同じ構成が有効になるという(自分の使い方では)問題があります。
- コンソールセッション毎に有効な構成を変えたい。
- direnv と連携して、今いるディレクトリに応じて自動的に構成を変えたい。
という挙動にしたい場合は、上記の設定に加えて direnv の .envrc
に設定を付け加えます。(公式ドキュメント にも記載があります。)
export CLOUDSDK_ACTIVE_CONFIG_NAME=CompanyA-dev # gcloud config configurations create で付けた NAME を指定します。
AWS 環境を自動で切り替える。
aws
コマンドでの、アクセスキーを元にした認証情報や初期リージョン設定などを切り替えます。
aws コマンドをインストールした直後、aws configure
コマンドでアクセスキーや初期リージョンを入力させられると思います。
この時 default
の Profile が作成されるのですが、Profile は複数作成することができます。
以下のような流れになります。
# 好きな名前を付けて Profile を作成します。
$ aws configure --profile=[NAME]
# アクセスキーや初期リージョンの入力が求められ、Profile が作成されます。
# Profile を指定してコマンドを実行できます。
$ aws s3 ls --profile=[NAME]
# 作成された全ての Profile は、以下で確認できます。
$ cat ~/.aws/config
# 現在有効な Profile は以下で確認できます。
$ aws configure list
Profile は、環境変数 AWS_DEFAULT_PROFILE
によって切り替えることができるので、これを direnv を使って自動設定されるようにします。
export AWS_DEFAULT_PROFILE=[NAME] # aws configire --profile= で付けた NAME を指定します。
Kubenetes 環境を自動で切り替える。
kubectl
コマンドでの、操作を行うユーザーや対象のクラスターを切り替えます。
kubectl ではユーザーとクラスターを組み合わせて context として管理し、適宜切り替え可能な仕組みが用意されています。
Configure Access to Multiple Clusters - Kubernetes
ですが、gcloud の場合と同じくデフォルトの状態では、全コンソールセッションで同じ context が有効になってしまいます。
また、自動切り替えも実現したいため、 ここでも direnv を使って(context の保存ファイルを変更する)KUBECONFIG
環境変数が自動設定されるようにします。
※ context を設定する前に行う必要があります
export KUBECONFIG=$(pwd)/.kubeconfig
あとはディレクトリに入って context を作成し利用します。(以下は GKE の場合の例)
# 認証情報を取得して context を作成する。
$ gcloud container clusters get-credentials company_a_cluster_name --region us-west1
# 作成された全ての context は、以下で確認できます。
$ kubectl config get-contexts
# 自動で長い名前が付いているので、気になるようなら分かりやすい名前に付け替えます。
$ kubectl config rename-context [OLD_LONG_NAME] [NAME]
# context が 1 つの場合は、いつもそれが有効になります。
# 複数の context を作成した場合は、 適宜 use-context コマンドで切り替えます。
$ kubectl config use-context [NAME]
Firebase 環境を自動で切り替える。
firebase
コマンドでの、操作を行うアカウントを切り替えます。
firebase コマンドには、他のコマンドのような構成やプロファイルのような仕組みは見つけられていません。
ただし、CI用ということになっていますが、環境変数にトークンを設定してアカウント認証できるので、これを使います。
# CI 用のトークンを入手する。ブラウザに誘導されるので適切なユーザーを選択すると、コンソールにトークンを出力されます。
$ firebase login:ci
Visit this URL on this device to log in:
https://accounts.google.com/o/oauth2/auth?client_id=...
Waiting for authentication...
✔ Success! Use this token to login on a CI server:
# ここにトークン文字列が出力されます。
トークンを環境変数 FIREBASE_TOKEN に入れておくことで、firebase コマンドはそれを元に認証を行ってくれるので、direnv を使って自動設定されるようにします。
export FIREBASE_TOKEN=トークン文字列
現在の状態をターミナルに表示して注意を促す。
プロンプトにクラウドサービス毎の現在の設定名を表示しておくと、すぐに確認できて間違いも起きにくいです。
リスクのある環境になっている時だけ表示された方がアラートになるので、プライベートな環境には 'default' や 'private' といった設定名が付くようにしておいて、その場合は何も表示しないようにしています。
~/.bashrc
に以下のような内容を追記しておくだけです。
function cloudps1() {
if [ -x "`which gcloud`" ]; then
__gcp=${CLOUDSDK_ACTIVE_CONFIG_NAME:-default}
fi
if [ -x "`which aws`" ]; then
__aws=${AWS_DEFAULT_PROFILE:-default}
fi
if [ -x "`which kubectl`" ]; then
__kube=`kubectl config current-context`
fi
if [ -n "${__gcp}" ] && [ "${__gcp,,}" != 'private' ] && [ "${__gcp,,}" != 'default' ];then
echo -en "${__gcp}\U1F176 "
fi
if [ -n "${__aws}" ] && [ "${__aws,,}" != 'private' ] && [ "${__aws,,}" != 'default' ];then
echo -en "${__aws}\U1F170 "
fi
if [ -n "${__kube}" ] && [ "${__kube,,}" != 'private' ] && [ "${__kube,,}" != 'default' ];then
echo -en "${__kube}\U1F17A "
fi
}
PS1='\[\e[01;30;43m\]$(cloudps1)\[\e[00m\]'$PS1