zsh: /usr/libexec/path_helperから逃れる方法 2020年版

macOSには /usr/libexec/path_helper というスクリプトがあり、これは /etc/zprofile で実行されOSがPATHをよしなに設定するというものだが、ユーザーが追加したパスより優先度高く追加するようになっており、かなり傍迷惑。
/usr/local/binなどより任意のパスを優先させたいのに〜〜〜ということがよくある。

Homebrewでzshを入れる際、過去には --disable-etcdir というオプションをconfigure時に渡すオプションとかがあったけどなくなっており、仕方なくforkして--disable-etcdirを付けたり、といろいろあったのだが、/etc/zprofileを読まないよう設定することもできて、これがおそらく最もポータブルな対処法でありそう。

unsetopt GLOBAL_RCSするだけ。

Commands are first read from /etc/zshenv; this cannot be overridden. Subsequent behaviour is modified by the RCS and GLOBAL_RCS options

zsh: 5 Files

注意したいのは /etc/zshenv は必ず読み込まれ、これはunsetopt GLOBAL_RCSでも回避できないこと。

2019

仕事

はてなブログ タグ

staff.hatenablog.com

initial commitの日付が1年くらい前だった。ほぼかかりきりだったので1年以上やっていたことになる。

上から下まで本当にいろいろやれて良かった。要素技術やらキーワードを挙げ連ねると:

  • Next.js
  • TypeScript
  • Go
  • GraphQL
  • styled-components
  • Atomic Design
  • AWS CDK

……などなど。引きの良いものが並んでいるけど、単に映えることだけを考えて挙げたり選んだわけではなく、必要とされるものや過去の反省を活かして最適な選択肢を模索した結果、これらが妥当と判断したので、すべての要素について選んだ根拠を自信をもって説明できる。 また、矛盾するようだけれどもすべてが最適だと考えているわけでもなく妥協した点や今後より良い選択肢が出そうな点についても心当たりがある。そういったリスク含めて説明できるし責任を負えると判断して作れたのは良い経験だと思う。

一方、こうした判断の壁打ちの機会が特に初期は乏しかったので、後から加わったメンバーからツッコミはなかったものの、それは既にできあがったからじゃないの、っていう疑念が無いでもない。 別にチームメンバーからのフィードバックを信用していないわけではないけれど、なんとなくこういうことって「便りのないことは元気な証拠」とも言い難い側面があるなあと思うので不安になっているだけだと思う。

たぶん今、自分が最も困っていてかつ解決すべきなのは、チームでお山の大将に限りなく近付いていることだと思う。自分の考えを理詰めで整理して伝えることが得意だと自負しているが、それが「なんか違う気がする」くらいの指摘を呼ぶ素地が無いように見えているんだと思う。 別に自分が受ける批判・指摘の全てに一切の瑕疵があってはならないなんて思っていないけれど、普段チームを引っ張るような役割の人間が常に75点くらいの仕事をしていたら、50点くらいでも赤点のような気がする、って周りに思わせてしまうっていうのは人の心として理解はできる。

じゃあ仕事の面で自分も甘さを見せれば良いのかというとそうではない気がするし、そうだとしてもかなりやりたくない。一辺倒では解決できない問題だと思うので、気長にトライアンドエラーしていくことになると思う。

テックスキルとしては、デザイナーとAtomic Designの落とし込みやJSSの選択について初期にかなりがっつり会話できたのは良い経験だった。あれこれ比較して当初から本命だったstyled-componentsに落ち着いたものの、比較検討できたことで選択に自信がついた。

そういったフロントエンドに近いところから始まり、インフラ設計はほぼひとりで、構築は後から加わったSREと一緒にやった。VPCなどネットワーク設計より上のことは一通りやったし、だいたい勘も付いた。

カメラマン

developer.hatenastaff.com

他社もインタビューコンテンツに力を入れている中、何がフックになるかといったらTwitter Cardsとかに出てくるサムネイルが大きいんじゃないかと思い、写真係やりますよって言い出して長命なシリーズになっている。

プロの方が絶対に腕は良いけど、小回りが利くことは強みではないか。

登壇

speakerdeck.com

speakerdeck.com

speakerdeck.com

仕事関係が2つ、完全な趣味が1つ。数は少なめだったけど、仕事の方はまだ出せそうなネタがいくつかあるのできっちり出しておきたい。

趣味のほうは、リメイクということで個人的にはちょっといただけない感じがするものの、動くデモが作れたのでトントン。

ソフトウェア

わりと仕事でやっているプロダクトで必要になったので書いてOSSにした、っていうのが多い。

go-http-replay

Go版vcr

「外部APIにアクセスするテストを書く時にスタブをしたいけど、手作りするより本物のレスポンスを使いたいよね?」「でもいちいちcurlして保存して……はだるいよね?」 → じゃあ初回だけ実際にリクエストして、そのレスポンスを保存して使い回そう! というライブラリ

Goには httputil.DumpResponse / httputil.ReadResponse っていう便利グッズがあるのでこれを使っているだけ。 http.TransportというPerlでいうLWP::Protocol的なやつを差し替えるだけでやっている。 72行くらいしか無いけど、Goのnet/httpのおもしろさが詰まっていると思うので気が向いたら読んでみてください。

go-envschema

環境変数JSONのobjectと見なせるやん? だったらJSON Schemaで検証できるやん? という発想によるライブラリ。

詳しくは 大コンテナ時代を生きのこるためのJSON Schema

go-dsn

TypeScriptで書いたオブジェクトを https://github.com/go-sql-driver/mysql のDSN (Data Source Name) 文字列にするNPMパッケージ。

AWS CDKでRDSのhostname/portを結合してコンテナの環境変数に渡すために作った。

cdk-mackerel-container-agent

CDKで書いた TaskDefinitionmackerel-container-agentをsidecar containerとして良い感じに差し込むグッズ。 mackerel-container-agentが対応している環境変数などをいちいちドキュメントを見に行かなくてもIDEで補完してくれるようにという目的で書いた。

ベータ版の頃はクラスタがFargateとEC2かによって設定の感じが変わるのでまあまあ賢いコードが書いてあったけど、今は単にデフォルト値を与えるくらい。 CDKがDeveloper Previewのころからライブラリにしていたので毎週のbreaking changeでスナップショットが壊れては仲間たちが丁寧に jest -u してくれた思い出のライブラリです。

action-aws-assume-role

GitHub Actionsで使えるaction.

文字通り AssumeRole して得られたsession tokenやらを環境変数にexportするグッズ。

gqlgen-tracer-xray

gqlgenでAWS X-Rayのトレースを良い感じに取るプラグイン。ほとんどopentracing版を真似しただけ。

migrate-gh-repo

2つのGitHubリポジトリでissueやらラベルやらを移行するスクリプト

似たようなツールはいろいろあるけど、ほとんどべき等になっているところとあまり賢くないが故に柔軟性が高いのが売り。

古いリポジトリのissueへのリンクを残すだけの仕様になので、たとえば複数リポジトリを1つのリポジトリへmonorepo化しつつ移行する場合にも、同じissue numberにコメントでリンクが書き連ねられるだけなので、N:1の移行も問題なくできる。

技術的には設定にCUEを使っているのがおもしろポイント。

総括

仕事に全振りした1年だった。それなりに得るものもあったけど、どうしてもやったことが仕事の文脈だけだとおもしろみが無いなあと感じてしまう。 来年は文字通りの意味でワークライフバランスの良いおもしろ技術探索をやっていく。

VSCodeでJSONを編集する時にJSON schemaを指定して補完を効かせる

JSON editing in Visual Studio Code

tsconfig.jsonなどはデフォルトで補完が効くが、これはsettings.jsonで追加できる。

たとえばrenovate.jsonを編集する時はこういう設定を入れておくと便利。

  "json.schemas": [
    {
      "fileMatch": ["renovate.json"],
      "url": "https://raw.githubusercontent.com/renovatebot/renovate/master/renovate-schema.json"
    }
  ]

SlackとGitHub Deployments APIで疎結合なChatOpsを実現する

this.aereal.org

Deployments APIが出た頃に上記記事を書いてもう5年が経とうしている中、最近いろいろなグッズが進化してタイトルにあるような良い塩梅のChatOpsが実現できそうなのでそれのメモ。

登場人物

Deployments APIGitHub Actions

このAPIだけではなんらかの仕事は行われず、ただWebhookのイベントが通知されるだけのAPIになっている。
この説明だけ聞くと「ふーん」というかんじだけれども、各種Webhookイベントに応じてなんらかのタスクが実行でき、しかもCI用に払い出されたAPIキーが振ってくるというGitHub Actionsの存在でできることの幅や手軽さが変わってくる。

実際のWorkflow YAMLを見るのが早いと思う: https://github.com/aereal/actions-playground/blob/master/.github/workflows/deploy.yml
on: deployment を書いておけば、Deploymentが作られた時にこのYAMLの内容が実行される。

内容の詳細は:

……となっている。

この例では活用していないが、Deployment APIのパラメータにはtaskやenvironmentがあるのでステージング環境か、アプリケーションのデプロイの他にDBのスキーマ更新などの付随するタスクも表現できたりなど、いろいろ使い出はありそうに見える。

Slackからデプロイ

では肝心のDeploymentはどうやって作るの、ということだけど、これまでは丁寧にcurlするしかなかったのが最近SlackのGitHub連携から作れるようになった。

/github deploy OWNER/REPOを実行するとこういう画面が出てきて:

n

リビジョンなどを埋めるとAPIが呼ばれる。

上記GitHub Actionsが設定されていれば、ピタゴラスイッチが動き出すという寸法。

Slackにはこういう通知が出る:

f:id:aereal:20191029121824p:plain

Deployment viewに期待

最近ひっそりとdeployment viewというものがベータリリースされている。これまで紹介してきたactions-playgroundの画面だとこういうかんじ: https://github.com/aereal/actions-playground/deployments

f:id:aereal:20191029121952p:plain

今は本当にログしか出てきていなくて味気が無いけれども、GitHub公式でこういうビューを作ろうとしているのはちょっと期待。

まあ仮にお蔵入りになってしまうとしてもDeployments APIを使ってちょっとしたビューを作るのはわりと楽だろう。

なぜDeployments APIなのか

こういうChatOpsの類はずっと前からいくらでもあるし、Deployments APIの何が良いの? という向きもあるかもしれませんが、以下の点でとても魅力的だと思っています:

  • チャット (Slack) 側の仕事内容が少ない = 移植性が高くコントローラブルな要素が多い
  • チャットを介さない実行が容易
  • Commit Statusなど既存のGitHubエコシステムと深く統合されて、今までの暮らしがスポイルされず、むしろ進化させられる

チャット側の仕事が少ないというのは、これまで見てきたように単にHTTP APIを呼び出しているだけなので、なにかうまく動かないということがそもそも起きにくい・起きたとしてもトレースがしやすい・実装の移植がしやすい、という点が嬉しい。
なんでもChatOpsにしたはいいがいざSlackが落ちると何もできないという事態に陥ることなく、いざとなればcurlを叩けば良いというのもポイントが高い。

またWebhookなどイベントベースのピタゴラスイッチはどこがホットスポットなのかわかりづらく全容を把握しづらくなってしまうことも多いけれど、Deployments APIとActionsの組み合わせだとGitHubが中央にあるので、とりあえずリポジトリを見れば概形がわかるというのも差別化ポイントになりうると思う。

さらにCommit Statusなど既に広く使われている機能などと統合されているというのも魅力。たとえばDeploymentにrequired_contextsを指定できるので、prchecklistのチェックが完了しなければデプロイが進められない、という制約も簡単に実現・移行できる。

そもそもなぜDeployments APIの話をしているのか

git の develop ブランチは必要なのか、またはリリースtagについて - Togetter

ここらへんでGit FlowなのかGitHub Flowなのかみたいな話が盛り上がり、そういえば最近Deployments APIが盛り上がっとるなということを思い出したのがきっかけ。

id:Songmuさんにこういうリプライもした:

実際、いま新しくやっているプロジェクトでもGitHub Flowに近いワークフローになっている。
コンテナワークロードになると同じリビジョンから作られる成果物を複数環境にデプロイが容易になるはずなので、アプリケーションの内容は同じなのに複数リビジョンが付くGit Flowは困ることが増えるなあ、という印象を抱いていた。

とはいえ上記Togetterまとめにあるとおりgit-pr-releaseは様々な点で便利なのは間違いない。が、本質は差分の可視化といったところなどにあるはずでPull RequestやGit Flow的なブランチ運用が根幹にあるものではないと思っていた。

そんなモヤモヤを抱く中でDeployments APIが進化してきたので注目しているというかんじ。

1PasswordのChrome拡張どれ使えばいいのか問題

結論から言うとtouch IDを使いたいなら「Xじゃないほう」

相対パス、絶対パス、相対URL、絶対URL

どう違うのか微妙にわかりづらいので表にした。

URL 相対パス 絶対パス 相対URL 絶対URL
/hoge n Y Y n
hoge Y n Y n
file:/// n n *1 n Y
https://example.com/ n n *2 n Y

便宜上、path-rootlessあたりを「相対パス」、absolute URIでないものを「相対URL」としています。

schemeが付いている場合のみ絶対URLで他の表現は相対URL、パスの絶対相対とURIの絶対相対は独立している、ということを覚えておくとよさそう。

参考: RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax

*1:is aではないがcontainsではある

*2:is aではないがcontainsではある

『入門 監視』を読んでMackerelの良さを改めて実感した

読んだ。新サービスローンチ前に読んでおいてよかった。

  • 目新しい話題はあまりなかった
    • なんとなくこうだよね、と思っていることが確認できた
    • 自信がなかったり理解が曖昧だったところを確認できた
      • メッセージングキュー (はてなでいうワーカー) の監視メトリックはキューの長さと消費率 (仕事率) を見るのが良い
  • 印象的だったところ
    • 監視自体は何も 修復 してくれません。何かが壊れたら、あなたがそれを直す必要があります。

    • オンコールシフト中、場当たり的対応をしていない時間は、システムの回復力や安定性に対して取り組むのをオンコール担当の役割にする - 3.2.2 場当たり的対応を減らす

    • 自動車メーカーのフォ–ドが、燃料タンクにガソリンがどのくらい入っているか計測する方法がない車を作ったとしたらどうでしょうか。(略) これらは、車が完成してから単に取り付ければよいというものではありません。ごく最初の段階から車にデザインされているものです。 - 5.4 自分のアプリケーションにそんなメトリクスはないという時は

Mackerelネイティブに育った人間なので「監視はこうあるべきだよね」という意識がキャリアが始まった時からインストールされていたことに気がつき、最初から一番良いやつを選べたのは高速道路だなーと思った。

このブログはMackerelを開発・提供している株式会社はてなでの勤務時間中に書きましたが、意見は私個人のものです。

ところで:

はてなで一緒に働きませんか?

typescript-eslint: monorepoでVS Codeからtsconfig.jsonのパスを正しく認識させる

typescript-eslintは型情報が必要なルールのためにプロジェクトの場所をparserOptions.projectで指定できる。

monorepo構成の場合かつ相対パスで指定している時、 yarn workspace front eslint ... のように実行する場合は期待通りtsconfig.jsonを見つけてくれるのだけれど、VS Codeのeslint extensionが実行する時にはtsconfig.jsonを見つけられない。

これは既知のissueでこの記事を書いている現在でもopenのまま:
Make `tsconfigRootDir` relative to the `.eslintrc` file · Issue #251 · typescript-eslint/typescript-eslint · GitHub

workaroundはあって tsconfigRootDir という相対パスを解決する基準となるパスを指定できるので、これに __dirname を指定するとVS Codeからも正しく見つけられる。

    project: "./tsconfig.json",

    // tsconfigRootDir: __dirnameを指定しないとVS Codeでmonorepoのtsconfig.jsonを正しく解決できないので.eslintrc.jsにしている
    // refs. https://github.com/typescript-eslint/typescript-eslint/issues/251
    tsconfigRootDir: __dirname,

__dirname が必要なので .eslintrc.js に書く必要がある。package.jsonや.eslintrc.jsonではだめ。

制限されたIAMロールをAssumeRoleして安全に削除操作を実行する

三行

  • 怖い操作をする時は許可するAPIコールを制限したIAMロールをAssumeRoleすれば安心
  • IAMユーザーにアクセス許可を委任するロールは同じAWSアカウントを指定することもできる

怖い操作をする時は許可するAPIコールを制限したIAMロールをAssumeRoleすれば安心

大量のリソースを削除するような操作はコンソールでぽちぽちやるとミスりそうで怖いのでスクリプトを書いて適宜レビューしやすいようにしたい。
けれども、普段使うIAMユーザーの権限だと広すぎると間違ったリソースを削除するなどの事故が怖い。普段からやや広めの権限で生活しているといきなり狭めるのも難しい。

今回はversioningが有効なS3バケットを削除したいが、削除するためにはすべてのオブジェクトのすべてのバージョンが削除されてバケットが完全に空じゃないといけない、という問題に遭遇した。

そこで実行したいAPIコールとリソースを限定したポリシーをアタッチしたIAMロールを作る。そしてaws-cliを実行する際にrole_arnを指定してAssumeRoleすることで、リスクを抑えられる。
refs. AWS CLI での IAM ロールの使用 - AWS Command Line Interface

IAMユーザーにアクセス許可を委任するロールは同じAWSアカウントを指定することもできる

IAMロールは使用する主体に応じて作り方・コンソールの画面が違う。

ドキュメントには以下の3つが挙げられている:

  • IAM ユーザーにアクセス許可を委任するロールの作成
  • AWS サービスにアクセス許可を委任するロールの作成
  • サードパーティーの ID プロバイダー (フェデレーション) 用のロールの作成
IAM ロールの作成 - AWS Identity and Access Management

今回はこのうち「IAM ユーザーにアクセス許可を委任するロールの作成」を選ぶ。

IAM ユーザーにアクセス許可を委任するロールの作成 - AWS Identity and Access Managementを読むとあたかもAWSアカウントをまたいだ操作を許可するためだけに使うようにも読めるがそんなことはなくて、IAMロールを発行するAWSアカウントと使用するAWSアカウントが同一であっても構わない。

似た事例: [https://dev.classmethod.jp/cloud/aws/assume-role-deploy-iam-user-and-role/:title=[AssumeRole] アクセスキーが流出しても被害が最小限になるIAMユーザでCloudFormationにデプロイする方法 | DevelopersIO]

#builderscon tokyo 2019で「自動作曲入門」について話した

自分のトーク

speakerdeck.com

デモはこちらです: musik

社内勉強会でやったトーク (『Scalaで自動作曲の練習』を社内勉強会で話した - Sexually Knowing) をベースにしています。 自分は資料を使い回して登壇することに強い抵抗を感じるので心苦しくあったのですが、社内勉強会から飛び出して広いところでぜひ話したいという思いがある一方で、ここから進んだ話をスクラッチから立てるのは今は厳しいという評価もあったので、折衷案としてトークの内容はほぼそのままに、きちんと動くデモを作りなんなら登壇するその場でメロディをつけるくらいのライブ感を出すくらいはやれたら自分も納得できそうだということでproposalを出し、トークする場をいただきました。

当日はWeb Audioを使ったデモはうまくいったのですが、MIDIキーボードを挿してメロディをつけるところはうまくいかなかったのでそれだけ心残りです。 Oscillator nodeのゲイン調整をしておらず音が大きすぎたため、メロディが鳴っているはずだけどほとんど聞こえないということが起きていました。ちゃんとGain nodeを繋げたらよさそう。

正直、目新しくも高度でもない話なので失望されないかドキドキしていましたが「おもしろかった」「やってみようかと思った」といった感想をいただけて登壇冥利につきます。

トークを聞いた方・このブログを読んだ方はぜひaereal/musikをforkしておもしろコンポーザを作ってください!!!

聞いたトーク

当日朝までデモを作るなどした結果、時間も体力も尽きてあまり聞けなかったのが悔やまれます。

Open SKT: メルペイ開発の裏側 - builderscon tokyo 2019

メルペイのオンボーディング内容をベースに公開できる内容にしたということで、まずオンボーディングプロセスが充実していることに驚きました。

個人的には分散トランザクションを伴う決済システムを開発しているので、わかる〜〜〜と思いながら、やっぱりある程度泥臭くなるよね、と安心しました。

コンパイラをつくってみよう - builderscon tokyo 2019

DQNEOさんによるコンパイラを1から作るライブコーディング。

Goのscannerなども使わず、コアの部分はほぼスクラッチから書いていくかんじで他の言語でも実践できそうなつくりなのが真似しやすくて親切設計でした。

会場から「そこtypoしています」とかやりとりがあったり、ライブ感があってめちゃくちゃ楽しかった。

Ruby (off|with) the Rails - builderscon tokyo 2019

僕はこのトークを「Railsに乗る = 使わされるだけではなく、ツールとして使う対象にする」「守破離」という趣旨だと理解しました。

普段、Railsを使わない立場 (業務で書いた経験はある) なので「大変そうだなー ActiveRecordが向いていないところもけっこうあるよなー」とわりと対岸の火事気味に聞いていましたが、一方、ライブラリ・フレームワークを使う上で一般的な話だとも思います。

つまりライブラリの事情などを抜きにして、責任の分離など抽象度の高い設計の作業を行い、それを実装へ落とし込む際に設計で果たしたい分離や凝集を壊しそうなライブラリの機能 *1 はこれとこれがありますね、というような思考を辿っていくもので、Railsユーザー以外でも得るものが多い内容でした。

Building, and Upkeeping Super Kamiokande - builderscon tokyo 2019

事前から楽しみだったし実際にめちゃくちゃおもしろかったトーク

実はこのトークを聞くまでスーパーカミオカンデが何なのかよくわかっていなかったので、そういった点でもdiscover something newが果たされました。

基礎物理学の世界の遠大な観測対象であっても、個々は素朴な技術 (センサー) と素朴な役割のソフトウェアシステムでできあがるというのがおもしろい。ただそのスケールがめちゃくちゃに大きいというのが興奮します。

11月に一般公開があるみたいなので申し込みます。いやーよかった。

北千住

事前の公式ブログで北千住駅の案内で脅かされていたり、足立区はなかなかラディカル *2 な土地だよと聞いて、トラブルに巻き込まれずに済むのか内心ヒヤヒヤしていましたが、無事どころかずいぶん楽しいできごとが多くて好きになりました。かなりホーム感がありました。

駅の近くにクラフトビールのお店がいろいろあったり、雑なところからそこそこのところまで飲食に困らなかったり、なにより荒川が近いのが良い。

川で飲んだりすることはけっこう奇行じみていると思われがちだけど、実質立食パーティみたいなもので、席に囚われず歩きまわっていろんな人と話せるというとても合理的なかたちでかなり好き。 懇親会が終わったあと20人くらいで荒川に移動したけど、飛び込みで20人も入れるお店はなかなか無いと思うし、見つかっても近くの席以外の人と話すのはなかなか難しいと思う。 出入り自由で、飛び入り参加したければ任意でお酒や食べ物を持ち寄るだけでよく実質プリペイドなのも気軽。

他人との距離、たしかにという感じ。居酒屋だと近すぎて疲れるけど、川だと自由に歩いて離れられるから気が楽、とかある。あとは、クラブとか行くとうるさいから距離近くなるとかある気がする。 かくれた次元 - hitode909の日記

鴨川でビール飲んでた.15人くらい来てくれた.

コンビニでクリスマスケーキ買って川で立ってケーキ持ってたら雪降ってきて最高の誕生日みたいな感じだった.前回は寒すぎてすぐ店に入ってしまったけど今回は暗くなるまで川にいられて自由に歩きまわって会話できてよかったと思う. ■ - hitode909の日記

荒川はとても広く地元の石狩川を彷彿とさせるスケールで、懐しい顔ぶれと話しているシチュエーションも手伝ってやけに楽しくちょっと懐かしい感じがした。

*1:いわゆるハマりポイントと呼ばれがちなもの

*2:婉曲しています

Google App Engine Standard EnvironmentにScalaで書いたWebアプリケーションをデプロイ

してみた: GitHub - aereal/gae-scala

GAE SE (Google App Engine Standard Environment) のいわゆる2nd generationと呼ばれるgVisorで構築された世代でJava 8/11が使える。

GAE SE (Google App Engine Standard Environment) ではgVisor上で実行されるランタイムとして新たにJava 8/11が選べる。

※当初Java 8を含めて2nd gen.としていたが公式ドキュメントによるとJava 8はgVisorで仮想化されているが、世代としてはJava 11のみが2nd gen.だったので訂正します。

Second generation runtimes are: Python 3.7, Java 11, Node 8, Node 10 PHP 7.2, PHP 7.3, Ruby 2.5, Go 1.11, and Go 1.12.

The App Engine Standard Environment  |  App Engine Documentation  |  Google Cloud

かつ、Serveletに対応しているJVM言語なら基本なんでも動くっぽく、公式のサンプルではKotolinの例もあった
https://github.com/GoogleCloudPlatform/getting-started-java/tree/master/appengine-standard-java8

古いJava 7ランタイムとの詳しい違いは以下:

The App Engine Java 8 runtime, which is based on OpenJDK 8, supports all of the existing features available in the current Java 7 runtime, which is based on OpenJDK 7, but with the following upgrades and enhancements:

  • Doesn't impose a security manager as the Java 7 runtime does, which means your code won't be restricted by Java permissions issues.
  • Supports all the standard public Java libraries.
  • Uses Jetty 9
  • Supports the Java Servlet 3.1 and Java Servlet 2.5 specifications.
  • Supports all Google Cloud-based APIs accessible from the Google Cloud Client Library for Java.
Java 8 Runtime Environment  |  App Engine standard environment for Java 8  |  Google Cloud

で、Scalaも動きそうだったので試した。

やったことは:

  • Scalaなのでmvnではなくsbtを使いたいのでsbt-appengineを入れる
  • GAEと関係ないけどScala 2.13にしたかったのでScalatra 2.7 RC1にした
    • ドキュメントに書いてある依存ライブラリのバージョンだと古くて2.13に対応していなかったりするので適宜上げたりした
  • Homebrewで入れたApp Engine SDK for Javaのどこにパスを遠したらいいかわからなかったけど `libexec` が正解だった

元気に動いています: https://gae-scala-247510.appspot.com

Serveletに対応していないとだめなのでPlayは動かなさそう。
こういう時はScalaでもWSGI/Rack的なやつがはやく策定・普及するといいですね〜〜って思う。

#builderscon 2019で「自動作曲入門」というトークをします

8月29日の前夜祭から始まるbuilderscon tokyo 2019で「自動作曲入門」というトークをします。
以前、このブログで紹介したScalaで実装してみたものを発展させたものをベースにしながら「そもそも作曲という行為をソフトウェアエンジニアの視点で再解釈するとどうなるのか」といった話から始める予定なので「むずかしそう」と思っている方でも楽しめる・むしろそんな方にこそ楽しんでほしいトークになると思います!

あと、おそらく音がなります。

僕のトークは8月31日の11:30から1204 セミナー会議室です。

builderscon.io

そんなbuilderscon tokyo 2019のチケットは7月22日までの販売だそうなのでまだの方はいますぐカモンジョイナス

builderscon-tokyo-2019.eventbrite.com

SVGから複数のfaviconを出力したり開発環境用に色を変えたりする

  • faviconやらapple-touch-iconやらいろいろ必要なアイコンが多い問題
  • 開発環境と本番でfaviconを区別して事故を防ぎたい問題

……などの話題がアイコン界隈にはあります。

SVGを使ってどちらも解決してみよう! のコーナーです。

必要なアイコンを生成する

icon-genというnpmパッケージを使うとSVGからicoやらpngが生成できます。便利。

こういうかんじ:

      const results = await icongen(variant.src, destPath, {
        favicon: {
          sizes: [180, 192],
        },
      })

開発環境ごとにfaviconを変える

↑でSVGからico/pngを生成するグッズを手に入れたので、ソースのSVGを環境ごとに変えればよさそう。

こういうかんじ:

const generateVariantSource = (variant) => {
  const { fillColor, src: dest } = variant;
  if (fillColor === undefined) {
    throw new Error('fillColor is empty');
  }
  const buf = Buffer.from(readFileSync(variants.live.src)); // assumed buffer
  const content = buf.toString().replace(/fill="#000000"/, `fill="${fillColor}"`);
  writeFileSync(dest, content);
};

replace(/fill="#000000"/, `fill="${fillColor}"`) は色を変えるハイテクなコードです。

BuildKitによるレイヤキャッシュのtargetは変数 (ENV, ARG) を展開してくれない

feature request: allow variables in the `RUN --mount=type=bind` values · Issue #815 · moby/buildkit

RUN --mount=type=cache,target=${APP_DIR}/pkg/cache go get -v と書いても `${APP_DIR}` という名前のディレクトリが作られるだけです! びっくり!

✘╹◡╹✘ < docker run --rm api:builder ls
${APP_DIR}
Makefile
api
go.mod
go.sum