VimConf2018 に行ってきた
行ってきました。最高でした。来年も行きたい。 スタッフの皆様お疲れ様でした。VimConfをたっぷり満喫できたと思います。
以下、感想メインでつらつらと。
LINK
VimConf2018 Official: VimConf 2018
スライドのリスト: VimConf 2018 – VimConf official blog
チケット
販売開始時刻にリマインダーセットして速攻買った。個人スポンサーも買った。
もともとmattnさんの発表が聞けるなら買わねば...と思っていたが、Bramさんが来日するとなればそりゃリマインダーセットするよね。
個人スポンサーも買ったのは、応援の意を込めて。
予習
vimconf2018.swp で、Bramさんのvim25周年時の動画があると知ったので見ておいた。
Vim 25 presentation by Bram Moolenaar on 2016 November 2 - YouTube
この動画は Vimの 25年の歴史を振り返る内容で、同時に Bramさんの歴史を振り返るものでもあって、私の中で、今まで雲の上の未確認な存在だったBramさんが、雲の上だけど存在ははっきり分かった存在に変わって、すごく良かった。
また、動画にはBramさん本人は映ってなくて、これがかえって、VimConf2018で本人に会える楽しみを増幅させてた。あの声の主に会える、みたいな。
Keynote 1
まずは mattn さんのキーノート。
vim-jp の話とNew Featureの話。
vim-jp によって日本の vimmer の知見が蓄積されていくのは本当に良い話。
New Feature の話では、VimScriptでNUL文字を扱えないことを説明するために、実際に Vim を開いてコマンドを入力して見せてもらえたのが最高だった。このライブ感がたまらない。
Keynote 2
そして Bramさんのキーノート。
最高だった。
Plugin のために今までどういうことをしてきて、これからどういうことをしようと思っているかの話。
Autocommand を追加し (Vim 4.0) Vim script を追加し (Vim 5.0) Plugin の概念を追加し (Vim 6.0) パフォーマンスに懸念が出たので autoload を追加し (Vim 7.0) 将来的にはマルチスレッドやpycのような中間言語にコンパイルするのが良いかもしれない、という感じ。
そして Plugin Manager の提案。個人的には、プラグイン管理はvim本体で持たなくても良いのではという気持ち。
あとはアンケートを取ってみたら、popup window と store properties with text の要望が多かったとのこと。properties は plugin 作ってる人たちからするとめちゃめちゃ欲しいだろうな、と聞いてて思った。
LSP は Bramさん的にはあんまりな感じだったけど、Vim が LSP に対応したらアツイ。LSP がプログラミング言語界隈でどれくらい浸透しているのかよく知らないけど、考え方は好きなので広まって欲しい。Vimが対応することでよりLSPの輪が広がると思う。
いやー。最高だった。
お昼
すきやき弁当がうまかった。
すきを見てBramさんと握手した。Vimが好きだとひたすら言った。幸せだ...。
午後
ほぼぶっ通しで発表を聞き続ける。スライド見続けるのでめちゃめちゃ目がしょぼしょぼした。目薬持ってくれば良かった。
発表の中では、 :Termdebug がインパクトあった。GDB使ったことなかったので使い方のデモとしても面白かったし、それが vim の中で完結されていたのが良かった。まさに vim を開発するための vim という感じ。
今どきのプラグインの作り方も良かった。スライドも発表も分かりやすい。Vital.vim で job/channel を Promise ぽく扱えるようになるのは良い。使ってみたい。
あとは vim の標準の補完機能もうちょっと使い込んでみたくなったなあー。<C-n> しか使ってないからなぁ。とりあえず dict は有効にした。
来年はLT出てみたい。何がいいかなぁ。
懇親会
英語で話す機会があった。これが国際カンファレンス...!
なんでVimを使ってるんだ、という話だったんだけど、私がVimを使うきっかけはEmacs使いの先輩への対抗心で、それを英語で伝えられたかというと伝えられていない。まず先輩を英語で何ていうか分からなかったのでFriendって言った時点でもう間違ってる。むずかしいなー。
というか、Vim自身に理由がないので説明しても面白くなくて、代わりにVimを使い続けている理由を話せば良かったのではと帰宅中に思った。
ちなみに相手の方は左手の小指が内側に曲がっていて、この指じゃEmacsは使えないだろ? みたいな話だった。まさかそんなパターンがあるとは...。
あと、Vim を tmux のように attach/detach したいという方もいた。それができれば tmux がいらなくなる、と。私は tmux + vim で満足してるのでそんな発想はなく、新鮮だった。これができるならログインシェルを /bin/sh
から /usr/bin/vim
にできたりするんだろうか。ちょっと違うか。
VimConf参加者のブログを読み漁ってたら、この話をしてたのってもしかして江添さんだろうか?もしそうなら、ばったり著名人と同じ輪の中で話すことがある。これが国際カンファレンス...!
家の事情があって途中で帰宅したのが残念。お酒も飲みそこねた。SAKE飲みたかった。やむなし。
また来年も参加したい。
GitHub の branch protection は force push を防いでも push は防がない
push も防ぐものだと勘違いしてた。
git push
# push できた $ git push Enumerating objects: 7, done. Counting objects: 100% (7/7), done. Delta compression using up to 4 threads Compressing objects: 100% (3/3), done. Writing objects: 100% (4/4), 407 bytes | 407.00 KiB/s, done. Total 4 (delta 2), reused 0 (delta 0) remote: Resolving deltas: 100% (2/2), completed with 1 local object. To github.com:yasuhiroki/iypymtiycaa 98b74d8..b6eb250 master -> master
git push -f
# force push はできない $ git push -f Enumerating objects: 4, done. Counting objects: 100% (4/4), done. Delta compression using up to 4 threads Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 266 bytes | 266.00 KiB/s, done. Total 3 (delta 1), reused 0 (delta 0) remote: Resolving deltas: 100% (1/1), completed with 1 local object. remote: error: GH006: Protected branch update failed for refs/heads/master. remote: error: Cannot force-push to a protected branch To github.com:yasuhiroki/iypymtiycaa ! [remote rejected] master -> master (protected branch hook declined) error: failed to push some refs to 'git@github.com:yasuhiroki/iypymtiycaa'
slackcat で iconemoji を設定できるようにした
以前、 slackcat で Slack に分報を流すようにした。
slackcat
だと投稿者のアイコンを変更できなかったので stdbuf
を使って prefix を挿入していたが、よく考えたら slackcat
を自分で改造して iconemoji
を受け付けられるようにすれば良かった。
プルリクも出した。
ただこの実装方法だと未対応の他のオプションにも対応したくなった時、関数の引数が延々と増えてしまう未来が見える。
ひとまず、私の slack
コマンドは次のようになった。
-i
オプションで投稿者のアイコンを絵文字で指定できる。
#!/bin/bash set -e which slackcat >/dev/null || { echo "required slackcat"; exit 1; } if [ $# -gt 0 ]; then echo "${*}" | slackcat -i ":yasuhiroki:" -c "${MY_SLACK_CHANNEL:-times-yasuhiroki}" -u "${MY_SLACK_USERNAME:-yasuhiroki}" --stream else cat | slackcat -i ":yasuhiroki:" -c "${MY_SLACK_CHANNEL:-times-yasuhiroki}" -u "${MY_SLACK_USERNAME:-yasuhiroki}" --stream fi
vim上で git rebase -i が動かない
解決はしたが、原因は不明。
解決方法
sequence.editor
を設定する。 core.editor
ではだめ。
$ git config --global sequence.editor $(which vim)
環境
- MacBook Pro
- High SIerra
- iTerm2
- zsh 5.5.1 (x86_64-apple-darwin17.5.0)
- MacVim
調査
vim 上からコマンド打って rebase できなくなった。
$ vim Created autostash: dcc6d6b HEAD is now at fde30be fixup! fea /usr/local/Cellar/git/2.18.0/libexec/git-core/git-rebase--interactive: line 277: /Users/a10lab-yasuhiroki/go/src/github.com/yasuhiroki/slackcat/.git/rebase-merge/git-rebase-todo: Permission denied Applied autostash. Could not execute editor
.git/rebase-merge/
ディレクトリは存在しない。
$ ls .git COMMIT_EDITMSG ORIG_HEAD description index logs/ packed-refs tags HEAD config hooks/ info/ objects/ refs/
ディレクトリを作ってみると、zsh の VCS_INFO が怒る。
$ mkdir .git/rebase-merge VCS_INFO_git_getbranch:25: no such file or directory: .git/rebase-merge/head-name
とりあえず rebase してみるも失敗。
$ vim It seems that there is already a rebase-merge directory, and I wonder if you are in the middle of another rebase. If that is the case, please try git rebase (--continue | --abort | --skip) If that is not the case, please rm -fr "/Users/a10lab-yasuhiroki/go/src/github.com/yasuhiroki/slackcat/.git/rebase-merge" and run me again. I am stopping in case you still have something valuable there.
/usr/local/Cellar/git/2.18.0/libexec/git-core/git-rebase--interactive
の先頭で set -xv
してデバッグログ出す。
...前略... ++ /Users/a10lab-yasuhiroki/go/src/github.com/yasuhiroki/slackcat/.git/rebase-merge/git-rebase-todo /usr/local/Cellar/git/2.18.0/libexec/git-core/git-rebase--interactive: line 278: /Users/a10lab-yasuhiroki/go/src/github.com/yasuhiroki/slackcat/.git/rebase-merge/git-rebase-todo: Permission denied gettext "Could not execute editor" ++ gettext 'Could not execute editor' ++ printf %s 'Could not execute editor' + die_abort 'Could not execute editor' + apply_autostash + test -f /Users/a10lab-yasuhiroki/go/src/github.com/yasuhiroki/slackcat/.git/rebase-merge/autostash + rm -rf /Users/a10lab-yasuhiroki/go/src/github.com/yasuhiroki/slackcat/.git/rebase-merge + die 'Could not execute editor' + die_with_status 1 'Could not execute editor' + status=1 + shift + printf '%s\n' 'Could not execute editor' Could not execute editor + exit 1 シェルが値を返しました 1 続けるにはENTERを押すかコマンドを入力してください zsh: suspended vim
ログをあちこちねじ込んで print デバッグしてくと git var GIT_EDITOR
の戻り値がおかしかった。
手元でやると、
$ git var GIT_EDITOR /usr/local/bin/vim
vim上だと、
:!git var GIT_EDITOR →何もなし
なんでだろう。git config で core.editor は設定済みのはずだが...。
vim上で !git config -l
してもちゃんと定義されてる。
!git var -l
すると、 GIT_EDITOR が空になってる。
腑に落ちないけど、 sequence.editor
を設定すればそっちから読み込んでくれそうなので設定してみる。
git_sequence_editor () { if test -z "$GIT_SEQUENCE_EDITOR" then GIT_SEQUENCE_EDITOR="$(git config sequence.editor)" if [ -z "$GIT_SEQUENCE_EDITOR" ] then GIT_SEQUENCE_EDITOR="$(git var GIT_EDITOR)" || return $? fi fi eval "$GIT_SEQUENCE_EDITOR" '"$@"' }
$ git config --global sequence.editor $(which vim) $ git config --global -l | grep editor core.editor=/usr/local/bin/vim sequence.editor=/usr/local/bin/vim
無事動くようになった。
cookpad.apk #1 に行ってきた
2018/08/21 に開催された cookpad.apk #1 に行ってきました。 もともと社内向けのイベントとして企画していたけど、別に外部に開いても良くない? となって開催が決定したとのこと。
楽しかったし美味しかったです。
楽しかったー!
— yasuhiroki (@duck_yasuhiroki) 2018年8月21日
ご飯美味しいし発表も種類が多くて面白いし懇親会でリリース自動化について詳しく聞けたので良かった。
アプリの公開範囲は、うちは規模がまだそこまで大きくないし週に一回リリースを目指しているのでしばらく100%のままで良さそうだなぁ。
#cookpad_apk
以下、メモ。
ReactNative for Android について
新規事業にReactNativeを採用してどうだったか、という話。
ReactNativeが向いているのはどんな環境か、採用してみたメリットはどの辺か、辛いポイントはどこか、の紹介。
その場でアプリをインストールして使ってみたけど、言われなきゃ ReactNative とは思わなかったかもしれない。言われてみれば何となくWebっぽいような気もするけど気のせいな気もする。
私はどっちかというとWeb側の人間なので、JavaScript(and TypeScript) に詳しくて、Android/iOSの有識者がいて、デザイナーも一緒に実装できる状態なら、ReactNative を選択するのはアリだと思う。ReactNative のマルチプラットフォーム対応の恩恵をフルに受けられる状況ならなおさら。
ただ、もしAndroid/iOSを両方に精通しているエンジニアが揃っているなら、ネイティブアプリで作った方が良いと思うし、そっちの方が理想的だとも思う。
クックパッドアプリのマルチモジュール化への取り組み
モノリシックな状態では、新規機能が使えないしビルドが遅すぎる...モジュール化だ! ということでマルチモジュール化への取り組みについてのお話。
マルチモジュールを Feature単位で進めていった、というのが印象に残った。
たしか、Feature単位で開発チームが分かれているんだったっけ...? それなら合理的な気がする。
ML Kitでカスタムモデルを使うまで
タイトル通り。
やってみた系の発表は自分でもやってみないと面白さが半減なので、(たぶん)口頭で紹介されてた firebase のサンプルを clone して試してみている。
https://t.co/pNzE3IALZJ
— yasuhiroki (@duck_yasuhiroki) 2018年8月21日
#cookpad_apk
まだ firebase のプロジェクトを作ったままなのでやらねば。
AndroidXとAOSP
Support Library 改め Android X と、そのソースコードを読むために AOSP にアクセスしてみよう、あわよくばパッチを送ろう、というお話。
AOSPの見方が説明されていて、レビューの様子とかcommitのルールとかそうなってたんだなーと興味深かった。
パッチは @NonNull
とか狙い目とのこと。
AOSPのソースコードは容量食うから削除したんだよな...。ノートPCを新しくする時はケチらず容量の多いタイプにしたい。
Google Playアルファリリースを自動化した話
Google Play alpha release の自動化の話。面白い。
もともとのリリースは半自動化されていて、最後に apk を upload してリリースするところが手動だったのだけど、それも自動化したとのこと。私もそれ取り組もうと思っていたところだったので、一つの事例としてすごく参考になった。
自動リリースする際は、バージョン名をどうするかが課題だと思っていたので、懇親会で詳しくお話が聞けたのも良かった。年・週・リリース番号、みたいな機械的に取れる値でインクリメントしていく案は良さそう。
人がスケジュールを管理するのではなくてスケジュールによって人が動くようにしたい、というのはすごく共感する。
もちろん無茶なスケジュールを押し付けられて苦しむ、という意味ではなくて、定期的にリリースできる環境を作っていくという意味なので、私も目指したいなと思っている。
Google Play alpha 機能を選んだ理由 (TestLab によるモンキーテスト) や 段階リリースの良し悪しについてもお話できたので有り難かった。
FireTV ことはじめ
FireTV全く知らないので新鮮だった。
Google開発者サービス入ってないから Firebase SDK 入れられないとは...おおお...。
Introduce Gradle Kotlin DSL
Gradle Kotlin DSL の紹介。そんなのあったんスね...。
私はRubyistなのでどっちかというとGroovyの方が扱いやすいし好きなんだけど、Kotlinで書きたい気持ちも分かるようなそうでもないような。
実際、Kotlin で書くメリットもさほど無いようなので、これはスルーしてもいいかなぁ...と思った。
余談
お酒強くないくせにハイボール飲んだせいか、翌日から体調崩したので反省。
slackに流す分報にprefixを付けたい
分報とは
日報はその日の作業や悩みをその日の最後に書いて出すことになる。作業中の課題や考えていることが、日単位で共有されるため、他の人が目にする時には、すでにその課題は解決済みな場合がある。情報共有の時間差がどうしても発生してしまう。
そこで、ツイッターのようにその時その時の作業内容や悩みをアウトプットする取り組みとして、分報というものが活用できる。
分報の考え方や進め方は次の記事が詳しい。
私の分報の仕組み
私は Terminal で zsh で vim な開発環境なので、つぶやくなら Terminal 上で行いたい。
自社ではSlackを使っているので、TerminalからSlackに分報を送信したい。
そこで下の記事を参考に、 slackcat を活用することにした。
slackcat の課題
slackcat は Slack App の Token を使うので、私のアカウントで発言したことにはならず、Token を発行した Slack App が発言したことになってしまう。
妥協策
せめて、もう少し自分の発言っぽさを出したいので、カスタム emoji を追加したい。
下のような感じ。
分報を送るためのスクリプト
毎回 emoji を入力するのは面倒くさい。
また、いちいち slackcat
とコマンドを入力するのも面倒くさい。
そこで、一度実行したら常に入力待ちになって、文字列を入力して改行する度に、カスタム emoji を先頭に付与して Slackに送信するスクリプトを作った。
#!/bin/bash set -e which slackcat >/dev/null || { echo "required slackcat"; exit 1; } if [ $# -gt 0 ]; then echo "${*}" | slackcat -c "${MY_SLACK_CHANNEL:-times-yasuhiroki}" -u "${MY_SLACK_USERNAME:-yasuhiroki}" --stream else cat | gstdbuf -oL gsed 's/^/:yasuhiroki: /g' | slackcat -c "${MY_SLACK_CHANNEL:-times-yasuhiroki}" -u "${MY_SLACK_USERNAME:-yasuhiroki}" --stream fi
stdbuf
で入力を行ごとにsedに渡して文頭にカスタムをemojiを追加している。
mac なので gstdbuf
と gsed
となる。 BSD版だと sed -l
としないと slackcat
に文字列を渡してくれない。ただ、私の環境だと日本語を入力するとエラーになるので、GNU版が必須。なんでだろ。
実装当初、BSD sed で実装していてうまくいかず悩んでいたら @eban さんが Ubuntu だとできたと教えてくださり、GNU版じゃないとダメなのだと気付いた。
ElasticBeanstalkのPlatform Versionを更新したらPaperclipでエラーが出た
TL;DR
- Ruby on Rails 4.10, Ruby 2.4 な環境で
- AWS ElasticBeanstalk Platform の version を Amazon Linux 2016.03 v2.1.0 から
2017.09 v2.6.5
に更新した - PaperClip 4.7 でエラーが出るようになったので調べたら
ImageMagick
のpolicy.xml
でHTTPS
から直接画像を指定できないようになっていたためだった- なので、S3からダウンロードしてファイルパスを Paperclip に渡すようにした
経緯
もともと、Paperclip を使って S3 上の画像ファイルを使ってゴニョゴニョしていた。S3上のファイルは https の Endpoint を指定していた。
で、Ruby バージョンを更新することにしたので、それならついでに AWS ElasticBeanstalk Platform も更新するかー、としてみた。
すると、Paperclip を使った処理で Paperclip::Errors::NotIdentifiedByImageMagickError
が発生するようになった。
原因特定と対策
Paperclip::Errors::NotIdentifiedByImageMagickError
だけだと原因が分からないのだが、すでに以前、 ImageMagick の policy.xml が更新されたことで、rmagick
が動かなくなる現象に出会ったことがあった。こちらも rmagick
で convert
に S3 の Endpoint を渡すようにしていたためで、この時は画像をダウンロードしてから使うことにした。
同じ原因だろう、とログを差し込んで、 Paperclip で https なEndpointを指定していることを確認して原因の特定は完了。
ImageMagick の policy.xml
2016年に公開された ImageMagick の脆弱性対策のため policy.xml で制御する、という対策が取られた。
脆弱性の内容自体は次の記事が分かりやすい。
ImageMagickの脆弱性(CVE-2016-3714他)についてまとめてみた - piyolog
ImageMagickの脆弱性(ImageTragick) - てきとうなメモ
Amazon Linux もこの対策を採用している。
https://alas.aws.amazon.com/ALAS-2016-699.html
Note: This update contains an updated /etc/ImageMagick/policy.xml file that disables the EPHEMERAL, HTTPS, HTTP, URL, FTP, MVG, MSL, TEXT, and LABEL coders. If you experience any problems after the update, it may be necessary to manually adjust the policy.xml file to match your requirements. Please take additional precautions to ensure that your applications using the ImageMagick library do not process malicious or untrusted files before doing so.
実際に EC2 上の policy.xml を見てみると HTTPS は制限されている。
<policymap> <policy domain="coder" rights="none" pattern="EPHEMERAL" /> <policy domain="coder" rights="none" pattern="HTTPS" /> <policy domain="coder" rights="none" pattern="HTTP" /> <policy domain="coder" rights="none" pattern="URL" /> <policy domain="coder" rights="none" pattern="FTP" /> <policy domain="coder" rights="none" pattern="MVG" /> <policy domain="coder" rights="none" pattern="MSL" /> <policy domain="coder" rights="none" pattern="TEXT" /> <policy domain="coder" rights="none" pattern="LABEL" /> <policy domain="path" rights="none" pattern="@*" /> </policymap>
該当行をコメントアウトすると、今までどおりの処理がされた。
<policymap> <policy domain="coder" rights="none" pattern="EPHEMERAL" /> <!--<policy domain="coder" rights="none" pattern="HTTPS" />--> <policy domain="coder" rights="none" pattern="HTTP" /> <policy domain="coder" rights="none" pattern="URL" /> <policy domain="coder" rights="none" pattern="FTP" /> <policy domain="coder" rights="none" pattern="MVG" /> <policy domain="coder" rights="none" pattern="MSL" /> <policy domain="coder" rights="none" pattern="TEXT" /> <policy domain="coder" rights="none" pattern="LABEL" /> <policy domain="path" rights="none" pattern="@*" /> </policymap>
HTTPSの制御をコメントアウトして良いのか?
HTTPS で指定したファイルを使えるようにする、というのは果たして良いのだろうか?
せっかく塞いである穴を自ら開けることになるので、せめてホワイトリスト指定ができれば良い。
ImageMagick 6.9.7-7 では、そのような機能が入ったらしい。
Behavior of policy changed from 6.9.7-7 · Issue #377 · ImageMagick/ImageMagick · GitHub
ImageMagick 6.9.7-7 から policy の挙動が変わりました - awm-Tech
ただし、URLをホワイトリスト指定する方法は調べた感じなさそう。ソースコードを追いかけたわけではないので、実装上できないのかは分からない。
また、私が使っている AmazonLinux 上の ImageMagick は 6.7.8-9
なので、そもそもホワイトリスト指定は使えない。yum update
すれば良い話だけど。
やはりセキュリティの穴を自ら開けるのは嫌なので別の方法を検討する。
Paperclip コミュニティではどのように対策を?
Paperclipコミュニティでは、どのような解決方法を検討しているのか調べてみた。
- cve-2016-3714 "magic byte" validation · Issue #2190 · thoughtbot/paperclip · GitHub
- ImageMagick の脆弱性対策に対して、どう対応するか検討している
- Paperclip::Geometry.from_file not working with new ImageMagick version for urls that have https · Issue #2198 · thoughtbot/paperclip · GitHub
- https を http にすれば解決した、というコメントだが、それもまた穴あけである
結局ダウンロードしてからPaperclipに渡すことにした
他の手もあるとは思うが、仕方がないので PaperClip の Wrapper を作ることにした。 モンキーパッチは避ける主義なので、Wrapperクラスをべた書き。
Dir.mktmpdir do |tmpdir| image_file = File.basename(URI.parse(image_url).path) download_path = Pathname(dir).join(image_file) File.open(download_path, "wb") do |output| OpenURI.open_uri(image_url) do |data| output.write(data.read) end end Paperclip::Geometry.from_file(download_path) end