HappyGoLucky

Web系サーバーサイド寄りの自動化大好きエンジニアの徒然なるブログ

slackcat で iconemoji を設定できるようにした

以前、 slackcat で Slack に分報を流すようにした。

yasuhiroki.hatenablog.com

slackcat だと投稿者のアイコンを変更できなかったので stdbuf を使って prefix を挿入していたが、よく考えたら slackcat を自分で改造して iconemoji を受け付けられるようにすれば良かった。
プルリクも出した。

github.com

ただこの実装方法だと未対応の他のオプションにも対応したくなった時、関数の引数が延々と増えてしまう未来が見える。

ひとまず、私の 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
  • iTerm2
  • zsh 5.5.1 (x86_64-apple-darwin17.5.0)
  • MacVim
    • VIM - Vi IMproved 8.1 (2018 May 18, compiled Aug 31 2018 11:39:09)
    • macOS
    • 適用済パッチ: 1-332

調査

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/

ディレクトリを作ってみると、zshVCS_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 してデバッグログ出す。

f:id:yasuhiroki:20180831114918p:plain

...前略...
++ /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 してもちゃんと定義されてる。

f:id:yasuhiroki:20180831115008p:plain

!git var -l すると、 GIT_EDITOR が空になってる。

f:id:yasuhiroki:20180831115014p:plain

腑に落ちないけど、 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 に行ってきました。 もともと社内向けのイベントとして企画していたけど、別に外部に開いても良くない? となって開催が決定したとのこと。

楽しかったし美味しかったです。

以下、メモ。

ReactNative for Android について

speakerdeck.com

新規事業にReactNativeを採用してどうだったか、という話。

ReactNativeが向いているのはどんな環境か、採用してみたメリットはどの辺か、辛いポイントはどこか、の紹介。

その場でアプリをインストールして使ってみたけど、言われなきゃ ReactNative とは思わなかったかもしれない。言われてみれば何となくWebっぽいような気もするけど気のせいな気もする。

私はどっちかというとWeb側の人間なので、JavaScript(and TypeScript) に詳しくて、Android/iOS有識者がいて、デザイナーも一緒に実装できる状態なら、ReactNative を選択するのはアリだと思う。ReactNative のマルチプラットフォーム対応の恩恵をフルに受けられる状況ならなおさら。
ただ、もしAndroid/iOSを両方に精通しているエンジニアが揃っているなら、ネイティブアプリで作った方が良いと思うし、そっちの方が理想的だとも思う。

クックパッドアプリのマルチモジュール化への取り組み

speakerdeck.com

モノリシックな状態では、新規機能が使えないしビルドが遅すぎる...モジュール化だ! ということでマルチモジュール化への取り組みについてのお話。
マルチモジュールを Feature単位で進めていった、というのが印象に残った。
たしか、Feature単位で開発チームが分かれているんだったっけ...? それなら合理的な気がする。

ML Kitでカスタムモデルを使うまで

speakerdeck.com

タイトル通り。
やってみた系の発表は自分でもやってみないと面白さが半減なので、(たぶん)口頭で紹介されてた firebase のサンプルを clone して試してみている。

まだ firebase のプロジェクトを作ったままなのでやらねば。

AndroidXとAOSP

speakerdeck.com

Support Library 改め Android X と、そのソースコードを読むために AOSP にアクセスしてみよう、あわよくばパッチを送ろう、というお話。

AOSPの見方が説明されていて、レビューの様子とかcommitのルールとかそうなってたんだなーと興味深かった。
パッチは @NonNull とか狙い目とのこと。

AOSPのソースコードは容量食うから削除したんだよな...。ノートPCを新しくする時はケチらず容量の多いタイプにしたい。

Google Playアルファリリースを自動化した話

speakerdeck.com

Google Play alpha release の自動化の話。面白い。
もともとのリリースは半自動化されていて、最後に apk を upload してリリースするところが手動だったのだけど、それも自動化したとのこと。私もそれ取り組もうと思っていたところだったので、一つの事例としてすごく参考になった。
自動リリースする際は、バージョン名をどうするかが課題だと思っていたので、懇親会で詳しくお話が聞けたのも良かった。年・週・リリース番号、みたいな機械的に取れる値でインクリメントしていく案は良さそう。

人がスケジュールを管理するのではなくてスケジュールによって人が動くようにしたい、というのはすごく共感する。
もちろん無茶なスケジュールを押し付けられて苦しむ、という意味ではなくて、定期的にリリースできる環境を作っていくという意味なので、私も目指したいなと思っている。

Google Play alpha 機能を選んだ理由 (TestLab によるモンキーテスト) や 段階リリースの良し悪しについてもお話できたので有り難かった。

FireTV ことはじめ

speakerdeck.com

FireTV全く知らないので新鮮だった。
Google開発者サービス入ってないから Firebase SDK 入れられないとは...おおお...。

Introduce Gradle Kotlin DSL

speakerdeck.com

Gradle Kotlin DSL の紹介。そんなのあったんスね...。

私はRubyistなのでどっちかというとGroovyの方が扱いやすいし好きなんだけど、Kotlinで書きたい気持ちも分かるようなそうでもないような。
実際、Kotlin で書くメリットもさほど無いようなので、これはスルーしてもいいかなぁ...と思った。

余談

お酒強くないくせにハイボール飲んだせいか、翌日から体調崩したので反省。

slackに流す分報にprefixを付けたい

分報とは

日報はその日の作業や悩みをその日の最後に書いて出すことになる。作業中の課題や考えていることが、日単位で共有されるため、他の人が目にする時には、すでにその課題は解決済みな場合がある。情報共有の時間差がどうしても発生してしまう。
そこで、ツイッターのようにその時その時の作業内容や悩みをアウトプットする取り組みとして、分報というものが活用できる。

分報の考え方や進め方は次の記事が詳しい。

c16e.com

私の分報の仕組み

私は Terminal で zshvim な開発環境なので、つぶやくなら Terminal 上で行いたい。
自社ではSlackを使っているので、TerminalからSlackに分報を送信したい。
そこで下の記事を参考に、 slackcat を活用することにした。

qiita.com

slackcat の課題

slackcat は Slack App の Token を使うので、私のアカウントで発言したことにはならず、Token を発行した Slack App が発言したことになってしまう。

f:id:yasuhiroki:20180426124002p:plain

妥協策

せめて、もう少し自分の発言っぽさを出したいので、カスタム emoji を追加したい。
下のような感じ。

f:id:yasuhiroki:20180426124123p:plain

分報を送るためのスクリプト

毎回 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 なので gstdbufgsed となる。 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 でエラーが出るようになったので調べたら
  • ImageMagickpolicy.xmlHTTPS から直接画像を指定できないようになっていたためだった
  • なので、S3からダウンロードしてファイルパスを Paperclip に渡すようにした

経緯

もともと、Paperclip を使って S3 上の画像ファイルを使ってゴニョゴニョしていた。S3上のファイルは https の Endpoint を指定していた。
で、Ruby バージョンを更新することにしたので、それならついでに AWS ElasticBeanstalk Platform も更新するかー、としてみた。
すると、Paperclip を使った処理で Paperclip::Errors::NotIdentifiedByImageMagickError が発生するようになった。

原因特定と対策

Paperclip::Errors::NotIdentifiedByImageMagickError だけだと原因が分からないのだが、すでに以前、 ImageMagick の policy.xml が更新されたことで、rmagick が動かなくなる現象に出会ったことがあった。こちらも rmagickconvert に 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 上の ImageMagick6.7.8-9 なので、そもそもホワイトリスト指定は使えない。yum update すれば良い話だけど。

やはりセキュリティの穴を自ら開けるのは嫌なので別の方法を検討する。

Paperclip コミュニティではどのように対策を?

Paperclipコミュニティでは、どのような解決方法を検討しているのか調べてみた。

結局ダウンロードしてから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

HTML5 Conference 2017 に行ってきた

events.html5j.org

行ってきた理由

  • 本職のFrontendエンジニアではないので情報収集しておらず知識が古いので
  • 勉強する際のキーワード集め
  • 勉強意欲のモチベーション維持

午前

寝坊して基調講演とセッション1に間に合わず。

後日の動画公開を待つことにします… (任天堂のセッションは多分公開しないと思うけど…)

最近の Web パフォーマンス改善について知っておきたいコト

パフォーマンス改善のために使える最近の技術について。
全く知見のないジャンルだったので、私にとってはただただ新鮮な情報ばかりだった。

詳解 WebRTC

「HTMLの話は一切しません」から始まる「WebRTCのプロトコルの解説」
最後の「これだけのプロトコルを全て隠蔽したのがWebRTC APIです。良かったですね」が、本当に良かったと思える濃厚な解説だった。
WebRTCが依存しているプロトコルを遡ってUDPから取り上げられていて、めちゃめちゃ楽しかったけど内容はほとんど理解できていない。

Web 技術とブラウザ ーいま知っておくべき Web 最新動向ー

この一年で各ブラウザがどのような新機能を追加したかの話。
情報を追いかけていなかった身としては助かるセッションだった。
Microsoftが作っているSonarというLintツール知らなかったので使いたい。ぱっと調べた感じVimのPluginは見つからなかったけど、もうちょい調査。

まあまあ最近のCSSと、これからつらくなくなるために

今年のCSSの目玉新機能 GridLayout について。
これは前から気になっていて、情報収集しつつもがっつり取り組めていなかった。
基本的な使い方の説明が分かりやすかったので一気に理解が進んだ気がする。
後半は既存のページにGridLayoutを導入するためにやったことの説明で、そもそもコンポーネント志向なCSSじゃないとGridLayoutは難しい、という話だった。
margin で余白を〜、という世界はいずれ無くなりそう。無くなるといいなぁ。

スペシャルセッション(ライトニングトーク大会)

LT面白かったー! たくさん笑ったて刺激をもらった。 数が多いので感想のまとめは割愛。

モバイルバッテリー貰いました!

全体を通して

目的通り、最近の情報をそこそこ収集できたと思う。
まずは見たセッションで得た知見を少しでも試して目と指で記憶して、余裕があれば他のセッションの情報もキャッチアップしたい。

HTML5 Conference に行ったの初めてだったけど、すごく楽しめた。来年もあるなら行きたい。
というか今まで行かなかったの勿体なかったなぁ….。

第10回 Jenkins勉強会 に参加しました

www.meetup.com

場所: テクマトリックス株式会社

発表者用とTwitter垂れ流し用のプロジェクターが用意されていて非常に良かった。

挨拶

日本Jenkinsユーザー会のドメインが変わったとのこと。

日本Jenkinsユーザ会

講演1:「第三版Jenkins 実践入門 What’s newから見るJenkinsのトレンド」 @yuki_iwnrさん

www.slideshare.net

Jenkins 実践入門の内容紹介

発表中に口頭で取ったアンケートでは、参加者のほぼ全員がプロジェクトでJenkinsを使っていて、5~6割くらいが 2.0 を使っていて 3割くらいが Jenkinsfile を使っていた。 Jenkinsfile はもっと広まるといいのになぁ。

Declarative と Scripted のどっちを使うかは悩ましい… Jenkinsfileが大きくなると関数化したくなるんだけど、Declarative だと自分で定義した関数が使えない。 かといって Scripted は自由すぎてメンテし辛い。 今のところ Declarative をメインに使って、どうしても関数化・共通化したい部分だけ Scripted を使うようにしてる。

Jenkinsの情報収集方法について紹介があって凄く助かった。 Pluginの検索ページが新しくなってたの知らなかった…

講演2:「Multibranch Pipeline with Docker 入門編」@kimullaaさん

t.co

Jenkinsを使っていたプロジェクトの悩みを、新しいJenkinsでどのように解決していったか、という話。

Jenkins で Docker を使う方法がいくつかあって、その説明と、どう選択したかの話が凄く自分にとってタイムリーで参考になった。

LT

ピザとビールが振る舞われた! Jenkinsユーザー会から出ているとのこと….。ありがたや!

LT1:「巨大不明ビルドの継続的統合を目的とするビルドパイプラインを主軸とした作戦要綱」 @kiy0taka さん

Jenkins の ビルドの通知について。

LT2:「Multibranch Pipelineでいろいろ学んだこと」 @AHA_oretamaさん

Multibranch Pipeline を使いはじめて得た知見のあれこれ。 ビルドのTrigger設定はちょうどいじってたばかりなので、大変参考になった。

LT3:「Jenkinsfileのlintで救える命がある」 @miyajanさん

Declarative Pipeline の構文チェックについて。
jflint というツールを作ったとのこと

www.npmjs.com

違うツールもあるらしい

LT4:「来週から始める本番環境の継続的デリバリー 」 @int128さん

お堅い組織で本番環境デプロイするには、な話。
検証環境で実績を作って、本番でも同じ方法で行う、を徹底した。

LT5:「プルリクエストCI時の2つのTIPS」 @ikikkoさん

プルリクエスト駆動開発でのCIについて。
Jenkins pipeline は CircleCI や TravisCI と同じようにリポジトリにビルド情報(Jenkinsfile)を置くので、プルリクエストと抜群に相性が良くて、使わない手はない。

リポジトリ間に依存関係がある場合のCIについての話が参考になった。

メモ

スライド見ててふと、自分の Jenkinsfile の先頭に groovy のシェバン付けてなかったことに気付いた。
そりゃあ vim でハイライトされなくて書き辛いわけだ…。