codebuildでハマってた
会社のブログに書いたけど、ここにもまとめておく
AWS CodeBuild使ってみようとして、以下の二点でハマった。
- buildspec.ymlのphase名をtypoってもエラーにならず、phasesが全て素通りした。
- go言語のプロジェクトをビルドしようとしたら、vendoringが有効になってなくてハマった
phase名をtypoってもエラーにならない件
ビルド完了してるのに、artifactsに指定したファイルが見つからないというログが出てて、なんでだろうと思ってたら、phasesを全て無視して、artifactsの処理だけ走ってたという話。
(そもそもartifactsに指定したビルド成果物が見つからなかったらエラーにしろって思うのですけど)
原因はpre_buildをpre-buildとtypoしてたせいでした。
phase名をミスったらphases全体をスキップしてしまうのは規定動作なのだろうか??
go言語のvendoringが有効になってなくてハマった
上記のtypoを修正して再実行したら、今度はbuildフェイズのgo buildでパッケージが見つからないと言われた。can not found package〜ね。
pre_buildフェイズでglideで依存パッケージは入れてるはずなので、おかしいなーと思いつつ、vendoring機能について確認してたら、そもそもビルド対象のプロジェクトディレクトリがGOPATH配下に無いことに気づいた。
(GOPATH配下じゃないとvendoringが有効にならないことを忘れていた)
codebuildはビルド対象として指定したリポジトリを/tmp/tmpランダム数字/srcって感じでチェックアウトしてくる。
で、ワーキングディレクトリは上記パスのsrc配下になっている。
この状態からvendoringを有効にするために行なったワークアラウンドが以下。
pre_build: commands: - glide install - mkdir -p $GOPATH/src/github.com/stk132/tsg - mv * $GOPATH/src/github.com/stk132/tsg/. build: commands: - cd $GOPATH/src/github.com/stk132/tsg && go build
うん。GOPATH配下に自分でディレクトリ切って、ファイル全部コピーして、当該ディレクトリに移動してgo buildコマンドを叩いている。
cdとgo buildをつなげているのは、別の行にわけて実行すると、cdの次の行ではワーキングディレクトリに戻っているため。
(このあたりはDockerfileをビルドするときと同じ挙動ですかね?)
これはもうちょいスマートな方法ないですかね??
まとめ
しょうもないことでハマったせいでポケモンやる時間吸われてつらい
ひさびさにMakefile書いた
別にC++を書き始めたとかいうことではない。 タスクランナー代わりにMakefileを使っている。
今仕事で、NFSのHA構成を構築するAnsibleスクリプトを組んでいるのだけど、ansible-playbookコマンドってextra-varsとか、tagの指定とか入ってくると横にクソ長くなるし、extra-varsの一部を変更して実行する必要がある場合とか面倒くさいんですよね。
なのでMakefileでタスク定義すればいいじゃん?と思いました。
Macならデフォルトで入ってますしね。(command line toolsかxcode入れる必要あったっけ?)
ていうかデフォルトで入ってるっていうのはツール選択上の強みですよね。
(だったらシェルスクリプトのほうがいいやんけって言われそうだけど)
gulpとかで書いた場合、他の人に渡すときにgulp入れてもらわないといけなくなるし
gulp1つインストールできない人にAnsibleスクリプトを引き継いだりするのは、それはそれで怖いけどね。。。
ここ一年間の進捗
ここ一年間ほどダイエットを敢行していたので、進捗を晒します。
進捗
- 開始時 : 133kg
- なう : 80.75kg
身長174.5cmなので、あと10kgほどは落とす必要がある。
ちなみに体脂肪率は11/7朝時点で12.7%とか出たが、体重が増減してないのに日によって5〜8%ぐらい上下するのであまり信用していない。
きっかけ
去年の健康診断で血圧が上140いったのと、肝臓の数値が悪くて病院での診断をすすめられたため。
「痩せりゃ正常値の範囲に戻るっしょ」という雑な考えのもとダイエットを開始した
(結局医者にはかかっていないので、今月の健康診断で数値が悪いままだったら本当に病院いかないといけないかも)
手法
食事はとりのささみをレンチンしたものにケチャップをかけたのと、豆腐をレンチンしてめんつゆかけたのばっかり食ってた。
あと、毎日エアロバイク15km
厳密には食事制限してなくて、大体1日1500kcal以下を目標としてたんだけど、カロリー計算するのがめんどくさくて同じものばっかり食ってた。
痩せてどうなったか
適当にLサイズの服を選択して普通に着られるっていうのは最高
(キングサイズの衣料はデザインがダサい上に、面積がデカイために高いということが多い)
あと、ズボンにデブ穴ができる心配が減った。
しかし、足のサイズが30cmあるので、靴選びだけは未だに難航する。(靴下もな)
終わりに
もう少しでBMI上の肥満域を脱してしまうのだけど、このブログのタイトルどうしましょうかね。。。
speakerdeckのスライドをpdfで保存するCLIコマンドを作った
pocketに保存したspeakerdeckのスライドをpdfでダウンロードしてローカルに保存するコマンド
won't read it laterの頭文字をとって「wril」です。
なぜ作った?
端的にいうとspeakerdeckが重くてkindle fire HD7と俺の寿命がマッハなので、いったんpdfで保存し、kindleパーソナルライブラリに突っ込もうとしたって話
いや、ほんと、speakerdeckって重くないですか? エアロバイク漕ぎながらpocketに入れた記事を消化するんですが、slideshareは普通に見られるのに、speakerdeckは重くてまともにスライドのページがめくれないんですよね。
めくれないどころか、kindle fire HD7がフリーズして再起動したんですよね。
おかげでspeakerdeckのスライドが全然消化できないので、技術で殴ろうとしたという話
仕組み
- pocketのapiを叩いて、「speakerdeck」という文字列が含まれるエントリを検索
- 上記検索結果からエントリのURLにアクセス
- アクセスしたspeakerdeckのページから、PDFのダウンロードリンクをスクレイピング
- 上記pdfリンクにアクセスしてダウンロード
技術的に特におもしろいところはない。
pdfをkindleパーソナルライブラリにアップロードするところは今のところsento-to-kindleアプリで手動アップロードしている
使い方
以下でコマンドをビルド
npm install npm run build
pocketのコンシューマキー、アクセストークンを環境変数に設定
export POCKET_CONSUMER_KEY=xxxx export POCKET_ACCESS_TOKEN=xxxx
以下のように実行
node dist/main.js -d /tmp/pdf_dl -c 10 -s unread
オプションで指定しているのはそれぞれ
- ダウンロード先ディレクトリ
- ダウンロード数
- pocketのアーティクルのstateの指定
ちなみにpdfのタイトルはURLをスラッシュ区切りにして、末尾のパスを使っている。 これだと同名のスライドがあった場合、上書きされてしまうので、スライド著者のspeakerdeckのアカウント名を先頭に入れて一意性を担保したほうがいいかもしれない。
終わりに
とりあえず、pocketに保存したspeakerdeckのページからスライドをpdfダウンロードして、kindleパーソナルライブラリに保存するという目的は達成できている。
あとはページング対応入れたらいいかなという感じ
というか、当初IFTTTとAWS Lambdaと組み合わせてピタゴラスイッチ化するつもりだったんだけど、途中でめんどくなってやめた。CLIコマンドならnode.jsである必要はないので、golangで書き直すかも。
Goでoshiraseというslackのcliコマンドを作ってみた
最近仕事でバッチやら定期実行してる監視スクリプトやらの結果をslackに通知させることが多いんだけど、シェルスクリプトからcurlでapi叩くのは面倒なので、goで簡単なcliコマンドを作ってみた
今のところ機能は以下の3つだけ
- 指定したチャンネル、グループにメッセージを投稿する (message)
- チャンネルの一覧を表示する (channel)
- グループの一覧を表示する (group)
slackの画面上からチャンネルIDとグループIDを調べるのが地味に面倒だったんだよね。。。
ちなみに、最初はslackerという名前にしようとしていたのだけど、github上で検索してみたら同名のリポジトリが600件ぐらいあった。。。
Thorで作った対話型コマンドをテストする方法
最近ThorでCLIコマンドを自作することが多い。 普通にテストするだけなら以下の記事の方法で問題無い
対話型コマンドの場合、テスト時にどうやって入力を与えればいいのか分からず、ちょいとハマってた。
解決方法:標準入力をモックすればよい
解決法は単純で、標準入力をモックすればよかった。
利用したテストダブルのライブラリはRR
stub($stdin).gets { "hoge" } Hoge.new.invoke :hoge, [] {}
ただ、上記の方法だと何回$stdin.getsしても同じ値が帰ってくるようになるので、ユーザに入力を複数回求める場合は使用できない。 そういった場合は以下のようにする。
stub($stdin).gets.times(1) { "hoge" } stub($stdin).gets.times(1) { "fuga" } Hoge.new.invoke :hoge, [], {}
上記のように指定すると、一回目はhoge、二回目はfugaが返却されるようになる。
欲を言えば、配列で指定した順番に返却してくれたりすると嬉しいんだけど、そういう感じの指定方法ってできないのかな?
初PRをキメた話
標準出力、標準エラー出力をキャプチャするgem、arieteにpull requestを出してマージされました
ariete.rb内にrspecの独自Matcherを定義しているため、arieteはrspec依存しているのだけど、gemspecにはrspecがdevelopment_dependencyで指定されており、かつariete.rb内でrspecがrequireされていなかったために、test-unitで使おうとした際に、require "ariete"するとNameErrorが発生するというもの。
(その前にrequire "rspec"しとくと回避できるけど)
修正箇所は2行。うん。プルリクのコメント書くほうが時間かかったよね。