bundle exec
って書くのがダルい。書きたくない。でもシステムに入ってたり違うバージョンの物が動いて変な動作をされても困る。どうにかしてこのダルさを解消できないかと考えてみた。
まず rbenv を使ってるなら gem でインストールされるコマンドは必ずシェルのラッパとして生成され、そこから本物が起動する様になっている。例えば rails であれば以下の様なシェルになっている。
#!/usr/bin/env bash
set -e
[ -n "$RBENV_DEBUG" ] && set -x
program="${0##*/}"
if [ "$program" = "ruby" ]; then
for arg; do
case "$arg" in
-e* | -- ) break ;;
*/* )
if [ -f "$arg" ]; then
export RBENV_DIR="${arg%/*}"
break
fi
;;
esac
done
fi
export RBENV_ROOT="/home/mattn/.rbenv"
exec "/home/mattn/.rbenv/libexec/rbenv" exec "$program" "$@"
おっと、運良く /usr/bin/env
を使ってくれている。つまりはパスを書き換えれば rails とタイプしたコマンドを自前のコマンドに置き換えられるという事だ。って事で
direnv
を入れよう。direnv - unclutter your .profile
Usage Use direnv edit . to open an ".envrc" in your 1EDITOR. This script is going to be executed onc...
http://direnv.net/
$ go get github.com/zimbatm/direnv
bash をインタラクティブシェルに使っているなら以下を .bashrc
に追加する。
eval "$(direnv hook bash)"
これでこのディレクトリ特有のフックが実行出来る。次に rails や middleman 等を起動しているディレクトリに .envrc
というファイルを作ろう。中身はパスを書き換えるだけ。
export PATH=$PWD/.bin:$PATH
シェルを起動し直すか source ~/.bashrc
した後でこのディレクトリに移動すると
direnv: error .envrc is blocked. Run `direnv allow` to approve its content.
と怒られる。すかさず
$ direnv allow
を実行しよう。さて、後は .bin
というディレクトリを作り、その中に bash
というファイルを作る。勘のいい方であればそろそろ気付いたはず。
#!/bin/bash
PATH=`echo $PATH | sed 's/^[^:]*://g'` bundle exec "$@"
追加したパスを元に戻して bundle exec "$@"
しています。これでいちいち
bundle exec middleman
とかしなくても middleman
とするだけで同じコマンドが実行出来る様になります。さようなら、
bundle exec
、いい思い出をありがとう。ちなみに shebang が bash じゃなくて perl な物を起動しようとしているなら同様に
.bin/perl
を書いてしまえば、carton exec
にも対応出来るかもしれませんね。(だらだら書いてますが
bundle install --binstubs
してそこにパス通すのでいいです)