くりにっき

フルスタックキュアエンジニアです

rubocop-itamaeを作った

itamae のレシピを静的解析するrubocopのプラグインを作りました。

github.com

コンセプト

前職でitamaeのレシピをレビューすることが多々あったのですが、毎回同じことを指摘するのも大変だったのでrubocopのcopにしました。

rubocop-itamae自体はrubocopにしか依存していないので itamae と mitamae の両方のレシピで使えると思います。

下記のようなcopを作っています

Itamae/CdInExecute

execute の中で cd せずに cwd を使え。

# bad
execute 'cd /tmp && rm -rf /tmp/*'

# good
execute 'rm -rf /tmp/*' do
  cwd '/tmp'
end

Itamae/CommandEqualsToName

execute の引数と command で同一のコマンドを書くのはDRYじゃないのでやめろ

# bad
execute 'rm -rf /tmp/*' do
  command 'rm -rf /tmp/*'
end

# good
execute 'rm -rf /tmp/*'

execute 'Remove temporary files' do
  command 'rm -rf /tmp/*'
end

Itamae/NeedlessDefaultAction

デフォルトのaction(package リソースでいえば :install)は省略できる

# bad
package 'git' do
  action :install
end

# good
package 'git' do
end

package 'git'

Itamae/RecipePath

レシピが itamae推奨のディレクトリ構成 に沿っているかチェックする

# bad
default.rb
hoge/web.rb

# good
cookbooks/nginx/default.rb
roles/web.rb

copを作ったメリット

  • 今までレビューで指摘してきた事例に対して Itamae/CdInExecute のような名前をつけることができたのでよかった

今後作りたいcop

Itamae/NodeKeyType

grepabilityの観点からnode のkeyをStringかSymbolかのどっちかに統一しときたい。

途中までは作った *1 んだけど、現状のrubocopだと実装に必要な機能が足りないのでいったん保留 *2

転職エントリ

こちらからは以上です。

*1:最終出社は5/25であとは1ヶ月間有給消化

プリ☆チャンMAPを作ってみた

公式HPの あそべるお店 には住所しか載っていなくて不便なので自分用に作りました *1

drive.google.com

https://drive.google.com/open?id=1e16bKjf_dOTkHEmZLZCqVTTHlVIr3f5l

やってること

詳細は省きますが、店舗リストをスプレッドシートに投入してGoogleマイマップにインポートしているだけです

こんな感じでスプレッドシートを作っておけばいい感じに地図に表示できて便利

f:id:sue445:20180701192554p:plain

マイマップは1レイヤ辺り2000件までしか登録できないので、地区ごとにレイヤーを分けています。(都道府県単位でレイヤーを分けると今度はインポートが不便)

f:id:sue445:20180701192712p:plain

良かったこと

  • データだけ用意しておけば雑に地図を表示できる
    • jsや公開先のサーバいらず
  • 通常Googleマップに表示する時は緯度経度の情報が必要だが、住所だけで地図に表示できる
    • ジオコーディングいらず

苦労したこと

  • GoogleマイマップにはAPIがない
  • インポート元のスプレッドシートが更新されてもマイマップは 更新されない
    • てっきり同期されてるもんだと思っていたら、再反映時は都度レイヤー削除&インポートが必要っぽい
  • スプレッドシートは1枚目のシートしかインポートしてくれない
    • 最初は1枚のスプレッドシートに対して地区(レイヤ)ごとにシートを分けていたんですが、それだと一番左のシートしか登録できなかったので各地区ごとにスプレッドシートを作るようにしました
  • 公式HPに載ってる住所が一部おかしくてそのままインポートするとエラーになる
    • 2000件中20件くらいがエラーになったので手で直しています(´・ω・`)

*1:ソースは非公開です

Trelloで散財リストを管理する

タスク管理ツールとして有名な Trello を散財リストとして運用している知見の紹介です。

僕の散財リスト

百聞は一見にしかずということで僕の散財リストを晒し。

f:id:sue445:20180626234629p:plain

リスト

購入予定

Twitterで買いたいものの新作情報が流れてきたら購入予定リストにカードを追加します。

f:id:sue445:20180626235028p:plain

カードの期限のところに僕は商品の発売日を入力しています。

この時言語設定がEnglishだと日付が分かりづらいので日本語推奨。

Englishだと MM/DD/YYYY

f:id:sue445:20180626235310p:plain

日本語だと YYYY/MM/DD

f:id:sue445:20180626235144p:plain

発売日(期限)順にソートできて便利。

f:id:sue445:20180626235558p:plain

予約済

実際にAmazonとかで予約したらカードを移動します。

f:id:sue445:20180626235748p:plain

「購入予定」と「予約済」でリストがわかれているのは、Twitterとかで情報が出た時点では予約が始まってないことがあるので予約することを忘れないためです。

どのサイトで予約したかをラベルにしとくとAmazonで予約したことを忘れて楽天で再度予約したりすることがなくていいかもしれないですね。*1

f:id:sue445:20180626235810p:plain

購入済

実際に購入したらカードを移動します。

まとめ

一番古いカードを見たら2014年11月だったのでだいたい3年半くらいTrelloで散財リストを運用しているようです。

f:id:sue445:20180627000428p:plain

Trelloを使う前はEvernote辺りを使ってたと思うのですが、予約済なのか購入済なのかのステータス管理が面倒でした。

Trelloを使うことでステータス管理できるようになって効率よくプリキュアに散財できるようになりました

*1:僕はラベル付けることをよく忘れてますが

プリパラを全話見た

きっかけ

4月の新番組の キラッとプリ☆チャン を見始める

www.tv-tokyo.co.jp

  ↓

5月頃映画が上映されたのでなんとなく見に行く

pp-movie.com

  ↓

入場者特典が欲しいので3周鑑賞

  ↓

映画の元ネタを知るためにプリパラ全話視聴

キュアエンジニアがプリパラにハマっていく流れ

1st season

anime.dmkt-sp.jp

anime.dmkt-sp.jp

anime.dmkt-sp.jp

ちなみにこの辺はRubyKaigiの宿でPR書きながら見てたと思います。

2nd season

anime.dmkt-sp.jp

(上記ツイートはブラジルじゃなくてメキシコの勘違い)

anime.dmkt-sp.jp

3rd season

anime.dmkt-sp.jp

anime.dmkt-sp.jp

アイドルタイム

anime.dmkt-sp.jp

anime.dmkt-sp.jp

余談

初めて見たプリキュアの映画がオールスターズNewStageで当時まともに見てたのはスイートとスマイルだけでしたが、その後過去作品全話視聴しています

参考

sue445.hatenablog.com

この後の予定

プリリズとキンプリを見ていこうと思います。

追記

一番好きなユニットはガァルマゲドンです

本を売った

近々引っ越しをする予定があって、引越し前に荷物の整理をしたくて物理本をほぼ全部売ったのでその時のメモ。*1

漫画・ラノベ

まんだらけの宅配買取を利用

ekizo.mandarake.co.jp

詳しい冊数は数えてないけどダンボール2箱でたぶん100冊前後。買取金額は4720円也

ただし発払いで送料(3000円ちょい)をこっちが負担したので、実質的な利益は1000円ちょい。いやまぁ、荷物を減らすことが目的だったんで金額はそんなに気にしてないんですが。

技術書

電脳書房 の宅配買取を利用。

www.bookcyber.net

ここをチョイスしたのは以前知り合いのブログで読んで名前を覚えていたため。

yoonchulkoh.hatenablog.com

目録作るのが手間だったけど10冊ごとに買取金額500円アップはデカイ。

最終的に80冊で12000円(前述の事前見積りボーナス込みで16000円)で買い取ってもらえましたが特筆すべき点は着払いで先方が送料負担してくれたこと。こっちもダンボール2箱だったけどもし発払いだったら3000円くらい減ってたところだった。ありがたい

目録をメールで送って何回かやり取りしていく中でゆうパックの着払いで送ってくれって言われたのですが、発送元の場所やダンボールの数によっては発払いになるのかもしれない。

目録をメールで送った段階で「買取金額は最大このくらいだけど本の状態によっては金額が下がります」って言われてたのでちょっと心配してたんだけど、表紙の日焼けくらいは特に問題なく12000円で買い取りしてもらえた。(タバコの臭いがついていると買い取り金額が大きく下がるとのこと)

*1:「ほぼ」と書いているのはサイン本やプリキュア関係の書籍だけ手元に残しているため

padrinoにPRを送った

padrino アプリでactiverecordを5.1系から5.2.0に上げようとしたら rake ar:migrate でエラーになったので直した

エラー内容

activerecord 5.2系からは ActiveRecord::Migrator.migrate がなくなったとのこと。めちょっく!

$ bundle exec rake ar:migrate:reset --trace
** Invoke ar:migrate:reset (first_time)
** Invoke ar:drop (first_time)
** Invoke skeleton (first_time)
** Execute skeleton
** Execute ar:drop
** Invoke ar:create (first_time)
** Invoke skeleton
** Execute ar:create
** Invoke ar:migrate (first_time)
** Invoke skeleton
** Execute ar:migrate
rake aborted!
NoMethodError: undefined method `migrate' for ActiveRecord::Migrator:Class
/app/vendor/bundle/ruby/2.5.0/gems/padrino-gen-0.14.3/lib/padrino-gen/padrino-tasks/activerecord.rb:127:in `block (2 levels) in <top (required)>'
/app/vendor/bundle/ruby/2.5.0/gems/rake-12.3.1/lib/rake/task.rb:271:in `block in execute'
/app/vendor/bundle/ruby/2.5.0/gems/rake-12.3.1/lib/rake/task.rb:271:in `each'
/app/vendor/bundle/ruby/2.5.0/gems/rake-12.3.1/lib/rake/task.rb:271:in `execute'
/app/vendor/bundle/ruby/2.5.0/gems/rake-12.3.1/lib/rake/task.rb:213:in `block in invoke_with_call_chain'
/Users/sue445/.rbenv/versions/2.5.1/lib/ruby/2.5.0/monitor.rb:226:in `mon_synchronize'
/app/vendor/bundle/ruby/2.5.0/gems/rake-12.3.1/lib/rake/task.rb:193:in `invoke_with_call_chain'
/app/vendor/bundle/ruby/2.5.0/gems/rake-12.3.1/lib/rake/task.rb:237:in `block in invoke_prerequisites'
/app/vendor/bundle/ruby/2.5.0/gems/rake-12.3.1/lib/rake/task.rb:235:in `each'
/app/vendor/bundle/ruby/2.5.0/gems/rake-12.3.1/lib/rake/task.rb:235:in `invoke_prerequisites'
/app/vendor/bundle/ruby/2.5.0/gems/rake-12.3.1/lib/rake/task.rb:212:in `block in invoke_with_call_chain'
/Users/sue445/.rbenv/versions/2.5.1/lib/ruby/2.5.0/monitor.rb:226:in `mon_synchronize'
/app/vendor/bundle/ruby/2.5.0/gems/rake-12.3.1/lib/rake/task.rb:193:in `invoke_with_call_chain'
/app/vendor/bundle/ruby/2.5.0/gems/rake-12.3.1/lib/rake/task.rb:182:in `invoke'
/app/vendor/bundle/ruby/2.5.0/gems/rake-12.3.1/lib/rake/application.rb:160:in `invoke_task'
/app/vendor/bundle/ruby/2.5.0/gems/rake-12.3.1/lib/rake/application.rb:116:in `block (2 levels) in top_level'
/app/vendor/bundle/ruby/2.5.0/gems/rake-12.3.1/lib/rake/application.rb:116:in `each'
/app/vendor/bundle/ruby/2.5.0/gems/rake-12.3.1/lib/rake/application.rb:116:in `block in top_level'
/app/vendor/bundle/ruby/2.5.0/gems/rake-12.3.1/lib/rake/application.rb:125:in `run_with_threads'
/app/vendor/bundle/ruby/2.5.0/gems/rake-12.3.1/lib/rake/application.rb:110:in `top_level'
/app/vendor/bundle/ruby/2.5.0/gems/rake-12.3.1/lib/rake/application.rb:83:in `block in run'
/app/vendor/bundle/ruby/2.5.0/gems/rake-12.3.1/lib/rake/application.rb:186:in `standard_exception_handling'
/app/vendor/bundle/ruby/2.5.0/gems/rake-12.3.1/lib/rake/application.rb:80:in `run'
/app/vendor/bundle/ruby/2.5.0/gems/rake-12.3.1/exe/rake:27:in `<top (required)>'
/app/vendor/bundle/ruby/2.5.0/bin/rake:23:in `load'
/app/vendor/bundle/ruby/2.5.0/bin/rake:23:in `<top (required)>'
/Users/sue445/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/cli/exec.rb:75:in `load'
/Users/sue445/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/cli/exec.rb:75:in `kernel_load'
/Users/sue445/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/cli/exec.rb:28:in `run'
/Users/sue445/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/cli.rb:424:in `exec'
/Users/sue445/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/Users/sue445/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/vendor/thor/lib/thor/invocation.rb:126:in `invoke_command'
/Users/sue445/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/vendor/thor/lib/thor.rb:387:in `dispatch'
/Users/sue445/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/cli.rb:27:in `dispatch'
/Users/sue445/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/vendor/thor/lib/thor/base.rb:466:in `start'
/Users/sue445/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/cli.rb:18:in `start'
/Users/sue445/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/exe/bundle:30:in `block in <top (required)>'
/Users/sue445/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/friendly_errors.rb:122:in `with_friendly_errors'
/Users/sue445/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/exe/bundle:22:in `<top (required)>'
/Users/sue445/.rbenv/versions/2.5.1/bin/bundle:23:in `load'
/Users/sue445/.rbenv/versions/2.5.1/bin/bundle:23:in `<main>'
Tasks: TOP => ar:migrate:reset => ar:migrate

修正内容

github.com

現時点でまだgemはリリースされてないのでpadrinoでactiverecord 5.2系使いたい場合はmasterブランチを要参照。

activerecordのメソッドを直接読んでRailsdb:migrate 相当のことを実現してるgemはたまにあるので、そういう場合はこれを参考に直せばいいと思います。