Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up
for free
歴史的経緯の説明 as code
FUJI Goro
September 27, 2018
Technology
7
2k
歴史的経緯の説明 as code
"歴史的経緯の説明 as code" であるところの querly の紹介です。
Code Review Meetup #4 (#codereview4) の発表資料です。
FUJI Goro
September 27, 2018
Tweet
Share
More Decks by FUJI Goro
See All by FUJI Goro
gfx
0
1.3k
gfx
3
1.7k
gfx
1
570
gfx
5
7.4k
gfx
20
7.6k
gfx
14
8.4k
gfx
1
3.5k
gfx
5
2.7k
gfx
21
13k
Other Decks in Technology
See All in Technology
1ftseabass
PRO
0
140
ks91
PRO
0
360
mathetake
2
150
brtriver
1
540
daisukehirama41
1
360
clustervr
PRO
0
180
supership
0
210
miyamotok
0
110
yuzoiwasaki
0
180
halhira
1
130
line_developers
PRO
2
400
hiyosi
0
120
Featured
See All Featured
keithpitt
402
20k
rmw
12
870
myddelton
109
11k
hursman
108
9.3k
colly
188
14k
jlugia
217
16k
morganepeng
95
14k
jakevdp
776
200k
michaelherold
226
8.7k
reverentgeek
28
2.1k
revolveconf
201
9.7k
lara
17
2.9k
Transcript
ྺ࢙తܦҢͷઆ໌ as code Code Review Meetup by Sider #4 2018/09/26
Presentation by FUJI Goro (@__gfx__)
ࣗݾհ • id:gfx • Bit JouruneyͰKibelaΛ։ൃ͍ͯ͠Δ • Kibela: ίϥϘϨʔγϣϯπʔϧ •
ࣾϒϩά & wiki ͱ͍͏SaaS • ࠷ۙͷؔ৺ࣄ DX: Developer Experience
ίʔυϨϏϡʔͱྺ࢙తܦҢ • ίʔυϨϏϡʔΔͱͯ͠ʮྺ࢙తͷઆ໌ʯͬͯ͋Γ·͢ΑͶ • ʮͦͷϝιου·ͩੜ͖ͯ·͕͢ݹ͍ͷͰΘͳ͍Ͱͩ͘͞ ͍ʯ • ʮͦͷgemґଘؔͷ߹্͑ͪΌ͍·͕͢ɺ͕͋Δ ͷͰΘͳ͍Ͱ͍ͩ͘͞ʯ •
ʮͦͷgemͷ͍ํͰ͕͢ɺϕετϓϥΫςΟε˓˓ͳͷͰ ै͍ͬͯͩ͘͞ʯ
ྺ࢙తܦҢͷઆ໌ as code ͱ • ྺ࢙తܦҢͷઆ໌͍͍ͩͨύλʔϯ͕͋Δ • ϓϩδΣΫτݻ༗ͷϕετϓϥΫςΟε • ৽چ༷͕ࠞࡏ͍ͯ͠Δաظͷա͝͠ํ
• ύλʔϯ͕͋ΔͳΒࣗಈԽ͢Ε͍͍͡Όͳ ͍ʂ⇢ “ྺ࢙త(ry as code”
ຊͷςʔϚ: Querlyʢ͑͘Γʙʣ • QuerlyίʔυϨϏϡʔͷࣗಈԽπʔϧͳ͕ Βɺ͍ํ͕গ͠Ή͔͍ͣ͠ • ͱ͍͏ΑΓɺ “Querly͕ఏڙ͢ΔՁ” ͕Θ͔ Γʹ͍͘
• ͦ͜ͰʮίʔυϨϏϡʔͷࣗಈԽͷͨΊʹ QuerlyΛ͏ʯͱ͍͏͜ͱΛओʹ͢
KibelaͱQuerlyͷ͖߹͍ • querly.ymlͷinitial commit 20169݄ • ࠷ॳ͍ॴ͕͍·͍ͪཧղͰ͖ͳ͔ͬͨ • ·͡Ίʹӡ༻͠͡Ίͨͷ 20176݄
• Querly meetup ʹग़ͯΑ͏͘ཧղ͠͡ΊΔ • 2018ʹͳ͔ͬͯΒසൟʹϧʔϧΛߋ৽͢ΔΑ͏ʹ • 2ோΊͯ “ྺ࢙త(ry as code” ͱ͍͏ཧղʹ౸ୡͨ͠
Querly: ྺ࢙త(ry as code • ύλʔϯԽ͍ͯ͠ΔͷࣗಈԽͰ͖Δ • ύλʔϯϚον⇢ܯࠂϝοηʔδͷग़ྗ ͱ͍ ͏λεΫΛ࣮ߦ͢Δͷ͕
querly(1) • QuerlyΛpull-requestͷมߋൣғʹݶఆ࣮ͯ͠ ߦͯ͘͠ΕΔSaaS͕SiderͰ͢
QuerlyͷϫʔΫϑϩʔ • `querly console [path…]` ͰconsoleΛ։͘ • `find $pattern` ͰύλʔϯϚον
• querly.yml ʹύλʔϯͱܯࠂจΛՃ • bad pattern͕ͳ͍߹ɺ࣮ࡍʹιʔεʹॻ ͍ͯ֬ೝ͢Δ
Demo
Querly DSL • Querlyจࣈྻʹର͢ΔύλʔϯϚονͰ ͳ͘ɺRuby AST ʹରͯ͠ύλʔϯϚονΛߦ ͏ • ͜ͷύλʔϯϚονDSLͳͷͰֶश͕ඞཁ
• ͦ͜Ͱquerly consoleͰࢼߦࡨޡ͢Δ
Querly DSL example (1) • foo • “foo” ͱ͍͏ϝιουݺͼग़͠ •
Ҿҙ • มจࣈྻɺγϯϘϧؚ·ͳ͍
Querly DSL example (2) • _ • ҙͷࣜʹϚον • foo(_)
ͩͱʮҙͷҾΛ1͚ͭͩ༩͑Δϝ ιουݺͼग़͠ʯͱ͍͏ҙຯ
Querly DSL example (3) • … • ҙͷҾϦετʹϚον • foo(…)
foo ͱಉ͡ɺͨͩ͠ෳࡶͳύλʔ ϯΛॻ͘ͱ͖…ͷ໌͕ࣔඞཁͳ͜ͱ͕͋ Δ
Querly DSL example (4) • foo(…){} • blockΛͱΔfooͷݺͼग़͠ʹϚον • …ඞਢ
• foo(…)!{} • blockΛͱΒͳ͍fooͷݺͼग़͠ʹϚον • …ඞਢ
Querly DSL examples (5) • [conditional], [!conditional] • `save [conditiona]`
Ͱʮ#save Λ݅ࣜͰධ Ձ͍ͯ͠Δͱ͖ʯʹϚον • `save [!conditional]` Ͱʮ#save Λ݅ࣜͰ ධՁ͍ͯ͠ͳ͍ͱ͖ʯʹϚον
Querly DSL syntax • ৄࡉϚχϡΞϧࢀরͷ͜ͱ • https://github.com/soutaro/querly/blob/ master/manual/patterns.md
ࣄྫ from kibela/querly.yml
ϝλϓϩͷ੍ - id: sample.metaprogramming_abuse pattern: - classify - constantize -
eval - instance_values - safe_constantize message: "本当にメタプログラミングが必要か3回 考えてください。" ※ 3ճߟ͑ͯҊ͕ͳ͍ͳΒͬͯΑ͍ɻͦ͏͍͑ send ܥ͜͜ʹՃ͍͑ͨɻ
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
ARͷenumͷ͍ํ - id: kibela.user_roles pattern: "User.roles[:symbol:]" message: "User.roles[:member] は多くの場合で必要 ありません。たとえばupdateやwhereではenum
symbolを 使えます。" ※ ੲARͷenumͷ͍ํ͕Θ͔ͬͯͳ͔ͬͨͷͰɻ༻Օ ॴ͕ଟ͍͏͑ʹࣗಈͰஔ͖͑ΒΕΔ΄ͲͰͳ͍ͷͰա ظҙשى͚ͩʹ͢Δ
localeͷࢀরͷ͔ͨ͠ - id: kibela.current_user_locale pattern: "current_user.locale" message: "current_userはログインしていない場合nil になります。 I18n.localeを使ってください。"
Raw SQLͷҙשى - id: kibela.order_by_string pattern: - "order(:dstr:)" - "where(:dstr:)"
- "find(:dstr:)" - "exists?(:dstr:)" message: "文字列によるSQL構築は本当に必要です か? SQL Injection を引き起こさないように気をつけ てください。"
block.callΛ͔͍ͭ·͠ΐ͏ - id: kibela.block_call pattern: - "yield" message: "yieldではなくblock.callを使いましょう。 そのほうが渡す引数が明確になります。"
developmentͰͷΈଘࡏ͢Δ ϝιουͷҙשى - id: kibela.yard_class_name pattern: "class_name()" message: "Class#class_name は
yard gem による拡 張なのでproductionでは使えません。必要なのはビルト インメソッドの Class#name ではないですか。"
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ຊମͰαϙʔτ͖͢Ͱͳ͍
چػೳΛͭͭ͠ҠߦΛଅ͢ - id: kibela.accessible_for pattern: "accessible_for(_)" message: "accessible_for(user) は古いメソッドで す。
readable_by(user) または manageable_by(user) を使ってください" justification: “互換性の確認のためtestでは一部 残っています。余裕があれば新しいメソッドに書き換え てください" ※ Kibela ACL v1 ͔Β ACL v2 ʹҠߦ͢Δʹ͋ͨͬͯΞΫη εݖݶܥΛΨόͬͱม͑Δʹ͋ͨΓɺʮچϝιουҰԠ ͕͢৽نίʔυͰ༻ېࢭʯͱ͍͏͜ͱʹ͔ͨͬͨ͠
FAQ
Linter ͱԿ͕ҧ͏ʁ • linter ʮҰൠతͳϧʔϧʯͷνΣοΫ • ͲͷϓϩδΣΫτɾͲͷϨϏϡΞʔͰಉ͡ࢦఠ Λ͢ΔͳΒlinterͷruleΛͭ͘Δ͖ • QuerlyʮϓϩδΣΫτݻ༗ͷϧʔϧʯͷνΣοΫ
• ଐਓԽ͕ͪ͠ͳʮྺ࢙తܦҢʯΛίʔυԽ͢Δ ͷ
ࢥͬͨͱ͓ΓʹϚον͠ͳ͍Αʁ • TwitterͰ࡞ऀʹฉ͘ͷ͕ૣ͍Ͱ͢ • ⇢ @soutaro • লུͰ͖ͦ͏ͳύλʔϯΛলུͰ͖ͳ͍͜ͱ ͕͋Γ·͢ (e.g.
◦: `foo(…){}` , ×: `foo{}`)
ޡݕ͕ଟ͗͢ΔΜͰ͕͢ʁ • Rubyʹܕ͕ͳ͍ͷͰ͠ΐ͏͕ͳ͍ΜͰ͢ • ޡݕ͕ଟ͍ͱ͍͏͜ͱϝιουͷ໋໊نଇ ʹҰ؏ੑ͕ͳ͍ͷ͔͠Ε·ͤΜɻ໋໊نଇΛ ݟ͢ͳͲͯ͠Έ·͠ΐ͏ • e.g. ಠࣗʹఆٛ͢Δ
update / update! ͳͲ ARͱৼΔ͍ΛҰகͤ͞Δ
ଞࣾͷࣄྫΛͬͱΓ͍ͨ • Θ͔Δ • ઃఆϓϩδΣΫτݻ༗ͳͷͰҰൠతʹ͢Δͷ Ͱͳ͍ • ͱ͍͑ൺֱతҰൠతͳϧʔϧͯ͠Αͦ͞͏ • `querly
init` ͱ͔ͰͦΕͳΓʹ͑ΔϨϕϧͷ querly.yml ͕ੜ͞Εͯ΄͍͠ؾ͢Δ
That’s it.