rbenv など *env でどの設定 (global, local, shell) を参照しているか知る

rbenv *1rbenv version-origin というサブコマンドがあり、それは「rbenv がバージョンを決定するのに使われた設定」を出力する。

出力は次の3つのうちのいずれかとなる。すなわち:

  • global の設定
    • $HOME/.rbenv/version
  • ディレクトリごとの設定 (local)
    • $HOME/myproj/.rbenv-version
  • シェルのプロセス固有 *2 の設定 (shell)
    • RBENV_VERSION environment variable

つまり rbenv version-origin の出力が:

  • global の設定ファイルに一致するならば global
  • global の設定ファイルに一致せず、ファイルとして読取可能ならば local
  • それ以外は shell

という風になる。

それでこのような zshスクリプトを書いた。たぶん bash でも動く。

dotfiles/.zsh.d/functions/llenv_version_origin at 78327cd0349b53686cacada45b1252a2cd38a95f · aereal/dotfiles · GitHub

*1:以下、plenv や pyenv など anyenv で管理できるものについてはそれぞれに読み替える

*2:厳密には環境変数 RBENV_VERSION が export されているあいだ

ログインシェルに fish を指定しているときに Vim の system 関数を実行すると E484 が発生する

解決

set shell=/bin/sh する。あるいは POSIX 互換のシェルを shell オプションに設定する。

原因

Vimsystem 関数はシェルに文字列を渡してコマンドを実行しようとするが、実行するシェルが POSIX 互換であることを期待している。

Homebrew で入れた Pow が起動しなくなる問題の解決

brew install pow したあと brew info pow に書かれている以下の手順でインストールした Pow が突然起動しなくなった。

sudo pow --install-system
pow --install-local

原因

~/Library/LaunchAgents/cx.pow.powd.plist にインストールされるプロパティ・リストの起動時の引数として Homebrew でインストールした noderealpath が書かれているが、この realpath にはバージョン番号が含まれているため、Pow をインストールした時点から node のバージョンが変わることによって存在しないパスを参照して起動に失敗した。

symlink を参照しても特に支障はないと考えたので起動時の引数を変更した。

diff --git a/cx.pow.powd.plist b/cx.pow.powd.plist
index e6e4e27..ded9906 100644
--- a/cx.pow.powd.plist
+++ b/cx.pow.powd.plist
@@ -6,8 +6,7 @@
         <string>cx.pow.powd</string>
         <key>ProgramArguments</key>
         <array>
-                <string>/opt/homebrew/Cellar/node/0.10.24/bin/node</string>
-                <string>/opt/homebrew/Cellar/pow/0.4.1/libexec/bin/pow</string>
+                <string>/opt/homebrew/bin/pow</string>
         </array>
         <key>KeepAlive</key>
         <true/>

結論

  • launchd に登録するプロパティ・リストには標準出力・標準エラー出力のリダイレクト先も指定しておく
    • StandardOutPath
    • StandardErrorPath

Go-lang で書かれた Fast GitHub command line client: gh を試している

jingweno/gh · GitHub

Go で書かれた hub の port のひとつ、と表現するのが簡潔でわかりやすい。

インストールの方法はいろいろある

拡張・追加しているサブコマンドは hub のそれとあまり変わらない。

hub のおよそ2倍ほど速いので、alias git=gh してもそれほどストレスを感じない。

コードもそれほど規模も大きくなくあまり凝ったことをしていないので Go-lang のコード・リーディングにもまあまあよさそう。

かばん情報

情報が集まっているので僕も提供します。

通勤、散歩

master-piece | MSPC PRODUCT : Effect No.12341

http://www.master-piece.co.jp/products/effect12341/12341-01.jpg

これのベージュを使っている。

通勤 (徒歩20分) やカメラを持っての散歩に使っている。一番使う頻度が高い。

なぜ大きくて重い一眼レフを毎日持ち歩いているかというと、昼休みにでかけて写真を撮るのが日課でありリフレッシュするための重要なアクティビティで、自分が写真を撮るとき最も信頼している道具が大きくて重たい一眼レフであるところの K-3 だからである。

モバイルバッテリの類は持ち歩いていない。平日はオフィスで仕事をしていて電源には困らず、休日など撮影にでかけるときはカメラを手にしている時間が長く、地図を見るなどの使い方の範囲では HTC J One は充分に電池が持つので信頼している。

休日は MacBook基本的に持ち歩かない。

休日などに撮影がてら散歩するときはのべ6〜7時間くらい鞄を背負ったまま歩いたり立っているので、中身は絞ってとにかくできるだけ身軽であろうとしている。

また、移動は大半が徒歩か鉄道であり、徒歩のときは考え事をする重要な時間だし、鉄道に乗って景観を楽しんでいるので、いわゆる暇潰し用のガジェットはいらず、スマートフォン (HTC J One) ひとつで事済んでいる。

気に入っているところ
  • 軽い (700g)
  • ちょっと雨にあたっても大丈夫 (撥水加工してある)
  • いいところにポケットがある
気に入っていないところ
  • ラップトップを入れるところがついていないのでパタパタする
  • K-3 + FA 77mm を入れるとちょっときつい
  • 1室しかなくてごちゃごちゃしがち
中身の様子 (通勤)

f:id:aereal:20140114022331j:plain

  • MacBook Pro with Retina Display 13インチ
  • PENTAX K-3 + smc PENTAX FA 77mm F1.8 Limited
  • Black Rapid R-ストラップ METRO
  • 財布
  • ケータイ
  • イヤフォン
    • 今まで使っていたやつが壊れたので HTC J One についてた試供品を使っている

ちなみにストラップは Black Rapid の R-ストラップという製品で、長さの調節が簡単だったり着脱が簡単だとかあってとても便利。

R-ストラップ METRO/メトロ

R-ストラップ METRO/メトロ

休日は MacBook が抜けて、代わりにクッションケースにレンズを1本入れたものを足したり、GXR を足したりする。

外出用 (1泊くらい)

Cote & Ciel のメッセンジャーバッグを使っている。

Cote&Ciel Laptop Messenger 2012 for 15 NEW TOFFY BROWN

Cote&Ciel Laptop Messenger 2012 for 15 NEW TOFFY BROWN

帰省するとき、東京に行くときに何度か使った。おしゃれな見た目に惚れて買ったけれどあまり使っていない。

17インチまで入る大きいサイズを買ったのだけれども、物はたくさん入るが、それに耐えられる肩がないので実用的ではない。このかばん自体がそこそこ重い (1kg くらい)。

着替えなどを持つ必要のある外出が1年に数回しかなく、そのうちのほとんど (あるいは全部) が帰省であり、その時にはトランクケースを持っていくことが多いのでやっぱり使う頻度は少ない。

気に入っているところ
  • ラップトップを入れる専用のコンパートメントがある
  • かわいい
  • 色がいい
  • アクセスしやすい外側にポケットが2つある
気に入っていないところ
  • 重い (これだけで 1kg くらいある)
  • 汚れが目立ちやすい (色がくすむ)
  • コットンキャンバスなので雨に濡れるとだめそう
  • マチが短いのでカメラを入れるのにあまり向いていない
  • 大きすぎる
    • たくさんものが入れても先に肩がおかしくなるので実用的ではない

雑談 (1)

余談だけれども、「これさえあれば (ある程度の妥協はありつつも) だいたいなんとかなる」的なデバイスとしてスマートフォンは存在していると思っているので、スマートフォンを持ちながらさらにごちゃごちゃとガジェットの類を持ち歩くのは前時代的だと思っているのでタブレットは持ち歩かないことにしている。*1

雑談 (2)

一眼レフを持ち歩くことについて、まあまあ葛藤もある。

  • そもそもカメラを持ち歩くこともないのではないか
  • もっと小さいカメラを使えばいいのではないか

OM-D E-M1 とか α7R とか見て、小さいなあ、と感心したし、けっこうぐらっと来た。α7R はともかく OM-D E-M1 はマイクロフォーサーズフランジバックが短いという利点を最大限に活かした小型化が行き届いていて素晴らしいなあ、と思う。

また、GXR や過去に持っていた SIGMA DP3 Merrill などコンデジもよく撮れるカメラだってたくさんある。

操作性がどうのという話もあるが、けっきょく FA 77mm に完全に参ってしまっており、これがある限りちょっとやそっとのことでは他のカメラシステムには手を出せないな、と思った。(他のレンズ交換式カメラも調べたけれど、これに匹敵するほどコンパクトで好みの写りをするレンズは見つけられなかった)

学び

  • そこそこ重いもの (2, 3kg〜) を持ち歩くならバックパックのほうがよい
  • ショルダーバッグにたくさんものを入れても重くて人間が耐えられない
  • 少なくともラップトップ用のコンパートメントがあると便利
  • 持ち歩くものを減らせば心身共に負担が減る

*1:けれども Kindle Paperwhite はかさばらないしいいかな、ってちょっと思っている

AquaSKK をインストールする Cask を書いた

homebrew-cask

homebrew-cask という OS XGUI アプリケーション (*.app のこと) も Homebrew のような DSL で管理できたらいいじゃん、という発想に基づいたプロジェクトがある。

homebrew-cask は tap という Homebrew に formula を追加する仕組みの上にできていてなかなか筋がよいと思う。

Cask を書く

自分は IME として AquaSKK を利用しているので、homebrew-cask を使ってインストールできるようにしようと思う。

homebrew-cask/CONTRIBUTING.md at master · phinze/homebrew-cask · GitHub

Cask *1 の書き方は上記のとおり、Formula と似ている。

Uninstall のサポートが興味深い。

OS XGUI アプリケーションはインストールされたパスではないところに設定などを保存したりする場合があるので後片付け処理を行わないといけないので、そのためのサポートが含まれている。

AquaSKK は pkg 形式で配付されているので、uninstall メソッドに :pkgutil オプションを渡す。

Cask を提供する tap をつくる

リポジトリ・ルート下にある Casks/*.rb を Cask として認識するようだった。

注意しなければいけない点として、tap として妥当なリポジトリ名の正規表現(homebrew-)?(\w+) なので - (ハイフン) は使えない。

In a nutshell, your repository name can only contain letters, numbers, and underscores.

brew tap · Homebrew/homebrew Wiki · GitHub

それでできた tap:

README に書いてあるとおり、brew tap aereal/homebrew-aereal_casks を実行すると使えるようになる。

brew cask install aquaskkAquaSKK がインストールできるようになる。

どうぞご利用ください。

*1:Homebrew で言う Formula

OS X の Network Locations を使ってプロキシの設定を分ける

SOCKS プロキシ

社内サーバなどファイアウォールの内側にあるサーバに SSH するために SOCKS プロキシを経由する必要がある。

また ProxyChains のようなソフトウェアを使って SOCKS プロキシ下でも名前解決ができるようにしたい。(参考: (ProxyChainsの最新版でSOCKS5プロキシを使った名前解決が出来るようになってた - yanbe.diff - subtech])

下記のような proxy.pac を書くと名前解決ができるようになる。

function FindProxyForURL(url, host) {
  if (/private\.host$/.test(host)) {
    return "SOCKS5 127.0.0.1:9050";
  else {
    return "DIRECT";
  }
}

ところでいつでも SOCKS プロキシを使いたいわけではない。SOCKS プロキシを使いたいのはリモートで作業する (自宅勤務、障害対応) ときなので。

都度、プロキシの設定を手で変えるのは煩雑なので自動化しやすい方法を考えたい。

Network Locations

そこで OS X の Network Locations を使う。(Network) Location とはネットワークの設定をまとめたものである。

What is a "location?"

In the Network preference pane of System Preferences, a location is a set of network preferences.

Using network locations (Mac OS X v10.6 and later)

(ちなみに最初から "Automatic" (ロケールによっては「自動」) という Location が存在している。)

Location を新たに作るには “System Preferences.app” で “Network” を開いて GUI で操作する方法 (詳しくはApple のドキュメントに書いてある) と、networksetup コマンドを使う方法とがある。(こちらも man networksetup すると詳細が読める)

Location ごとにプロキシの設定を含めたネットワークに関する設定を分けることができる。

たとえば nomad という Location を自宅作業用につくる。この Location に対してプロキシの設定を行う。nomad という Location を選択しているあいだはこの設定が有効になり、別の Location に切り替えると設定も切り替わる。

DNS の設定なども Location ごとに分けられるので、たとえば Google Public DNS を使う場合と使わない場合で分ける、といった使い方が考えられる。

ほかにも networksetup コマンドは Network.prefpane で編集できる設定はだいたい編集できるようだった。

はてなブックマーク REST API のクライアントライブラリ in Ruby

aereal/hatena-bookmark-restful · GitHub

JSON over HTTP な API であるのではたして「クライアントライブラリ」が必要なのか怪しい気もするけれど、手軽に API を利用しようと思ったときに生の Hash じゃなくてちゃんとオブジェクトが返ってくると嬉しいこともあるだろうと思って書いた。

どうぞご利用ください。

ついでにおしゃれポイントについて書いておく。

*1:この表現が正しいのかはわからない、include する module or class

2013→2014

2013年のこのブログではなんらかのトピック (たいていはソフトウェア技術) に関してなんらかの成果を生み出したら書く、というようなルールで概ね運用されていた。

自分の中で「成果」=「結果」に対するハードルが高くなりすぎた結果、なにか書こうと思っても「これはちょっと……」と思うことがあって手が止まることがあった。

本当はこのブログに書いてきた以上になにかしらの取り組みを行ってきた *1 ので、今年はそれを記していくことを疎かにしない。

きちんと試行錯誤を記録する。

*1:社内ブログ見たらたくさん書いてあった

ソフトウェア・テストと Web サービスの寿命







より低レベルな Git コマンドを使って他のプログラム (e.g. Vim) と連携する

このエントリはGit advent calendar 2013の24日目のエントリです。


私は普段から Vim というテキストエディタを使ってコードを書いています。

また unite.vim というプラグインをファイルやバッファを選択して開くといった用途などに利用しています。unite.vim はもっと汎用的で強力なプラグインですが詳しい説明は他に譲ります。

つまるところ unite.vim は「列挙」した候補を「選択」しなにかのアクションを「実行」するためのプラグインです。

ところで Git を利用した開発ではマージ時のコンフリクトに遭遇することがしばしばあり、たまに大量のファイルが一度にコンフリクトしそれを解決しなければならない、いわゆる「コンフリクト解決地獄」に遭遇することが稀によくあります。

それを解決するために git status などの出力を眺めながらエディタでいちいち開いて解決していては日も暮れてしまいます。

そこで unite.vim の力を借りることにします。

" unite-git-files-conflict {{{
let s:unite_git_files_conflict = {
      \   'name' : 'git/files/conflict',
      \ }
function! s:unite_git_files_conflict.gather_candidates(args, context)
  let output = unite#util#system('git diff-files --name-only --diff-filter=U')
  let candidates = map(split(output, "\n"), '{
        \ "word" : fnamemodify(v:val, ":p"),
        \ "source" : "git/files/conflict",
        \ "kind" : "file",
        \ "action__path" : fnamemodify(v:val, ":p"),
        \ }')
  return candidates
endfunction
call unite#define_source(s:unite_git_files_conflict)
" }}}
dotfiles/.vim/vimrc at 41908c62aa6347ba737cf2e6f1db9b163001eb03 · aereal/dotfiles · GitHub

肝は git diff-files --diff-filter=U です。git-diff-filesgit-diff のような人間が扱うことを想定している高レベルなコマンド *1 より低レベルで機械で処理しやすい出力を備えたコマンド *2 です。

--diff-filter オプションは表示するファイルを状態でフィルタします。たとえば A を引数として渡すと「ステージに上がっている」=「index に登録されている」ファイルのみを表示します。

この値は git status --short の出力と互換があるのでそれを意識すると覚えやすいかもしれません。詳しくは man git-diff-files で。

他にも Git には低レベルなコマンド群が存在し、一部の人間むけのコマンドはそれらを組み合わせたものでもあります。

低レベルなコマンド群はより機械的に処理しやすいフォーマットの出力を備えていることが多いので、それらを利用して外部のプログラムと連携させるのもよいと思います。

*1:Main porcelain command と呼ばれています

*2:Interrogation commands と呼ばれています

Clojure で前景色と背景色が見やすいか検証するライブラリを書いた

aereal/clj-visible-colors · GitHub

Clojure で遊ぶためにある2つの色がじゅうぶんに見やすい輝度差と色相差を持っているかを検証するコードを書いた。

アルゴリズムはTechniques For Accessibility Evaluation And Repair Toolsから拝借した。

  • レコードを定義して実体化する
  • apply 関数
  • Java の API を呼ぶ (Math.abs)
  • マップとシーケンスを扱う

Clojure に慣れると手始めとしてなかなかいいかんじだったと思う。

よくわからないこともある。

  • 抽象化はこんなものなのか
    • 抽象化 ~= 関数として抽出する
  • インデント
    • 意味単位でインデントしたつもりだけどけっこう一行にべたっと書いてしまっている気もする
    • 文化っぽいところがあると思う

pkgutil(1) の zsh 補完関数を書いた

http://dl.dropboxusercontent.com/u/9571220/g/ca5bda41adb01a201614ee3c3cd8dedb.png

自分は zsh の補完関数をシェルのプロンプトからシームレスに読めるドキュメントだと考えているので、コマンドを使う頻度に関わらず補完関数の存在に頼っているところが大きい。

最近使う機会がいくらかあったので pkgutil(1) の補完関数を書いた。

dotfiles/.zsh.d/functions/_pkgutil at master · aereal/dotfiles · GitHub

Travis CI 上の Poltergeist で撮ったスクリーンショットを確認する方法

Capybara + Poltergeist を使った統合テストがローカルの開発環境 (OS X) では成功するが Travis CI では失敗するという現象に遭遇して困っていたら、Poltergeist の README に「とりあえずスクリーンショットを撮ってみなよ」と書いてあった。

Depending on your tests, one thing that you may need is some fonts. If you're getting errors on a CI that don't occur during development then try taking some screenshots - it may well be missing fonts throwing things off kilter. Your distro will have various font packages available to install.

jonleighton/poltergeist · GitHub

ローカルで試したらうまくいったので実際に Travis CI 上でスクリーンショットを撮影してそれを見たいが、Travis CI で標準出力を見ることはできるがそれ以上のことはできない。

認証とかなしで画像をアップロードできるサービスといえば Gyazo なのでこれを利用する。

.travis.yml に追記する:

after_script: curl -X POST http://gyazo.com/upload.cgi -F 'imagedata=@/tmp/create_new_entry.png' -F 'filename=gyazo.com'

たぶん curl の出力に line feed が含まれていないのが悪いんだろうけど、ビルドジョブの出力を眺められるページで curl の出力が見えない。
Travis CI は省略・装飾されていない生の出力をテキストファイルとしても提供しているのでこれを見てみる (例: https://s3.amazonaws.com/archive.travis-ci.org/jobs/14253241/log.txt)

すると Gyazo へ POST することに成功しているのでスクリーンショットを見てみる (例: http://gyazo.com/c33bfefa7144c9f0d35d2ee78329dd0b)