Upgrade to Pro — share decks privately, control downloads, hide ads and more …

歴史的経緯の説明 as code

FUJI Goro
September 27, 2018

歴史的経緯の説明 as code

"歴史的経緯の説明 as code" であるところの querly の紹介です。

Code Review Meetup #4 (#codereview4) の発表資料です。

FUJI Goro

September 27, 2018
Tweet

More Decks by FUJI Goro

Other Decks in Technology

Transcript

  1. ྺ࢙తܦҢͷઆ໌
    as code
    Code Review Meetup by Sider #4
    2018/09/26
    Presentation by FUJI Goro (@__gfx__)

    View Slide

  2. ࣗݾ঺հ
    • id:gfx
    • Bit JouruneyͰKibelaΛ։ൃ͍ͯ͠Δ
    • Kibela: ίϥϘϨʔγϣϯπʔϧ
    • ࣾ಺ϒϩά & wiki ͱ͍͏SaaS
    • ࠷ۙͷؔ৺ࣄ͸ DX: Developer Experience

    View Slide

  3. ίʔυϨϏϡʔͱྺ࢙తܦҢ
    • ίʔυϨϏϡʔ͸΍Δͱͯ͠ʮྺ࢙తͷઆ໌ʯͬͯ͋Γ·͢ΑͶ
    • ʮͦͷϝιου͸·ͩੜ͖ͯ·͕͢ݹ͍ͷͰ࢖Θͳ͍Ͱͩ͘͞
    ͍ʯ
    • ʮͦͷgem͸ґଘؔ܎ͷ౎߹্࢖͑ͪΌ͍·͕͢ɺ໰୊͕͋Δ
    ͷͰ࢖Θͳ͍Ͱ͍ͩ͘͞ʯ
    • ʮͦͷgemͷ࢖͍ํͰ͕͢ɺϕετϓϥΫςΟε͸˓˓ͳͷͰ
    ै͍ͬͯͩ͘͞ʯ

    View Slide

  4. ྺ࢙తܦҢͷઆ໌ as code ͱ͸
    • ྺ࢙తܦҢͷઆ໌͸͍͍ͩͨύλʔϯ͕͋Δ
    • ϓϩδΣΫτݻ༗ͷϕετϓϥΫςΟε
    • ৽چ࢓༷͕ࠞࡏ͍ͯ͠Δա౉ظͷա͝͠ํ
    • ύλʔϯ͕͋ΔͳΒࣗಈԽ͢Ε͹͍͍͡Όͳ
    ͍ʂ⇢ “ྺ࢙త(ry as code”

    View Slide

  5. ຊ೔ͷςʔϚ: Querlyʢ͑͘Γʙʣ
    • Querly͸ίʔυϨϏϡʔͷࣗಈԽπʔϧͳ͕
    Βɺ࢖͍ํ͕গ͠Ή͔͍ͣ͠
    • ͱ͍͏ΑΓɺ “Querly͕ఏڙ͢ΔՁ஋” ͕Θ͔
    Γʹ͍͘
    • ͦ͜ͰʮίʔυϨϏϡʔͷࣗಈԽͷͨΊʹ
    QuerlyΛ࢖͏ʯͱ͍͏͜ͱΛओ୊ʹ࿩͢

    View Slide

  6. KibelaͱQuerlyͷ෇͖߹͍
    • querly.ymlͷinitial commit͸ 2016೥9݄
    • ࠷ॳ͸࢖͍ॴ͕͍·͍ͪཧղͰ͖ͳ͔ͬͨ
    • ·͡Ίʹӡ༻͠͸͡Ίͨͷ͸ 2017೥6݄
    • Querly meetup ʹग़ͯΑ͏΍͘ཧղ͠͸͡ΊΔ
    • 2018೥ʹͳ͔ͬͯΒසൟʹϧʔϧΛߋ৽͢ΔΑ͏ʹ
    • 2೥ோΊͯ “ྺ࢙త(ry as code” ͱ͍͏ཧղʹ౸ୡͨ͠

    View Slide

  7. Querly: ྺ࢙త(ry as code
    • ύλʔϯԽ͍ͯ͠Δ΋ͷ͸ࣗಈԽͰ͖Δ
    • ύλʔϯϚον⇢ܯࠂϝοηʔδͷग़ྗ ͱ͍
    ͏λεΫΛ࣮ߦ͢Δͷ͕ querly(1)
    • QuerlyΛpull-requestͷมߋൣғʹݶఆ࣮ͯ͠
    ߦͯ͘͠ΕΔSaaS͕SiderͰ͢

    View Slide

  8. QuerlyͷϫʔΫϑϩʔ
    • `querly console [path…]` ͰconsoleΛ։͘
    • `find $pattern` ͰύλʔϯϚον
    • querly.yml ʹύλʔϯͱܯࠂจΛ௥Ճ
    • bad pattern͕ͳ͍৔߹͸ɺ࣮ࡍʹιʔεʹॻ
    ͍ͯ֬ೝ͢Δ

    View Slide

  9. Demo

    View Slide

  10. Querly DSL
    • Querly͸จࣈྻʹର͢ΔύλʔϯϚονͰ͸
    ͳ͘ɺRuby AST ʹରͯ͠ύλʔϯϚονΛߦ
    ͏
    • ͜ͷύλʔϯϚον͸DSLͳͷͰֶश͕ඞཁ
    • ͦ͜Ͱquerly consoleͰࢼߦࡨޡ͢Δ

    View Slide

  11. Querly DSL example (1)
    • foo
    • “foo” ͱ͍͏ϝιουݺͼग़͠
    • Ҿ਺͸೚ҙ
    • ม਺΍จࣈྻɺγϯϘϧ͸ؚ·ͳ͍

    View Slide

  12. Querly DSL example (2)
    • _
    • ೚ҙͷࣜʹϚον
    • foo(_) ͩͱʮ೚ҙͷҾ਺Λ1͚ͭͩ༩͑Δϝ
    ιουݺͼग़͠ʯͱ͍͏ҙຯ

    View Slide

  13. Querly DSL example (3)
    • …
    • ೚ҙͷҾ਺ϦετʹϚον
    • foo(…) ͸ foo ͱಉ͡ɺͨͩ͠ෳࡶͳύλʔ
    ϯΛॻ͘ͱ͖͸…ͷ໌͕ࣔඞཁͳ͜ͱ͕͋
    Δ

    View Slide

  14. Querly DSL example (4)
    • foo(…){}
    • blockΛͱΔfooͷݺͼग़͠ʹϚον
    • …͸ඞਢ
    • foo(…)!{}
    • blockΛͱΒͳ͍fooͷݺͼग़͠ʹϚον
    • …͸ඞਢ

    View Slide

  15. Querly DSL examples (5)
    • [conditional], [!conditional]
    • `save [conditiona]` Ͱʮ#save Λ৚݅ࣜͰධ
    Ձ͍ͯ͠Δͱ͖ʯʹϚον
    • `save [!conditional]` Ͱʮ#save Λ৚݅ࣜͰ
    ධՁ͍ͯ͠ͳ͍ͱ͖ʯʹϚον

    View Slide

  16. Querly DSL syntax
    • ৄࡉ͸ϚχϡΞϧࢀরͷ͜ͱ
    • https://github.com/soutaro/querly/blob/
    master/manual/patterns.md

    View Slide

  17. ࣄྫ from kibela/querly.yml

    View Slide

  18. ϝλϓϩͷ཈੍
    - id: sample.metaprogramming_abuse
    pattern:
    - classify
    - constantize
    - eval
    - instance_values
    - safe_constantize
    message: "本当にメタプログラミングが必要か3回
    考えてください。"
    ※ 3ճߟ͑ͯ΋୅Ҋ͕ͳ͍ͳΒ࢖ͬͯ΋Α͍ɻͦ͏͍͑͹
    send ܥ΋͜͜ʹՃ͍͑ͨɻ

    View Slide

  19. migration ࣌ͷΧϥϜͷ࡟আ
    - id: kibela.remove_column
    pattern:
    - "remove_column"
    - "remove_reference"
    message: |
    カラムを削除する前に、該当カラムを使わないよう
    にした上で `ignore_colums` で無視するようにしてく
    ださい。
    参考文献: Rails アプリでオンラインでカラムの削
    除やリネームを行うには - eagletmt's blog http://
    eagletmt.hateblo.jp/entry/2017/09/24/004709

    View Slide

  20. ARͷenumͷ࢖͍ํ
    - id: kibela.user_roles
    pattern: "User.roles[:symbol:]"
    message: "User.roles[:member] は多くの場合で必要
    ありません。たとえばupdateやwhereではenum symbolを
    使えます。"
    ※ ੲ͸ARͷenumͷ࢖͍ํ͕Θ͔ͬͯͳ͔ͬͨͷͰɻ࢖༻Օ
    ॴ͕ଟ͍͏͑ʹࣗಈͰஔ͖׵͑ΒΕΔ΄ͲͰ΋ͳ͍ͷͰա౉
    ظ͸஫ҙשى͚ͩʹ͢Δ

    View Slide

  21. localeͷࢀরͷ͔ͨ͠
    - id: kibela.current_user_locale
    pattern: "current_user.locale"
    message: "current_userはログインしていない場合nil
    になります。 I18n.localeを使ってください。"

    View Slide

  22. Raw SQL΁ͷ஫ҙשى
    - id: kibela.order_by_string
    pattern:
    - "order(:dstr:)"
    - "where(:dstr:)"
    - "find(:dstr:)"
    - "exists?(:dstr:)"
    message: "文字列によるSQL構築は本当に必要です
    か? SQL Injection を引き起こさないように気をつけ
    てください。"

    View Slide

  23. block.callΛ͔͍ͭ·͠ΐ͏
    - id: kibela.block_call
    pattern:
    - "yield"
    message: "yieldではなくblock.callを使いましょう。
    そのほうが渡す引数が明確になります。"

    View Slide

  24. developmentͰͷΈଘࡏ͢Δ
    ϝιου΁ͷ஫ҙשى
    - id: kibela.yard_class_name
    pattern: "class_name()"
    message: "Class#class_name は yard gem による拡
    張なのでproductionでは使えません。必要なのはビルト
    インメソッドの Class#name ではないですか。"

    View Slide

  25. graphql-ruby ͷϕετϓϥΫ
    ςΟε
    - id: kibela.connection_type_without_resolver
    pattern: "field(:symbol:,
    _.connection_type, ..., !resolve: _, ...)"
    message: "Relay connection に resolver が設定さ
    れていません。 AR::Relation に対するconnectionは
    resolver でソートを指定すべきです。”
    ※ʮ field(:notes, Note.connection_type) Ͱ resolver option ͕ͳ
    ͍ύλʔϯʯͱಡΉɻසൃ͢Δϛεͳ͕Β΋ͱ΋ͱsortͯ͋͠Δ
    ͜ͱ΋͋ΔͷͰgraphql-rubyຊମͰαϙʔτ͢΂͖Ͱ΋ͳ͍

    View Slide

  26. چػೳΛ࢒ͭͭ͠ҠߦΛଅ͢
    - id: kibela.accessible_for
    pattern: "accessible_for(_)"
    message: "accessible_for(user) は古いメソッドで
    す。 readable_by(user) または manageable_by(user)
    を使ってください"
    justification: “互換性の確認のためtestでは一部
    残っています。余裕があれば新しいメソッドに書き換え
    てください"
    ※ Kibela ACL v1 ͔Β ACL v2 ʹҠߦ͢Δʹ͋ͨͬͯΞΫη
    εݖݶܥΛΨόͬͱม͑Δʹ͋ͨΓɺʮچϝιου͸ҰԠ࢒
    ͕͢৽نίʔυͰ͸࢖༻ېࢭʯͱ͍͏͜ͱʹ͔ͨͬͨ͠

    View Slide

  27. FAQ

    View Slide

  28. Linter ͱ͸Կ͕ҧ͏ʁ
    • linter ͸ʮҰൠతͳϧʔϧʯͷνΣοΫ
    • ͲͷϓϩδΣΫτɾͲͷϨϏϡΞʔͰ΋ಉ͡ࢦఠ
    Λ͢ΔͳΒlinterͷruleΛͭ͘Δ΂͖
    • Querly͸ʮϓϩδΣΫτݻ༗ͷϧʔϧʯͷνΣοΫ
    • ଐਓԽ͕ͪ͠ͳʮྺ࢙తܦҢʯΛίʔυԽ͢Δ΋
    ͷ

    View Slide

  29. ࢥͬͨͱ͓ΓʹϚον͠ͳ͍Αʁ
    • TwitterͰ࡞ऀʹฉ͘ͷ͕ૣ͍Ͱ͢
    • ⇢ @soutaro
    • লུͰ͖ͦ͏ͳύλʔϯΛলུͰ͖ͳ͍͜ͱ
    ͕͋Γ·͢ (e.g. ○: `foo(…){}` , ×: `foo{}`)

    View Slide

  30. ޡݕ஌͕ଟ͗͢ΔΜͰ͕͢ʁ
    • Rubyʹ͸ܕ͕ͳ͍ͷͰ͠ΐ͏͕ͳ͍ΜͰ͢
    • ޡݕ஌͕ଟ͍ͱ͍͏͜ͱ͸ϝιουͷ໋໊نଇ
    ʹҰ؏ੑ͕ͳ͍ͷ͔΋͠Ε·ͤΜɻ໋໊نଇΛ
    ݟ௚͢ͳͲͯ͠Έ·͠ΐ͏
    • e.g. ಠࣗʹఆٛ͢Δ update / update! ͳͲ͸
    ARͱৼΔ෣͍ΛҰகͤ͞Δ

    View Slide

  31. ଞࣾͷࣄྫΛ΋ͬͱ஌Γ͍ͨ
    • Θ͔Δ
    • ઃఆ͸ϓϩδΣΫτݻ༗ͳͷͰҰൠతʹ഑෍͢Δ΋ͷ
    Ͱ΋ͳ͍
    • ͱ͸͍͑ൺֱతҰൠతͳϧʔϧ͸഑෍ͯ͠΋Αͦ͞͏
    • `querly init` ͱ͔ͰͦΕͳΓʹ࢖͑ΔϨϕϧͷ
    querly.yml ͕ੜ੒͞Εͯ΄͍͠ؾ΋͢Δ

    View Slide

  32. That’s it.

    View Slide