Thanks Driven Life

日々是感謝

Turnip 2.0.0 リリースされました

Release Version 2.0.0 · jnicklas/turnip

メジャーバージョンアップとなる 2.0.0 ですが、機能追加されたとか機能削除されたとかではなく

RSpec のサポートバージョンポリシー策定

の一環です。

経緯

github.com

以前は RSpec 2.14.x 系から RSpec 3.x の最新まで全てをサポートする体制でした。 定義されていなかった というのが正確なところですが。

ともかく近年の RSpec の躍進ぶりを追い続けるため、全てのバージョンをサポートしていくのは現状メンテナ一人の状態では無理と判断し、上記のような提案をさせていただきました。

提案の結果

反応としては「まあいいんじゃないのー」といった肯定的なものだったので、安心してばっさりいきました。つまり

  • 最新のバージョン、およびその一つ前のバージョンだけをサポートする
  • それ以前のバージョンはサポート対象外(動くかもしれない)

という形にしました。

最近の RSpec 3.x のリリースは 2,3 ヶ月に1回となっており、まあ約半年ぐらいあれば Turnip ユーザも手元の RSpec のバージョン上げられるだろ、ぐらいの気持ちで進めています。

そんなわけで

Turnip をこれからもよろしくお願い致します。

heroku-docker を使って Emacs & Cask がインストールされた Heroku 環境 (Slug) を作成する Docker イメージ作った

成果物

経緯

Emacs を使っている人は、日頃から

「あー Emacs でも HTTP サーバ立てられるんだし Heroku で起動してーなー」

と考えていると思います。

しかし Emacs ぐらいになると Heroku が標準サポートしている環境には含まれておらず、
いわゆるサードパーティ製 buildpack の導入が必要となります。

Emacs の buildpack もあった*1 のですが

  1. 試しに使ってみたら、なんかエラー出た*2
  2. まあ直せばいいかーと思う
  3. buildpack の修正検証ってものすごいめんどくさいイメージ(ちゃんと調べてない)
  4. モチベーション消えた

みたいな人生を送っていました。

Heroku + Docker

そんなある日、もう一つの可能性である Docker を思い出しました。

Build and Deploy with Docker | Heroku Dev Center

リリースされた当時は

「好きな Docker イメージを Heroku で動かせるのかよすごい!!」

みたいな反応が多数(私も)だったのですが、実際には

  1. 「Heroku と同等の環境を Docker イメージとして配布する」
  2. 「その中で動作確認しろよ」
  3. 「(制限はあるが)そのままデプロイできるフローも作ったぜ」

的なものでした。

デプロイ方法もあるし、ドカドカデバックできるので、これで行こうと決めました。

そんなわけで作りました。

https://github.com/gongo/emacs-heroku-docker

概要は README を読んでもらうとして、つまり必要なことは

  1. 普段通り Emacs Lisp で Web アプリケーションを書く
  2. Cask ファイルを作成し、依存パッケージを書く
  3. Heroku ではお馴染の Procfile に、起動コマンドを書く
  4. コンテナビルドしたり Heroku へリリースするためのファイルを作成
    • docker build したあとのファイルを転送するため、リリースにも使われる
  5. heroku docker:release

みたいな感じです。

試しに作ったのがこちら

https://emacs-heroku-docker-sample.herokuapp.com/

いつか消します

補足

heroku-docker でデプロイする時に注意するところ、備忘録も兼ねて

1. /app 以下のファイルしか転送されない

heroku docker:release で Heroku にデプロイされるファイルは、awesome氏のポストにもある通り

/app以下をtgzで固めてcpコマンドでそれを取り出している.なのでDockerfileに独自の変更を加えるときは注意が必要で/app以下に依存をちゃんと含めるように書く必要がある.

Herokuの'docker:release'の動き | SOTA

という制限(仕様)となっています。

つまり、Dockerfile で素直に apt-get install emacs とかやっても、Heroku 側には Emacs が入っていない slug が転送されてしまう、ということです。 なので今回はソースコードからコンパイルし、 /app/emacs 以下にインストールすることで依存を /app 以下に閉じ込めました。Cask についても同様。

2. 環境変数 export は /app/.profile.d/* 以下に書いておこう

上記のとおり heroku docker:release で転送されるのは、コンテナ内の /app 以下だけ。つまり

ENV PATH /app/emacs/bin:$PATH

みたいなのを書いていても、docker run した環境では使えますが Heroku 上には反映されません

ではどうするか。/app/.profile.d/ 以下に、環境変数設定するファイルを書いておきます。

.profile.d Scripts | Heroku Dev Center

$HOME/.profile.d/ 以下に置いたやつは Dyno 起動時に読まれるので、必要な処理はここに書いておきましょう。

ちなみに heroku-ruby では Dockerfile の ENTRYPOINT として init.sh というものを仕込んでいます。

#!/bin/bash

for SCRIPT in /app/.profile.d/*;
  do source $SCRIPT;
done

exec "$@"

こうすることで

Procfile:

web: cask exec emacs -Q --batch -l app.el

docker run 時:

$ docker run `コンテナ名` cask exec emacs -Q --batch -l app.el

つまり

  • Procfile に書くコマンドと docker run のコマンドを揃えることができる
  • どちらもコンテナ起動時に /app/.profile.d/* 以下を読んでくれる

という感じで、より Heroku の環境に近づけることができる、というわけです。

まとめ

heroku-docker を使うことで、buildpack よりも破壊再構築のサイクルを早く回せると思います。 どんどん作って最高のオレオレ cedar:14 にしよう!!

参考

*1:https://github.com/technomancy/heroku-buildpack-emacs

*2:libgpmが無いとかなんとか

json-reformat.el v0.0.4 リリースしました

Release 0.0.4 · gongo/json-reformat · GitHub

修正内容

v0.0.3 までは、空のハッシュに対して json-reformat-region とかを仕掛けると、
下記のように null になってしまう という 仕様 でした。

{"foo": {}}

// ↓↓↓

{
  "foo": null
}

v0.0.4 からは、ちゃんと空のハッシュのまま整形できるようになりました。

{"foo": {}}

// ↓↓↓

{
    "foo": {
    }
}

空のハッシュであれば "foo": { } という感じで改行入らない方がいいかもしれませんね。
いつか考えます。

今回の内容を仕様としていた理由

json-reformat.el では、JSON テキストのパースを (json-read) で行っています。

;; $ cat foo.json
;; {
;;     "foo": 3,
;;     "bar": "pizza"
;; }

(dolist (type '(plist alist hash-table))
  (let ((json-object-type type))
    (with-temp-buffer
      (insert-file-contents "foo.json")
      (json-read))))

;; => (:bar "pizza" :foo 3)
;; => ((bar . "pizza") (foo . 3))
;; => #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8 data ("foo" 3 "bar" "pizza" ...))

このように alist plist hash-table の中の好きな形でパースした結果を受け取れます。

v0.0.3 までは plist で実装していたのですが、この時問題となるのが、前述の 空のハッシュ です。

;; $ cat foo.json
;; {
;;     "foo": {},
;;     "bar": null
;; }

(let ((json-object-type 'plist))
  (with-temp-buffer
    (insert-file-contents "foo.json")
    (json-read)))

;; => (:bar nil :foo nil)

このように 空のハッシュも null もパースすると nil になってしまう ということで、
受け取った側としては「どっちかわからんから {} に直すこともできねーなー」となって
最終的に「これは仕様ですわー」みたいな感じにしていました。

光明

そんなことを Tweet してみたところ、 @ さんから以下の reply をいただきました。

なるほど hash-table と思って実際に試してみたところ

;; $ cat foo.json
;; {
;;     "foo": {}
;; }

;; $ cat bar.json
;; {
;;     "bar": null
;; }

(let ((json-object-type 'hash-table))
  (dolist (filename '("foo.json" "bar.json"))
    (with-temp-buffer
      (insert-file-contents filename)
      (json-read))))

;; => #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8 data ("foo" #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8 data ( ...)) ...))
;; => #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8 data ("bar" nil ...))

ちゃんと nil なのか空ハッシュなのか判別できる!!

というわけで、今までの仕様はバグということにできて修正することができました。 @ さんありがとうございました!!

P.S.

Emacs 24.4 から標準実装されている M-x json-pretty-print も似たような問題が起きていますが
M-x json-pretty-print または M-x json-pretty-print-buffer 実行前に

(setq json-object-type 'hash-table)

とかしておくと、空ハッシュが壊れることはありません。

PHP バージョン毎の php.ini の差分を確認できるサービス phpini-diff

軽く作りました。

http://phpini-diff.herokuapp.com/

f:id:gongoZ:20150924162526g:plain

概要

RailsDiff みたいなやつです。

作成経緯

PHP のバージョン上げる時に php.ini の違いも一応調べないと*1。でも PHPソースコード落としてきて diff するのめんどいし。今なら GitHub にある PHP 本体のリポジトリ でタグ差分で違いみれるけどいちいちバージョン探して指定してーってめんどくさいな」

みたいなことから

Rails だと railsdiff があるよなー」

みたいな感じで php.ini 版があると多少便利になるかな、といった感じです。

ソースコード

github.com

備忘録も兼ねて簡単に内容を

PHP のバージョンは 4.0.0 以上 & (正式版 or RC 版) を対象

  • GitHub でタグ付けされてる分だけ
  • 正式版以外だと alpha とか beta とかあるけど、めんどくさいので RC だけ

php.ini の種類については

プロダクション用(所謂 php.ini-production)を比較対象としています。php.ini-development とかは除外しています。 ちなみに PHP 5.3 未満は php.ini-recommended が production 用っぽかったので、それを採用しています。

各バージョンの php.ini の収集方法

適当にスクリプト書いて 対処しました。

とりあえず JavaScript (Node.js) で

  • フロントは vue.js + webpack で作成
  • サーバ側は express
    • そこは PHP だろみたいなところもあったんですが、 PHP xdiff を heroku で使うのめんどそう
    • いい感じで差分ブロック分けてくれるやつが node にあった flitbit/diff ので、もう統一しようかなと

まとめ

ini ファイル、拡張ライブラリまで手を出そうと思ったけどめんどくさいのでやめました。 そこらへんはファイルサイズもそんなに大きくないし、ひとまずコアな php.ini の差分だけ簡単に見れたら良しとしました。

てきとうにご利用ください

*1:例えば 5.3 → 5.4 みたいな差分は http://php.net/manual/ja/migration54.ini.php とかでも確認できます

YAPC::Asia Tokyo 2015 参加ついでに会社(前)訪問したり飯食ったりしてた

YAPC::Asia Tokyo 2015 参加してきました - Thanks Driven Life

合間のお話

食事

マグロカツカレー。マグロカツ美味しかった

東印度カレー商会 築地場外店 - 築地市場/カレーライス [食べログ]


親子丼

なか卯 勝どき一丁目店 - 勝どき/牛丼 [食べログ]




朝シースー最高!!

店舗詳細 | 東京の寿司 マグロが自慢【すしざんまい】つきじ喜代村


朝ぎゅうどん

松屋 勝どき店(晴海/丼もの) - ぐるなび


ビッグサイト近くで沖縄勢と飲んだ居酒屋の茶漬。店忘れた


最高の肉

the 肉丼の店ホームページ | 高田馬場・晴海・蒲田・赤坂でステーキ丼とローストビーフ丼

会社(の前の写真を撮るための)訪問

GitHub ジャパン!!!

伝説のヒカリエのオフィス受け付け(11F)まで行って写真だけ撮ってすぐ降りました

YAPC::Asia 2015 Hackathon 会場だったというビルいって写真。
若干遠くから撮ったっぽい理由は、警備員いて怖かったからです。

まとめ

飯最高!!

YAPC::Asia Tokyo 2015 参加してきました

yapcasia.org

f:id:gongoZ:20150822233914j:plain

最高!!!

経緯

YAPC::Asia 、一昔前は名前のとおり Perl Conference ということもあり Perl まったく触っていない自分とは遠い存在でしたが、 ここ最近の「いいからテクを集中させて祭だ!!」感が良さそうだったので参加してみました。

初参加、そして最後です。

8/20 (木) 前夜祭

8/21 (金) 一日目

instagram.com

朝寿司最高

8/22 (土) 二日目

御礼

  • WiFi CONBU さんありがとうございました!!ほぼほぼ快適に使えておりました!
  • 無限コーヒーありがとうございました!! Emacs コップ最高でした!
  • 同時通訳すごかった……

    togetter.com

牧さんはじめ YAPC::Asia Tokyo スタッフの皆様、本当にありがとうございました!!!

YAPC::Asia Tokyo 2015 で、PHP の register_globals に関する LT してきました

参加しました記事はまた別で書きます。書きました → YAPC::Asia Tokyo 2015 参加してきました - Thanks Driven Life

発表直前

発表しました。

スライド

69ページ辺りで銅鑼が鳴り、LT 力不足が露見しました。最後まで行けなかったのは心残りですが、笑ってくれれば僕としては満足です。 残りのスライドで、書かれてること以外に言うことはなかったので、あとはスライドで補完していただければと思います。

ドキュメントに載ってない仕様について

ネタっぽく喋りましたが、当時この現象と直面した時は

  • php.net に載ってない
  • ググっても出てこない(みんな extract($_FILES) で余裕かましてた)

という状況で、仕方なく PHP 5.3.29 のソースコードを読んで*1、どうにか確信に近いものを手に入れました。

「載ってないなら自分から php.net にコミットするべきか?」とも思ったのですが、 今更 PHP 5.3 以下向けのドキュメント更新してもな?という気持ちがありました。単にめんどくさかったとも言います。

会場でも挙手をお願いした時、何人か PHP 5.3 以下を使用中という方々も居らっしゃったので 少しでもこのスライドがみなさまの register_globals 撲滅の助けになればいいなと思います。

merciful_polluter について

PHP 5.4 以上でも register_globals を再現するライブラリ MercifulPolluter - Qiita

作成した理由としては以下のとおりです。

  • 面白ろ4割
  • packagist でライブラリUPしてみたかった3割
  • 高まって欲しくない実用性3割

本体のコード200行、テストコード含めても500行ぐらいの軽いライブラリなので、 もし怪しいところがあっても、そこそこ手を加えやすくなってると思います。

発表について

  • みんな「採択されたトークは当日発表します!」という状況できっちり仕上げてきててすごい…
  • 国際会議場の壇上すごい緊張しました(会場キャパは1000人なので、おそらく950人ぐらいはいた)

f:id:gongoZ:20150822075643g:plain

f:id:gongoZ:20150822075933j:plain

まとめ

本セッショントークでは落選してしまいましたが、LT 採用されてある意味本セッションよりも面白い壇上(通常であればキーノートレベルしかできないところ)に立つことができたので 結果的に良かったかなと思います。みなさん PHP がんばりましょう!!