DirenvでDotenvのファイル(.env)を読み込む

Dotenv環境変数をファイル(.env)から読み込むためのRubyライブラリ。 Twelve-Factor Appなどでは、アプリケーションの設定は環境変数に格納することを推奨しており、Dotenvは本番と開発で環境変数を切り替えるのにうってつけ。

一方、開発環境で環境変数と言えばDirenv。 アプリにコードを追加する必要があるDotenvに比べ、Direnvはアプリと完全に独立して動作する!

ここで、Dotenvのファイル(.env)をDirenvから読み込むことさえできれば、Direnvに完全移行できるじゃないか!

と思ったら・・・なんだ、標準で入ってました、という話。

dotenv [dotenv_path]: Loads a ".env" file into the current environment

http://direnv.net/#man/direnv-stdlib.1

すばらしい。

go-gitconfigで自作ツールの設定を~/.gitconfigに書く

Goプログラマ必携のGoライブラリ管理ツールghqは、 インストール先などを~/.gitconfigから取得するようになっています*1

まぁ、非開発者はどうするかとか、そもそも他ツールの設定ファイルに相乗りするのはどうなのかとかは問題ですが、開発者用と割り切れば、~/.gitconfigはVCSで管理しているだろうし*2、フォーマットも周知なので、専用の設定ファイルを作らせるより便利。

というわけで、ghqの真似をしたい人は go-gitconfigを使えばOK。

github.com

*1:正確にはgit configコマンドから。~/.gitconfig以外からも取得する場合もあります。

*2:管理してますよね?Git使ってない人はともかく。

PythonのfileinputをGoで実装してみた

Pythonの○○をGoで実装してみたシリーズ

fileinputは、行単位で処理を行うコマンド(特にUNIXフィルタ)を作るときなどに便利なライブラリ。

import fileinput
for line in fileinput.input():
    process(line)
  • コマンドライン引数で与えられたファイルの行に順番にアクセス
  • 引数が空の場合は標準出力の行にアクセス
  • ファイル名として '-' が与えられたときも標準出力の行にアクセス

github.com

使用例

sc := fileinput.Lines(os.Args[1:])
for sc.Scan() {
    process(sc.Text()) // 行を処理
}
if sc.Err() != nil {
    os.Stderr.WriteString(sc.Err().Error() + "\n")
    os.Exit(1)
}

// なお、ファイルハンドラを閉じる処理は.Scan()や.Err()の中で自動で行われる

Python版との違い

Go版はbufio.Scannerを真似たインターフェースにしました。 そのため、Pythonほどシンプルではありません(Pythonはfor文に渡すだけで使えるが、Go版は覚えるべきメソッドが3つもある)。

行をchan stringで返せば、Python版に近い書き心地になるような気もしましたが、 標準に合わせたいことと、チャネルを返そうとするとGoroutineを1つ余分に消費してしまうことがあり、 あきらめました。

#リハビリを兼ねて、チョチョイと書くつもりが、なぜか半日もかかってしまった・・・

Python 3.3〜3.5の変更点まとめ(標準編)

この記事は3.2まではPythonを使っていたが、しばらくPythonを離れ、最近戻ってくることになった人*1向けに、 3.3〜3.5で何があったか(何が起こる予定か)をまとめる記事です。

*1:つまり私

続きを読む

Dockerの6つのtips

1. イメージを作る方法はDockerfileだけじゃない

Packerもある。

Packer by HashiCorp

Packerは様々な仮想環境のイメージを統一的な方法で作れるツールで、VirtualboxAWS・DigitalOceanなどにも対応しています。 したがって、DigitalOceanイメージとDockerイメージを1つのソースから作るといったことができます。

PackerはDockerの全機能が使えるわけではない(差分ビルドができない)のですが、 場合によっては問題にならないかもしれません。

2.Dockerイメージはtarで保存できる

Dockerイメージをtarとして保存すれば、Jenkinsの成果物として保存したり、S3経由で配信したりできます。

tar出力するにはdocker exportを使います。また、packerはデフォルトではイメージをtarで出力します。

3. 出力ファイルをchownする

docker run-v を付けると、コンテナにホストのディレクトリをマウントできます。

ところで、一般ユーザーがdocker runを実行しても、コンテナ内部ではrootユーザーとしてコマンドが実行されているため、出力ファイルもオーナー= rootで作られます。 このとき、ホスト側のディレクトリでもファイルのオーナーがrootになってしまうため、ファイルにアクセスできなくなってしまいます。

環境変数としてユーザー名を渡し、出力ファイルのオーナーを変更するとよいと思います。

docker-test.sh

#!/bin/bash
go test -v ./... | tee /docker/output/gotest.log
EXIT_CODE=$?

useradd "${OUTPUT_USER}"
chown "${OUTPUT_USER}:${OUTPUT_USER}" /docker/output/gotest.log

exit ${EXIT_CODE}
docker run \
  --env=OUTPUT_USER="${USER}" \
   -v "/workspace:/docker" \
  centos \
  docker-test.sh

4. --rmでコンテナを削除する

普通にdocker runするとコマンド終了後もコンテナが残り、いずれこのコンテナが溜まってディスクが溢れてしまいます。

docker run--rmをつけると、コマンド成功時には自動でコンテナを削除します。

5. cidfileで失敗時にもコンテナを削除する

docker runはコマンドが失敗したときにはコンテナを終了しません。 そのため、--rmをつけていてもコンテナが残ってしまいます。

docker run--cidfile=<file>をつけるとにコンテナのIDを出力するので、後からdocker stopします。

docker run --rm --cidfile=dockercid centos /bin/false

if [ -e dockercid ]; then
  CID=$(cat dockercid | cut -b -12)
  (docker ps -aq | grep "${CID}") && docker stop "${CID}"
  rm -f dockercid
fi

6. 古いコンテナ・イメージを削除する

さらに定期的に以下のコマンドを実行すれば、さらに安心です。

for cid in $(docker ps -aq); do
  docker rm "${cid}"
done

for iid in $(docker images | awk '/^<none>/ { print $3 }'); do
  docker rmi "${iid}"
done

まとめ

DockerはWordのイルカより有能です。

メモ:ローカル環境でCookieが動かないなら、127.0.0.1を疑え。

Cookieを使った認証において、認証取得先とリダイレクト先などは同じ表記でなくてはならない。

すなわち、localhost127.0.0.1は異なるホストとみなされる。設定ではどちらかに統一すること。

VMWare fusion上のXubuntuで?GVimが正しく描画されない問題

GVimでスクロールしたり、ggでジャンプしたりすると正しく再描画されず画面が真っ黒に。

(たちの悪いことに、マウスで少しスクロールすると再描画される。  そのため、絶妙な「不便で作業効率は落ちるけど一応使えてしまう」不具合になっている)

どうやら前からある問題のよう https://groups.google.com/forum/#!topic/vim_use/_goVuyxdgWA

解決方法としては、掲示板にもあるように、最新版を諦めてv7-3-367を使うこと。

ただし、これはVimではなくVMWare Fusion側の問題かもしれない。