株式会社はてなに入社しました
rubicure v1.0.0リリースノート
rubicure (1.0.0): All about Japanese battle heroine "Pretty Cure (Precure)". https://t.co/pfuO7MMTOn
— RubyGems (@rubygems) 2017年3月12日
rubicureのこれまでとこれから - くりにっき でも書きましたが、大幅に変更が入っています!
詳しいことはCHANGELOGを読んで下さい https://github.com/sue445/rubicure/blob/master/CHANGELOG.md#v100
破壊的変更
長らくdeprecatedにしていたhumanizeメソッドを削除
humanize!
を使ってください
Ruby 2.2.2以上必須にした
activesupport 5系との兼ね合いで2.2.2以上必須にしています
Ruby 2.2.2未満の時はGemfile側でactivesupport 4系を使ってもらうという選択肢(ドキュメントで補完)というのもあったのですが、どうせドキュメントなんて読まないだろうし「Ruby 2.1系でbundle installに失敗する」というissueに対して質問返すのも不毛なのでこの機会にバッサリ古いRubyのサポートを切りました。
キュアプリンセスの人間の時の名前を変更
後述の Girl#full_name
メソッドとの兼ね合いで変更しました
- 変更前:白雪ひめ(ヒメルダ・ウインドウ・キュアクイーン・オブ・ザ・ブルースカイ)
- 変更後:白雪ひめ
Precure.all_starsメソッドの振る舞いを変更
既存コードの改修が必要という点ではこれが一番大きい変更です
今まで Precure.all_stars
は基本的に全てのプリキュアを返していましたが、v1.0.0以降は初代〜魔法つかいプリキュアまでしか返さないようになりました。*1
これは、プリキュアオールスターズ が終わって プリキュアドリームスターズ! が始まったためです。
全てのプリキュアを取得したい場合は後述の Precure.all_girls
か Precure.all
を使ってください。
機能追加
Girl#full_nameを追加
白雪ひめやトワ様のように人間界の名前とは別に自国での名前が存在する場合があるので取得できるようにしました
Cure.princess.human_name => "白雪ひめ" Cure.princess.full_name => "ヒメルダ・ウインドウ・キュアクイーン・オブ・ザ・ブルースカイ" Cure.scarlet.human_name => "紅城トワ" Cure.scarlet.full_name => "プリンセス・ホープ・ディライト・トワ"
別名がないキャラで full_name
を使った場合は human_name
(通常の人間時の名前)が返ります
Cure.miracle.human_name => "朝日奈みらい" Cure.miracle.full_name => "朝日奈みらい"
Precure.all_girls を追加
Precure.all_stars
が全てのプリキュアを返さなくなったため、代わりに all_girls
が返ります。
all_girls
と違ってデフォルトでキュアエコーが含まれます
Precure.all
もエイリアスとして存在しているので好みに応じて使ってください
キラキラ☆プリキュアアラモードを追加
Precure.a_la_mode
Precure.alamode
Precure.kirakira_precure_a_la_mode
Precure.kirakira_precure_alamode
のいずれかで取得できます。
Precure.a_la_mode #=> {:series_name=>"a_la_mode", :title=>"キラキラ☆プリキュアアラモード", :started_date=>Sun, 05 Feb 2017, :girls=>["cure_whip", "cure_custard", "cure_gelato", "cure_macaroon", "cure_chocolat"]} Precure.a_la_mode.girls.map(&:precure_name) #=> ["キュアホイップ", "キュアカスタード", "キュアジェラート", "キュアマカロン", "キュアショコラ"]
余談ですが今期の嫁はキュアカスタードです
Precure.dream_starsを追加
映画プリキュアドリームスターズ! に登場する Go!プリンセスプリキュア 、魔法つかいプリキュア! キラキラ☆プリキュアアラモード のプリキュアが返ります
Precure.dream_stars.map(&:precure_name) #=> ["キュアフローラ", "キュアマーメイド", "キュアトゥインクル", "キュアスカーレット", "キュアミラクル", "キュアマジカル", "キュアフェリーチェ", "キュアホイップ", "キュアカスタード", "キュアジェラート", "キュアマカロン", "キュアショコラ"]
余談
正式リリース前のバージョンのpreは、プレビュー(preview)の pre とプリキュア(precure)の pre の両方にかかっています
https://rubygems.org/gems/rubicure/versions
勉強会のスライドにもマンガルーが使えそう
tl;dr
HTMLにマンガルーのタグを埋め込む形式であれば勉強会のスライドにも利用可能
マンガルーとは?
マンガのコマをwebサイトやSNSに貼り付けることができるサービスです
このサイトのすごいところは「権利者より正式に許諾を受けた作品」を使えるということです
ある予感がしてFAQを読んでみた
http://mangaloo.jp/info/faq.html
コマをSNSにシェアするにはどうすればよいですか?
「コマをつくる」のコマの範囲確定後、または「コマをさがす」でコマをクリックした際に出るポップアップから、下図赤丸の「共有URL」をコピーしてSNSにはりつけてください。twitterやfacebookなどのOGP(リンクからの画像表示機能)に対応しているSNSであれば、コマをタイムラインに表示することができます。
マンガ画像を保存して使いたいのですが
申し訳ありません。コマは埋め込みもしくは共有用URLでのご利用のみ可能です。 ダウンロードやスクリーンショットなどで保存、利用することは禁止させていただいております。
パワポやpdfへの画像埋め込みはアウツだけど、HTML形式のスライドならマンガルー使っても大丈夫ではという気づき
マンガルーの利用規約確認したけど、これだとパワポやpdfへの画像埋め込みはダメだけどhtmlでwebに公開するタイプの勉強会のスライドなら広義の意味でwebサイトということで大丈夫な予感があるな。(後で問い合わせてみる)https://t.co/inwClQ3III pic.twitter.com/xVsYLNNOCC
— sue445 (@sue445) 2017年2月28日
実際に問い合わせてみた
問い合わせたメール
こんにちは。FAQを読むとwebサイトやブログに貼り付けることを想定しているようですが、HTMLにマンガルーのタグを埋め込む方式であれば公開先は何でもいいのでしょうか? 私は勉強会で発表するためのプレゼンスライドをHTMLで書いてwebに公開しているのですが、そのような場合でもマンガルーが使えるかどうか気にしています。具体的には http://sue445.github.io/omotesandorb-10/ のような形式のスライドにマンガルーのタグをHTMLとして埋め込んで使うことを想定しています
返信メール *1
ご利用方法として問題なさそうなので
まとめ
勉強会のスライドにwebで拾ったマンガのコマを貼り付けるよりもこういうサービス使うのが健全ですね
*1:ブログでのメールのやり取りの公開は予め許可をもらってます
プリキュアの誕生日をGoogleカレンダーに登録する
あると便利そうだったのでキラッとひらめいて作りました。
概要
rubicure でプリキュアの誕生日を取得できるので、RubicureAPI でical形式で登録できるようにしてみました。
使い方
https://rubicure.herokuapp.com/ の一番下にあるicalのリンク( https://rubicure.herokuapp.com/girls/birthday.ics )をGoogleカレンダーに追加するだけです。
実際に登録してみた
こんな感じです。便利!
仕様
- 今年〜2年後まで登録できます
- 現在放映中のキラキラ☆プリキュアアラモードまで対応しています
- Googleカレンダー以外でもたぶん対応してます
ChatWork API v2への追従について
下記でChatWork APIのバージョンアップがアナウンスされています
既にv2はリリースされていてv1は5月上旬に停止予定とのことなので早めにアップデートしておくのがいいでしょう
とのことで、自分の視界に入っている限りでのv2対応状況について紹介します
既存のプログラムをv2対応する
既存プログラムの改修レベルでいえば
- エンドポイントをv1からv2にする
- 静的型付け言語であれば
message_id
の型をintegerからstringにする
だけで動きます。完全なv2 API対応にはコンタクト承認依頼APIにも対応する必要がありますが、「v1 API廃止後も既存のプログラムが問題なく動く」ということだけにターゲットを絞ればこの2つだけで十分かと。(以降「v2対応」はこの最低限の対応を指します)
他の人が作ったライブラリのv2対応状況
chatwork
Rubyで一番使われてそうなChatWorkクライアントのgem
https://github.com/asonas/chatwork-ruby/pull/14 でv2対応されているので、v0.4.0以降を使えばv2対応完了です
capistrano-chatwork, cha
capistrano-chatworkの中で使ってるクライアントgemがchaです。
chaとcapistrano-chatworkの両方でPR投げて取り込まれています。
cha v1.2.0以降とcapistrano-chatwork v1.4.0以降を使えばv2対応完了です。*1
go-chatwork
golang用のクライアント。本家 ではなくfork版の方です
https://github.com/griffin-stewie/go-chatwork/pull/8 でPRを投げて取り込まれているので go get -u github.com/griffin-stewie/go-chatwork
すればv2対応完了です。
拙作のChatWork系ツールのv2対応状況
Jenkins ChatWork Plugin
v1.0.8 でv2対応完了しています。余談ですがこの時送られてきたPRで初めてChatWork API v2のことを知りましたw
https://github.com/jenkinsci/chatwork-plugin/pull/34
zatsu_monitor
v0.2.2でv2対応しています
capistrano-around_chatwork
v0.1.1以降にアップデートすれば自動的にchatwork gemのv0.4.0以降(v2対応版)が入るようになってるのでそれでv2対応完了です
ただし capistrano-around_chatwork v0.1.1 と capistrano-chatwork を同時にインストールしようとするとバージョンがコンフリクトして bundle install
できないので capistrano-around_chatwork v0.2.0推奨
詳細: https://github.com/sue445/capistrano-around_chatwork/pull/2
fluent-plugin-chatwork
v1.0.1にアップデートすれば自動的にchatwork gemのv0.4.0以降(v2対応版)が入るようになってるのでそれでv2対応完了です
*1:capistrano-chatworkのPRを見てもらえれば分かりますが、chaだけだと依存の関係でbundle installできないのです
Travis CIでdepを使う
zatsu_monitor でdep対応をしたのでその時のメモ
depについて
depについては下記を参照
.travis.yml
必要最低限だとこんな感じ
language: go go: - 1.7 - tip before_install: - go get github.com/golang/dep/... install: - $GOPATH/bin/dep ensure script: - go test
depのREADMEに書いてるのを.travis.ymlに書いただけです。
.travis.ymlの完全版はこちら https://github.com/sue445/zatsu_monitor/blob/c265f1b9301c056cbac5006952270812c9155266/.travis.yml
注意点としては、Travis CIだと go get
しても $GOPATH/bin
にPATHが通らない *1 こと。
goveralls でもフルパスで書いてるのでそんなもんかなぁ。。。
あと、golang 1.6系だとdepがビルドできずにエラーになったので1.7以降必須。
https://travis-ci.org/sue445/zatsu_monitor/jobs/196138494
depをいれたメリット
依存するライブラリのバージョンを上げた時にそれがgitの履歴として残るのはいいですね。 https://github.com/sue445/zatsu_monitor/commit/cb1d7ab446e1a511844740f63d366d8a6a901c62
*1:明示的にPATHを通してもダメだった
rubocopでreversibleなmigrationかどうかチェックしたかったので作った
僕がrubocopに送ったPRが v0.47.0 に取り込まれました。
個人的に便利機能だと思うのでこの場を借りて軽く紹介したいと思います。
Rails/ReversibleMigrationについて
Railsのmigrationファイルで change
メソッドの中に書いたmigrationコマンドがreversible *1かどうかをチェックするためのcopです
具体例
https://github.com/bbatsov/rails-style-guide#reversible-migration より抜粋
これだと drop_table :users
だけだと逆方向のmigration(create_table
)でどのようなカラムでテーブルを作ればいいか分からないのでreversibleではありません。rake db:rollback
や rake db:migrate:down
した時にエラーになります。
# bad class DropUsers < ActiveRecord::Migration def change drop_table :users end end
こういう場合、upメソッドとdownメソッドでそれぞれmigrationを書いてあげないと rake db:rollback
や rake db:migrate:down
が正しく実行されません
# good class DropUsers < ActiveRecord::Migration def up drop_table :users end def down create_table :users do |t| t.string :name end end end
http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters.html#method-i-drop_table にも書いていますが、 drop_table
にブロックを渡すとchangeで逆方向のmigrationを補完する時に create_table
の引数扱いになりカラムが作られます。
# good # In this case, block will be used by create_table in rollback # http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters.html#method-i-drop_table class DropUsers < ActiveRecord::Migration def change drop_table :users do |t| t.string :name end end end
どうして作ったか?
慣れてくればreversibleなコマンドかどうかは Railsの気持ちになって考えれば だいたい推測はつきます。
例えば
add_column :users, :name, :string
の逆は
remove_column :users, :name
ですが、
remove_column :users, :name
の逆方向を考えた時にどんな型でカラムを作ればいいかの情報がこれだけでは推測できないのでreversibleじゃないといった感じです。
微妙に迷った時も全部 http://api.rubyonrails.org/classes/ActiveRecord/Migration/CommandRecorder.html に書いてあるのでこれを読めば分かります。
しかしコードレビューの度にそれをいちいち指摘するのは面倒なので自動化するために Rails/ReversibleMigration を作成しました。
検出精度について
さっきのリファレンスを全部読んだ上でchangeメソッド内の下記を検出するようにしています
- 絶対にreversibleじゃないmigrationコマンド
- change_table
- change_table_comment
- execute
- remove_belongs_to
- 特定の条件を満たさないとreversibleじゃないmigrationコマンド
- drop_table
- change_column_default
- remove_column
- remove_foreign_key
ただし特例として reversibleブロックがある場合は reversibleであるとみなして検出対象外にしています。
詳細は下記参照
auto correctについて
rubocopのcopでは autocorrect
メソッドを定義すればauto correct時の実装を定義することができますが、down(逆方向)のmigrationは過去のmigrationファイルを探して人間が書く必要がありそうな気がしたのであえて実装していません。
Cop開発Tips
次回以降自分がrubocop触りやすくするために開発手順とか参照すべきソースをメモっときます。
前提知識
日本語だとここが参考になりました。
rubocop静的解析したいソースをruby-parseでS式を出す
ruby_parser というRubyのソースコードを解析するためのgemを使います。rubocopのソースをcloneしていればbundle installで入るので別途gem installする必要はありません。
例えばこんなファイルを作っといて
class ExampleMigration < ActiveRecord::Migration def change # ブロックがあるのでreversible drop_table :users do |t| t.string :name end # ブロックがないのでrubocopで警告を出したい drop_table :users end end
ruby-parseに食わせてS式を出します。
bundle exec ruby-parse /tmp/migration.rb (class (const nil :ExampleMigration) (const (const nil :ActiveRecord) :Migration) (def :change (args) (begin (block (send nil :drop_table (sym :users)) (args (procarg0 :t)) (send (lvar :t) :string (sym :name))) (send nil :drop_table (sym :users)))))
rubocopのcopに on_def
や on_send
などのメソッドを定義することによって、rubocopで解析中にS式のその要素と対応するメソッドが実行されます。
今回の場合はメソッド呼び出し drop_table
や change_table
などのメソッド呼び出しをフックしたかったので on_sendメソッドを作りました。
binding.pryなどでとめてnodeの中身を確認
on系のメソッドに binding.pry
や binding.irb
を書いて
def on_send(node) binding.pry
任意のspecを実行
$ bundle exec rspec -- spec/rubocop/cop/rails/reversible_migration_spec.rb:85 Run options: include {:focus=>true, :locations=>{"./spec/rubocop/cop/rails/reversible_migration_spec.rb"=>[85]}} exclude {:broken=>#<Proc:./spec/spec_helper.rb:32>} Randomized with seed 63344 From: /Users/sue445/workspace/github.com/bbatsov/rubocop/lib/rubocop/cop/rails/reversible_migration.rb @ line 120 RuboCop::Cop::Rails::ReversibleMigration#on_send: 119: def on_send(node) => 120: binding.pry 121: return unless within_change_method?(node) 122: return if within_reversible_block?(node) 123: 124: check_irreversible_schema_statement_node(node) 125: check_drop_table_node(node) 126: check_change_column_default_node(node) 127: check_remove_column_node(node) 128: check_remove_foreign_key_node(node) 129: end [1] pry(#<RuboCop::Cop::Rails::ReversibleMigration>)> node => s(:send, nil, :drop_table, s(:sym, :users)) [2] pry(#<RuboCop::Cop::Rails::ReversibleMigration>)>
慣れていないうちは1回1回 binding.pry
で止めてnodeの中身を確認しつつデバッグしていくのがいいと思います。余談ですがデバッグに慣れていなさすぎて1日 1migrationコマンド対応が限界でした('A`)
S式にマッチさせるmatcherを書く
cop内に
def_node_matcher :drop_table_call, <<-END (send nil :drop_table ...) END
のようなmatcherを書くことによって、
drop_table_call(node) do # drop_table メソッドの呼び出しがあればこの中が評価される end
のように処理を挟むことができます。
matcherの書き方は https://github.com/bbatsov/rubocop/blob/master/lib/rubocop/node_pattern.rb のコメントを要熟読
matcherに $_
や $...
を書くことにより、マッチした文字列を変数として取得することもできます。
$_
は単一nodeを取得
# remove_foreign_keyに渡された引数の2つ目のみを取得するmatcher def_node_matcher :remove_foreign_key_call, <<-END (send nil :remove_foreign_key _ $_) END
remove_foreign_key_call(node) do |arg| # $_ の内容がブロック引数のargに入ってくる if arg.hash_type? # remove_foreign_keyの第2引数がHash(テーブル名以外)の時に警告を出す add_offense( node, :expression, format(MSG, 'remove_foreign_key(without table)') ) end end
$...
は以降のnodeを全部取得
# remove_columnに渡された引数を全部取得するmatcher def_node_matcher :remove_column_call, <<-END (send nil :remove_column $...) END
remove_column_call(node) do |args| # argsに引数全部入ってくる if args.to_a.size < 3 # 引数が3個未満の時に警告を出す add_offense( node, :expression, format(MSG, 'remove_column(without type)') ) end end
*1:rake db:rollback や rake db:migrate:down した時に逆方向のmigrationを自動補完する