コードレビュー自動化の最前線から

 コードレビュー自動化の最前線から

Rails Developers Meetup 2018 https://railsdm.github.io/

1fab9d01b25e99522f3dfd01e3d4cb51?s=128

Soutaro Matsumoto

March 25, 2018
Tweet

Transcript

  1. ίʔυϨϏϡʔࣗಈԽͷ ࠷લઢ͔Β দຊफଠ࿠
 !TPVUBSP

  2. !TPVUBSP w দຊफଠ࿠ w 4JEF$*Λ։ൃ͍ͯ͠ΔʢޙͰ৮ΕΔʣ w 3VCZͷܕݕࠪثΛ࡞͍ͬͯΔʢࠓ೔͸৮Εͳ͍ʣ
 IUUQTHJUIVCDPNTPVUBSPTUFFQ

  3. ίʔυϨϏϡʔ͸೉͍͠

  4. None
  5. ίʔυϨϏϡʔͷ೉͠͞ w ΊΜͲ͍͘͞ w ͕͔͔࣌ؒΔ w ਓؒؔ܎ Ͱ͖Δ͚ͩػցʹ΍Β͍ͤͨ

  6. ίʔυϨϏϡʔͱ͸ w ໰୊ͷ͋ΔίʔυΛݟ͚ͭͯमਖ਼͢ΔΑ͏ʹ͓ئ͍͢Δ w ιϑτ΢ΣΞΛϝϯςφϯε͠΍͍͢ঢ়ଶʹอͭ w ෆ۩߹Λݟ͚ͭΔ

  7. ίʔυϨϏϡʔͷࣗಈԽ w ͳΜΒ͔ͷπʔϧͰɺ໰୊Λൃݟͯ͠։ൃऀʹमਖ਼Λଅ͢ w ࣗಈϨϏϡʔͰ͸શͯͷ໰୊ΛൃݟͰ͖ͳ͍ͷͰɺ࠷ऴత ʹ͸ਓ͕ؒ֬ೝ͢Δ w ໰୊ͷ૯ྔ͸มΘΒͳ͍͕ɺਓ͕ؒ֬ೝ͠ͳ͍ͱ͍͚ͳ ͍໰୊ͷྔ͕ݮΔ

  8. ίʔυͷ໰୊ w Ұൠతͳ໰୊ w ෆద੾ͳ໊લ w ෼ׂ͕ඞཁͳίʔυ w ௕͗͢Δߦ w

    ྑ͘ͳ͍ந৅Խ w ϓϩδΣΫτݻ༗ͷ໰୊
  9. ϓϩδΣΫτݻ༗ͷ໰୊ʢྫʣ

  10. ϓϩδΣΫτݻ༗ͷ໰୊ʢྫʣ

  11. ϓϩδΣΫτݻ༗ͷ໰୊ w ҰൠతͳϕετϓϥΫςΟεͱҰக͠ͳ͍͠ɺໃ६͢Δ͜ ͱ͢Β͋Δ w Ұൠతͳ໰୊Ͱ͸ͳ͍ͷͰɺϓϩδΣΫτʹ௕ؔ͘Θͬͯ ͍Δਓ͔͠஌Βͳ͍ w ద༻Ͱ͖Δൣғ͕ۃΊͯڱ͍

  12. ՝୊ w ։ൃΛԁ׈ʹਐΊΔͨΊͷϓϩδΣΫτݻ༗ͷϧʔϧ͸ɺ Ұൠతͳ-*/5πʔϧͰ͸ΧόʔͰ͖ͳ͍ w ϓϩδΣΫτͷ੒௕ʹͱ΋ͳͬͯେ͖ͳ໰୊ʹͳΔ w ৽͍͠ϝϯόʔ͕Ճೖͯ͠஍ཕΛ౿Ήճ਺͕૿͑Δ w Α͘஌Βͳ͍"1*ͷ਺͕૿͑Δ

  13. ղܾํ๏ w 3VCP$PQʹ13͢Δ w 3VCP$PQͷϓϥάΠϯΛ࡞Δ

  14. ͍΍͍΍͍΍ w Ұൠతͳϓϩάϥϛϯάͷ໰୊Ͱ͸ͳ͍ͷͰɺ13ͮ͠Β ͍ w ར༻ऀ͕ਓ͘Β͍͔͍͠ͳ͍ϓϥάΠϯͱ͔࡞Γͨ͘ͳ ͍͠ϝϯςφϯεͨ͘͠ͳ͍

  15. 3VCZϓϩάϥϛϯά͕೉͗͢͠Δ w ΄ͱΜͲͷ৔߹͸ಛఆͷ໊લͷࢀরΛݕग़Ͱ͖Ε͹ྑ͍ w ϓϩάϥϛϯά͠ͳ͍ͱղ͚ͳ͍໰୊Ͱ͸ͳ͍ͷʹɺ 3VCZͰॻ͘ͷ͸ແବͳίετ w ίετ͕ߴ͗͢ΔͷͰར༻ऀ਺͕े෼ʹଟ͘ͳ͍ͱ։ൃ ͍ͨ͠ؾ࣋ͪʹͳΒͳ͍

  16. ղܾํ๏ w ؆୯ʹϧʔϧΛ௥ՃͰ͖Δ-*/5πʔϧΛ։ൃ͢Δ w ݕ͍ࠪͨ͜͠ͱࣗମ͸؆୯ͳͷͰɺখ͞ͳݴޠΛ࡞Δ ͜ͱͰ3VCZϓϩάϥϛϯά͠ͳͯ͘΋ରԠͰ͖Δ w ؆୯ʹϧʔϧ͕௥ՃͰ͖ΔͷͰΈΜͳϓϩδΣΫτຖ ʹϧʔϧΛ͡ΌΜ͡ΌΜ௥Ճ͢Δʢ͸ͣʣ

  17. ਖ਼نදݱͱಉ͡ߏ଄ w ਖ਼نදݱ੍ݶ͞Εͨϓϩάϥϛϯάݴޠ w จࣈྻ͕͋Δੑ࣭Λຬ͔ͨ͢Ͳ͏͔ΛݕࠪͰ͖Δ w ʮϝʔϧΞυϨεͬΆ͍ײ͔͡Ͳ͏͔ʯ w ͳΜͰ΋Ͱ͖ΔΘ͚Ͱ͸ͳ͍͕ɺҰൠతͳϓϩάϥϛ ϯάݴޠΑΓ΋֮͑Δͷ͕؆୯

    w ਖ਼نදݱͰࡁΉ໰୊ͳΒɺਖ਼نදݱͰࡁ·ͤΔํָ͕ͳ ͜ͱ͕ଟ͍
  18. ࡞ͬͨ $ gem install querly IUUQTHJUIVCDPNTPVUBSPRVFSMZ

  19. rules:
 - id: com.sideci.env
 pattern: ENV
 message: |
 ؀ڥม਺Λ࢖͏ͱ͖͸ .env.sample

    ʹ
 αϯϓϧΛೖΕ͍ͯͩ͘͞
  20. rules:
 - id: com.sideci.env
 pattern: octokit()
 message: |
 octokit Ͱ͸ͳ͘ɺϦτϥΠͱ͔Λྑ͍ײ͡ʹ


    ΍ͬͯ͘ΕΔ with_octkit Λ࢖͍·͠ΐ͏
  21. ύλʔϯ w Ҿ਺Λ൐͏ϝιουݺͼग़͠
 has_many(_, class_name: _, !inverse_of: _, ...) w

    Ϩγʔόͷࢦఆ
 :string:.freeze() w ϒϩοΫͷ༗ແͷࢦఆ
 _.count() !{} w จ຺
 save(!validate: false) [!conditional]
  22. - id: com.sideci.link_to_with_method pattern: "link_to(..., method: _, ...)" message: |

    GETҎ֎ΛϦϯΫͰ࣮૷͠ͳ͍Ͱ͍ͩ͘͞ formΛ࢖͏͔ɺAjaxͰ໌ࣔతʹ࣮૷͠·͠ΐ͏ɻ
  23. - id: com.sideci.with_octokit pattern: - "with_octokit(_)" message: with_octokit ͸࢖༻ՄೳͳτʔΫϯΛ୳ͨ͢Ίɺ
 ౉͞ΕͨϒϩοΫΛϦτϥΠ͠·͢ɻ


    ϒϩοΫ͸ϦτϥΠ͞Εͯ΋ྑ͍Α͏ʹͳ͍ͬͯ·͔͢ʁ justification: - ϒϩοΫ͕ϦτϥΠ͞Εͯ΋໰୊ͳ͍Α͏ʹ࣮૷͞Ε͍ͯΔ৔߹
  24. - id: com.sideci.repository.full_name pattern: api_github_repository.full_name message: | GithubRepository#full_name Λ࢖͍·͠ΐ͏ examples:

    - before: repo.api_github_repository.full_name after: repo.full_name
  25. - id: com.sideci.remove_column pattern: - 'remove_column(:symbol:, ...)' message: | ෳ߹ΠϯσοΫε͕ઃఆ͞Ε͍ͯΔΧϥϜΛ࡟আ͢Δࡍʹ͸ɺ


    ઌʹΠϯσοΫεΛ࡟আ͢ΔΑ͏ʹ͍ͯͩ͘͠͞ examples: - before:
 "remove_column :organizations, :plan_id"
  26. - id: com.sideci.pusher pattern: Pusher.trigger message: | Pusher.triggerΛ௚઀࢖͏ͷΛ΍Ί·͠ΐ͏ `PusherNotification` ʹΠϕϯτΛఆٛͯ͠࢖͍·͠ΐ͏ɻ

    `PusherNotification.trigger` ͸ΤϥʔॲཧΛؚΜͰ͍·͢ɻ examples: - before:
 Pusher.trigger("#{user.id}", "reload-dashboard", {}) after: PusherNotification.new_repository_added(user)
  27. - id: com.sideci.use_pluck pattern: "all.map(&:symbol:)" examples: - before: "Tool.all.map(&:id)" after:

    "Tool.pluck(:id)" message: |
 ActiveRecordͰ͸all.map(&:id)Λ͢ΔΑΓ
 pluck(:id)Λ࢖͏ํ͕ߴ଎Ͱ͢ɻ
  28. ࢖͍ಓ w มͳ"1*ͷ࢖͍ํΛ͍ͯͨ͠ΒࣤΔ w ʮTBWFͨ͠ΒฦΓ஋Λ֬ೝ͠Α͏ʯ w "1*Λ%FQSFDBUF͢Δ w ʮ0K͸΋͏࢖Θͳ͍Α͏ʹ͠·͠ΐ͏ʯ w

    "1*ʹؔ͢Δิ଍৘ใΛग़͢ w DPVOUͱTJ[Fͷҧ͍ w ʮXJUI@PDUPLJU͸ϦτϥΠ͢Δ͔ΒCMPDLͷத਎͸࠶࣮ߦ͞ Εͯ΋յΕͳ͍Α͏ʹͯ͠Ͷʯ
  29. ໾ʹཱͭͷʁ w গͳ͘ͱ΋4JEF$*ࣾ಺Ͱ͸࢖͍ͬͯΔ w ΈΜͳؾܰʹϧʔϧΛ௥Ճ͍ͯ͠Δ w 13ΛϨϏϡʔ͍ͯͯ͠܁Γฦ͠ʹؾ͍ͮͨΒ2VFSMZʹ ௥Ճ͢Δ w 13Λ࡞͍ͬͯͯɺͳʹ͔Λ%FQSFDBUF͍ͨ͠ͱ͖ʹ͸

    2VFSMZʹ௥Ճ͢Δ w ਫ਼౓͸ѱ͍͚Ͳɺؾʹ͠ͳ͍
  30. ਫ਼౓͕ѱ͍ w ໊લͰϚονϯά͍ͯ͠Δ͚ͩͳͷͰɺGBMTFQPTJUJWF͕ଟ͍ ˠҙਤ͞ΕͨσβΠϯ w ϧʔϧΛؾܰʹ௥ՃͰ͖Δ͜ͱͷํ͕େ੾ w ʮࡶʹϧʔϧΛ௥Ճͯ͠ɺࡶʹݕࠪ͢Δʯ w ϊΠζରࡦ͸ͦͷ্ͷϨΠϠͰؤுΔ

    w 13Ͱมߋͨ͠ͱ͜Ζ͚ͩΛදࣔͯ͠ઈର਺ΛݮΒ͢ w 044 SFWJFXEPH Ͱ΍Δ͔ɺۚͰԥΔ 4JEF$*
  31. sideci.com

  32. ·ͱΊ w ϓϩδΣΫτݻ༗ͷϧʔϧΛؾܰʹ௥Ճͯ͠ɺίʔυϨ ϏϡʔΛޮ཰Խ͠Α͏ w HFNJOTUBMMRVFSMZ w 2VFSMZΛ࢖͏ͳΒ4JEF$*ʢ3VCP$PQ΋࢖͑Δʂʣ w HFNΛ࡞Δͱ͖ʹ͸:PVUVCFSͱͷ໊લͷিಥʹ஫ҙ͢Δ