TravisCI 上で「(GNU, BSD) sed & 各 shell」の組み合わせでテストする
成果物
雰囲気こんな感じです。
github.com/gongo/tpdiff/.travis.yml
経緯
というところから始まりました。
https://github.com/gongo/tpdiff
さてテストを書くぞ!といったところで、何を重点的に見れば良いか:
この2点が特に注意すべきところと考えました。
1番に関しては「POSIX 準拠かどうか」みたいなのを ShellCheck を用いて確認はしているのですが、 やっぱり実際に動作した結果を見たいという気持ちがあります。
2番については、ユーザの使用マシンが Linux だったり OS X (macOS) だったりで sed にも違いが出てくるはずなので、ここも気をつけないといけません。
TraviCI ではこうしました
上記の注意点を踏まえ、TravisCI でテストを実行してもらうために
こんな感じにしました。
os: - linux - osx env: - SH=mksh - SH=dash - SH=bash - SH=zsh
BSD sed が (TravisCI が用意する) Ubuntu 環境に簡単に用意できれば話は早かったのですが、なかなか難しそうだったので BSD sed を標準で持つ OSX 環境を用意してもらうことで、そこを補うことにしました。
refs: The Build Environment - Travis CI
env
に定義したテスト対象のシェル選定理由なんですが、まあ特にこれといった理由はないんですけど、これぐらいカバーしてればいいかなーと。
ちょっとした問題点
TracisCI で OS X を使用すると、さすがに起動が遅くて全体的なテスト実行時間はそこそこ掛かってしまいます。
例えば https://travis-ci.org/gongo/tpdiff/builds/156956287 を見ると
> Elapsed time 21 min 12 sec > Total time 3 min 51 sec
テストそのものの実行時間は短いのですが、環境を用意するのも併せると 20分ぐらい掛かっているのがわかります。 まあいいかってことで今は気にしてないです。
まとめ
どなたか Ubuntu で GNU/BSD sed を用意できる方法知りませんか
参考
Pokemon-Emacs 〜あなたが Emacs で開いているファイルに潜んでいるポケモン〜
TL;DR
https://github.com/gongo/pokemon-emacs
経緯
最近は Pokemon Go が流行っているようで、正式サービス開始を待ち望まれているようです。
『Pokémon GO』は、位置情報を活用することにより、現実世界そのものを舞台として、ポケモンを捕まえたり、交換したり、バトルしたりするといった体験をすることのできるゲームです。 このゲームはモニターの中だけで完結せず、プレイヤーは実際に家の外に出てポケモンを探したり、他のプレイヤーと出会ったりしながら楽しむことができます。
面白そうですね。海外でも既にユーザが爆発的に増えており、スマホ片手に街をうろうろする様子などを画像や動画でも目にします。
さて、日本は夏まっさかりであり、暑い日が続いています。そんな中
「私もポケモン探しにいきたいけどまだサービス開始してないし、 そもそも外に出たくない… 」
という Emacs 使いも多いと思います。
でもよく考えてみてください。ポケモンは何も外だけに居るわけじゃないんです。 昔はゲームボーイにいました。じゃあ Emacs にも居るかもしれないですよね。
Pokemon-Emacs とは
https://github.com/gongo/pokemon-emacs
Emacs のマイナーモードの一つです。効果としては「今開いているファイル名の絶対パス(もしくはバッファ名)で一意に決まるポケモン名を表示する」だけです。
とりあえずいろいろがんばってインストールしてもらったあと
M-x pokemon-emacs-mode
を実行すると、(おそらく)ファイル名の横あたりに、下図っぽい感じでポケモン名が表示されます。
この場合は ナッシー が選ばれました。
つまり /Users/gongo/src/github.com/gongo/pokemon-emacs/README.md
にはナッシーが潜んでいる。豆知識です。
ちなみに *scratch*
にはナゾノクサが居ます。多分。
実装についてちょっとだけ
特に難しいことはしてませんが
- ファイル名、もしくはバッファ名を seed として乱数をゲット
- ポケモン一覧から↑の乱数を index としてポケモンをゲット
これだけです。
少し前に Pokemon-Go におけるポケモン出現率*1 みたいな画像を見たので、出現率に併せて「出やすいポケモン」「出にくいポケモン」みたいな実装をしてたんですが、 あの画像自体デマだったみたいなコメントもあったので、まあいいかってことでとりあえず愚直にリストから取るようにしました。
あとはポケモン一覧はとりあえず初代の 151 匹*2をチョイスしました。他のシリーズ追加すれば勝手に出てくるとおもいます
まとめ
「/path/to/foo
にピカチュウが潜んでいたぞ!!」
「ミュウが見つからねえ!!」
みたいな楽しみ方で、エディタ生活に華を添えてください。ポケモン大好き!!
Docker Image がデプロイできるようになった Heroku で、Emacs (elnode) on Alpine Linux を動かす
成果物
(7/21 追記: Docker Hub のリポジトリ名を gongo/docker-emacs
を gongo/emacs
に変更しました)
経緯
HerokuにDockerイメージをデプロイできるようになりました。 #docker https://t.co/ybbktKL9X1
— Ayumu AIZAWA (@ayumin) July 7, 2016
Container registry public beta - deploy Docker images to Heroku | Heroku Dev Center
半年ほど前に heroku-docker を使ってみた んですが、 今回の発表は更に熱くて、まさに Docker Image そのものを Heroku にもっていけるということで、早速試してみました。
作成した Docker Image
今回は Alpine Linux をベースに、Emacs や Cask に必要なライブラリ(python など)をインストールしています。
デプロイしてみる
Container Registry and Runtime | Heroku Dev Center の手順通り。
今回はあらかじめ docker build
して動作確認したりしていたので、いざデプロイする時には「Pushing an existing image」を行いました。
$ heroku apps:create gongo-docker-emacs $ docker tag gongo/emacs:example registry.heroku.com/gongo-docker-emacs/web $ docker push registry.heroku.com/gongo-docker-emacs/web
そして出来上がったのがこちら(いつか消します)
https://gongo-docker-emacs.herokuapp.com/
まとめ
お手軽感が高いです。 いくつか制限はある らしいですが、まだ Beta ですし、正式リリースされたら解決するかもしれないので、そこらへんはゆったり待ちましょう。
そんなわけでみなさん Emacs を動かしましょう!!
terraform plan の実行結果で、属性値が変更になる行に色付けする sed
TL;DR
readonly escape_ansi=$(printf '\033') sed -e '/".*" => ".*"$/!b' \ -e '/^.*: *"\(.*\)" => "\1"$/!s/.*/'"$escape_ansi"'[31m&'"$escape_ansi"'[m/'
経緯
毎晩暑い日が続く日本、AWS の各種リソース管理を Terraform で行っている皆様におかれましては、 日々の業務において terraform plan をよくお使いになられていることと存じます*1。
そんな中、例えばこのような実行結果が表示されたとします:
.. .. (message) .. + aws_security_group.app ingress.#: "" => "1" ingress.0.cidr_blocks.#: "" => "1" ingress.0.cidr_blocks.0: "" => "192.0.2.0/24" ingress.0.from_port: "" => "80" ingress.0.protocol: "" => "tcp" ingress.0.to_port: "" => "80" -/+ aws_security_group.db ingress.#: "2" => "2" ingress.0.cidr_blocks.#: "1" => "1" ingress.0.cidr_blocks.0: "198.51.100.0/24" => "198.51.100.0/24" ingress.0.from_port: "3306" => "3306" ingress.0.protocol: "6" => "tcp" ingress.0.to_port: "3306" => "3306" ingress.1.cidr_blocks.#: "" => "1" ingress.1.cidr_blocks.0: "" => "203.0.113.0/24" ingress.1.from_port: "" => "5432" ingress.1.protocol: "" => "tcp" ingress.1.to_port: "" => "5432" -/+ aws_security_group.mail ingress.#: "2" => "1" ingress.0.cidr_blocks.#: "1" => "1" ingress.0.cidr_blocks.0: "198.51.100.0/24" => "198.51.100.0/24" ingress.0.from_port: "587" => "587" ingress.0.protocol: "6" => "tcp" ingress.0.to_port: "587" => "587" ingress.1.cidr_blocks.#: "1" => "" ingress.1.cidr_blocks.0: "198.51.100.0/24" => "" ingress.1.from_port: "995" => "" ingress.1.protocol: "6" => "" ingress.1.to_port: "995" => "" Apply complete! Resources: 1 added, 2 changed, 0 destroyed.
(実行結果はてきとうです)
各セキュリティーグループのルール数が2、3個なのでまだまだ見えますが、例えばルール数が20個とかになるとかなりの行数が目に入ります。その中で どの行(属性)が変更なのかぱっと見、わかりづらい と思うわけです。思いました。
まあそんなわけで、属性値に変更のある場所がわかりやすく見えればいいな、ということで、いくつか方法はあると思いますが、今回は sed でやってみました。
sed
readonly escape_ansi=$(printf '\033') sed -e '/".*" => ".*"$/!b' \ -e '/^.*: *"\(.*\)" => "\1"$/!s/.*/'"$escape_ansi"'[31m&'"$escape_ansi"'[m/'
"xx" => "yy"
という文字列(xxとyyは任意)を 含まない 行はスキップして次に進む"xx" => "xx"
という条件に一致しない(つまり左と右の""
内の値が 同じではない )場合 に、赤で色付けする
こんな感じでできました。パターンは単純なんですが terraform plan
の実行結果に対してだけ使うのであれば充分かなと思います。
ついでにこいつをスクリプトに落とすと、雰囲気こんな感じ
#!/bin/sh readonly escape_ansi=$(printf '\033') readonly program_name=$0 if [ -p /dev/stdin ] ; then cat - else if [ ! $# -ge 1 ] ; then echo "$0: [ERROR] You must specify file." exit 1; fi if [ ! -f "$1" ] ; then echo "$0: [ERROR] \"$1\" No such file." exit 1; fi cat "$1" fi | sed -e '/".*" => ".*"$/!b' \ -e '/^.*: *"\(.*\)" => "\1"$/!s/.*/'"$escape_ansi"'[31m&'"$escape_ansi"'[m/'
てきとうに tpdiff
とか名前で保存しておいて
$ terraform plan | tpdiff
こんな感じで、冒頭の画像のように表示されます。多分。
ひとまず
あたりでは動いているようです。
まとめ
sed 難しい
おまけ
当初、sed の色付けする部分を
-e $'/^.*: *"\\(.*\\)" => "\\1"$/!s/.*/\e[31m&\e[m/'
みたいな感じでやってたんですが、 POSIX 準拠してるかってチェックしてくれる shellcheck を使うと
fi | sed -e '/".*" => ".*"$/!b' -e $'/^.*: *"\\(.*\\)" => "\\1"$/!s/.*/\e[31m&\e[m/' ^-- SC2039: In POSIX sh, $'..' is undefined.
ってな感じで怒られたので、printf 使うようにしました。
*1:手元実行なんかせず、Atlasにお任せしてる人が多いのかもしれない
「Methods & Tools Summer 2016 Magazine」に Turnip について寄稿しました
A free software development magazine
であるところの Methods & Tools に 「Turnip - Gherkin extension for RSpec」というタイトルで寄稿しました。
書いたこと
- テストやってますか。受け入れテストどうですか。
- Cucumber が人気だよね
- だけど人によっては Cucumber のこういう部分がちょっと気になる人いるよね
- そこらへんを解決しようとしてるのが Turnip です
- Turnip 導入編
- Turnip のこういう機能が、3 で挙げた点を解決してるのだー
- まとめ
目新しいことは何もなく、Turnip の誕生理由とか Cucumber との軽い比較ぐらいですね。
経緯
なんか面白いメールがきてる…
— Wataru MIYAGUNI (@gongoZ) 2016年2月10日
Methods & Tools の編集者(なのかな)の Franco さんから「Turnip の紹介記事とか書いてみませんか」みたいなメールが来ました。 正直なところ Methods & Tools の存在をこの時知りました。1999年から続いてる老舗なんですね…
ちなみに Turnip 作者である Jonas さんに「この件どうしましょうかー」って聞いたところ
jonas「書いていいよ」 gongo「お、おう」
という感じで。まあせっかくの機会だしなってことで、私がメインで、英語のおかしい点を jonas さんに見てもらう、という体制で始めました。
できた
「締切まであと2ヶ月もあるし余裕で書けるわ。なんでみんなギリギリになってバタバタするんだろうな〜」と思ってたけどつい最近(締切二日前)まで何もしてなかったし人間とは同じ業に苛まれている
— Wataru MIYAGUNI (@gongoZ) 2016年4月13日
この後 jonas さんにめっちゃくちゃ添削してもらった
終わり
今回はただの紹介記事だったのでそれほどの量でもなく、英語も難しい言い回しとかは無かったのですが、 それでもなかなか書けず時間がかかってしまいました。英語すごい。
そんなわけでよろしくお願い致します。
「1時間後に OSX をスリープする」をセットするコマンド
$ sudo pmset schedule sleep "$(date -v +'1H' +'%D %T')"
OSX 10.11 El Capitan
および OSX 10.10 Yosemite
で動作確認しています。おそらくそれ以下のバージョンでも動くやつは動くと思います。多分。
経緯
私は就寝する時に Mac mini で音楽を鳴らしながら床に就くのですが、つけっぱなしなのもあれなので、毎晩寝る直前に
- システム環境設定
- 省エネルギー
- スケジュール
を経て*1、「今は0時だから、1時にスリープするようにセットして…と…」みたいな感じで設定しています。 だいたい寝る時間は一定なのですが、夜更かしするなどしてスリープ時刻を過ぎてから寝ることもしばしばなので そういう時は上記の設定を毎回行っています。
正直めんどいのでコマンドラインでぱぱっとできないかなと調べてみました。
pmset
遅ればせながら pmset
というコマンドの存在を知りました。
スリープモードの変更(hibernateとか)等もできるらしいのですが、今回使うのは pmset schedule
です。
pmset schedule
schedule
サブコマンドでは引数として
- sleep
- wake
- poweron
- shutdown
- wakeorpoweron
これらの type と時刻を受けとります。例えば
$ sudo pmset shceudle wake "07/04/16 20:00:00"
とすれば「2016年7月4日の午後8時 にマシンをスリープから復帰させろ(wake)」になります。便利。
「1時間後」の時刻を取得する
おなじみの date
コマンドを使います。
pmset schedule
が許容する時刻のフォーマットは MM/dd/yy HH:mm:ss
なので
$ date -v +1H +'%D %T'
こうなります *2 。
最終的に
組合せると、冒頭の
$ sudo pmset schedule sleep "$(date -v +'1H' +'%D %T')"
になります。お疲れ様でした。
余談ですが
しっかり登録されてるかを確認しましょう。
$ date Wed Apr 20 09:51:24 JST 2016 $ sudo pmset schedule sleep "$(date -v +'1H' +'%D %T')" $ pmset -g sched Scheduled power events: [0] sleep at 04/20/16 10:51:27
OK
まとめ
眠い