Slide 1

Slide 1 text

! ͷͭ͘Γ͔ͨ 2023 Omotesando.rb #89 2023/09/07 1

Slide 2

Slide 2 text

ࣗݾ঺հ • ໊લ: ਖ਼ಙ ޼(aka: ਆ଎) • ձࣾ: - • GitHub: @sinsoku (ը૾ӈ্) • Twitter: @sinsoku_listy (ը૾ӈԼ) • ޷͖ͳݴޠ: Rust • Railsྺ: 8೥͘Β͍ 2

Slide 3

Slide 3 text

࿩͢͜ͱ • ! Gemͷछྨ • " Gemͷ࢓૊Έ • # Gemͷ࡞Γํ 3

Slide 4

Slide 4 text

! Gemͷछྨ 4

Slide 5

Slide 5 text

Gemͷछྨ1 • CLIܥ • ศརϝιουܥ • Gemͷ֦ுܥ • Rails Engineܥ 1 ؆қతͳ෼ྨͰ͢ 5

Slide 6

Slide 6 text

CLIܥ CLIίϚϯυΛఏڙ͢Δɻ • rspec • rubocop • irb 6

Slide 7

Slide 7 text

ศརϝιουܥ ෳࡶͳॲཧΛ؆୯ʹѻ͏ͨΊͷϝιουΛఏڙ͢Δɻ • csv, json, yaml • pg, mysql2, sqlite3, redis • faraday, logger • octokit, aws-sdk 7

Slide 8

Slide 8 text

Gemͷ֦ுܥ طଘGemʹػೳΛ௥Ճͨ͠Γɺ2ͭͷGemΛ࿈ܞ͢Δɻ • stateful_enum • rspec-rails, rubocop-rspec 8

Slide 9

Slide 9 text

Rails Engineܥ RailsΞϓϦʹ؅ཧը໘2Λؙ͝ͱఏڙ͢Δɻ • Active Admin • ؅ཧը໘Λఏڙ͢Δ • Flipper • ػೳϑϥάͷ؅ཧը໘Λఏڙ͢Δ 2 Model, View, Controller, DBΛؚΊͨҰࣜ 9

Slide 10

Slide 10 text

! Gemͷ࢓૊Έ 10

Slide 11

Slide 11 text

GemͷσΟϨΫτϦߏ଄ ./ ├ exe/ │ └ foo # ࣮ߦϑΝΠϧʢCLIͷ৔߹ͷΈʣ ├ lib/ │ ├ foo.rb # ϝΠϯͷॲཧ │ └ foo/ │ └ version.rb # όʔδϣϯ └ foo.gemspec # ઃఆϑΝΠϧ 11

Slide 12

Slide 12 text

gemΛಡΈࠐΉ # example.rb require 'foo' puts Foo::VERSION #=> "0.1.0" ͜ΕͰ lib/foo.rb ΛಡΈࠐΊ·͢ɻ 12

Slide 13

Slide 13 text

BundlerͰಡΈࠐΉ Gemfile ʹॻ͍͓͚ͯ͹ɺBundler.require Ͱ·ͱΊͯಡΈࠐΉ͜ ͱ͕Ͱ͖Δɻ3 gem 'foo' # `lib/foo.rb` ΛಡΈࠐΉ gem 'foo', require: 'bar' # `lib/bar.rb` ΛಡΈࠐΉ gem 'foo', require: false # ࣗಈͰ͸ಡΈࠐ·Εͳ͍ 3 ීஈͷRailsΞϓϦͷ։ൃͰrequireΛॻ͔ͳ͍ͷ͸͜ͷͨΊ 13

Slide 14

Slide 14 text

ศརϝιουܥ ศརͳΫϥεΛఆ͓ٛͯ͠ ͘ɻ # lib/foo.rb module Foo class Omotesandorb # do something end end # ผϑΝΠϧͷΫϥεΛಡΈࠐΉ͜ͱ΋Մೳ require 'foo/api' ࢖͏ଆ͸͜Μͳײ͡ɻ # lib/example.rb require 'foo' obj = Foo::Omotesandorb.new 14

Slide 15

Slide 15 text

Gemͷ֦ுܥ ϞδϡʔϧΛ࡞੒͓͖ͯ͠ɺ ֦ு͍ͨ͠Ϋϥεʹinclude/ prepend͢Δέʔε͕ଟ͍ɻ # lib/foo.rb require 'active_record' module Foo module DefaultScopeWarning def default_scope(*) puts " ⚠ default_scope͸NG " super end end end ActiveRecord::Base.singleton_class .prepend(DefaultScopeWarning) 15

Slide 16

Slide 16 text

! Gemͷ࡞Γํ 16

Slide 17

Slide 17 text

Gemͷωλग़͠ • ͲΜͳ໰୊Λղܾ͢Δͷ͔ʁ ! • طଘͷgemͰղܾͰ͖ͳ͍͔ʁ ੈͷதʹཉ͍͠ ! ͕ແ͚Ε͹ɺ࡞ͬͯΈΑ͏ 17

Slide 18

Slide 18 text

Gemͷ໊෇͚ • ! ී௨: annotate, letter_opener, rspec, simple_form • pros: ػೳ໊ʹؔ࿈໊ͨ͠લͩͱ֮͑΍͍͢ • ✨ ΩϥΩϥωʔϜ: kaminari ⚡ , nokogiri , Hanami • pros: Ϟδϡʔϧ໊͕ඃΓʹ͍͘ 18

Slide 19

Slide 19 text

RubyGems.orgͰ໊લ͕ඃ͍ͬͯͳ͍͔ݕࡧ͢Δɻ4 4 gem info -r Ͱ΋ݕࡧͰ͖Δɻ 19

Slide 20

Slide 20 text

ॳظઃఆ 1. RubyGems.org ʹ৽نొ࿥ 2. BundlerʹGitHubͷϢʔβʔ໊Λઃఆ 20

Slide 21

Slide 21 text

RubyGems.org ʹ৽نొ࿥5 5 https://rubygems.org/sign_up 21

Slide 22

Slide 22 text

APIΩʔΛऔಘ͢Δ $ gem signin Enter your RubyGems.org credentials. Don't have an account yet? Create one at https://rubygems.org/sign_up Email: [email protected] Password: API Key name [MacBook-Pro.local-sinsoku-20230907163435]: Please select scopes you want to enable for the API key (y/n) index_rubygems [y/N]: y push_rubygem [y/N]: y yank_rubygem [y/N]: y add_owner [y/N]: N remove_owner [y/N]: N access_webhooks [y/N]: N show_dashboard [y/N]: N You have enabled multi-factor authentication. Please enter OTP code. Code: 012345 Signed in with API key: MacBook-Pro.local-sinsoku-20230907163435. 22

Slide 23

Slide 23 text

BundlerʹGitHubͷϢʔβʔ໊Λઃఆ6 ͸ࣗ෼ͷGitHubͷΞΧ΢ϯτʹมߋ࣮ͯ͠ߦ͠·͢ɻ $ bundle config set gem.github_username bundle gem ίϚϯυͰੜ੒ͨ͠READMEͰɺࣗಈతʹGitHubͷΞ Χ΢ϯτ໊͕࢖༻͞ΕΔɻ 6 https://github.com/rubygems/rubygems/pull/3687 23

Slide 24

Slide 24 text

͜ΕͰ ! Λ࡞Δ४උ͕׬ྃ 24

Slide 25

Slide 25 text

gem, bundler ΛΞοϓάϨʔυ bundle gem ίϚϯυΛ࣮ߦ͢ΔલʹΞοϓάϨʔυ͓ͯ͘͠ɻ7 $ gem update --system $ gem update bundler 7 ΞοϓάϨʔυ͸ඞਢͰ͸ͳ͍͕ɺͨ·ʹศརػೳ͕૿͑ͯͨΓ͢Δ 25

Slide 26

Slide 26 text

bundle gem ίϚϯυͰ਽ܗΛ࡞Δ ͸࡞Γ͍ͨgem໊ʹมߋ࣮ͯ͠ߦ͠·͢ɻ $ bundle gem CLIπʔϧΛ࡞Δ৔߹͸ --exe Λ͚ͭΔɻ $ bundle gem --exe 26

Slide 27

Slide 27 text

.gemspec Λमਖ਼͢Δ 1. TODO ΛؚΉจࣈྻΛमਖ਼ 2. allowed_push_host Λ https://rubygems.org ʹมߋ 3. metadata ͷuriΛGitHubʹ߹Θͤͯมߋ 27

Slide 28

Slide 28 text

GemΛϦϦʔε͢Δ 1. ػೳΛ࣮૷͢Δ • rake Λ࣮ߦͯ͠ɺςετΛ௚͢ 2. lib//version.rb Λߋ৽͢Δ8 3. ίϛοτͯ͠ɺGitHubʹϓογϡ͓ͯ͘͠ 4. rake release Λ࣮ߦ͢Δ 8 ࠷ॳͷϦϦʔεͰ͸ෆཁ 28

Slide 29

Slide 29 text

σϞ 29

Slide 30

Slide 30 text

30

Slide 31

Slide 31 text

--- sinsoku_hello.gemspec +++ sinsoku_hello.gemspec @@ -8,16 +8,14 @@ Gem::Specification.new do |spec| spec.authors = ["Takumi Shotoku"] spec.email = ["[email protected]"] - spec.summary = "TODO: Write a short summary, because RubyGems requires one." - spec.description = "TODO: Write a longer description or delete this line." - spec.homepage = "TODO: Put your gem's website or public repo URL here." + spec.summary = "Hello, RubyGems!" + spec.description = "This is a gem created for studying." + spec.homepage = "https://github.com/sinsoku/sinsoku_hello" spec.required_ruby_version = ">= 2.6.0" - spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'" - spec.metadata["homepage_uri"] = spec.homepage - spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here." - spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here." + spec.metadata["source_code_uri"] = "#{spec.homepage}/blob/v#{spec.version}/CHANGELOG.md" + spec.metadata["changelog_uri"] = "#{spec.homepage}/tree/v#{spec.version}" # Specify which files should be added to the gem when it is released. # The `git ls-files -z` loads the files in the RubyGem that have been added into git. 31

Slide 32

Slide 32 text

--- spec/sinsoku_hello_spec.rb +++ spec/sinsoku_hello_spec.rb @@ -4,8 +4,4 @@ RSpec.describe SinsokuHello do it "has a version number" do expect(SinsokuHello::VERSION).not_to be nil end - - it "does something useful" do - expect(false).to eq(true) - end end 32

Slide 33

Slide 33 text

! Λ࡞Δͷ͸؆୯ͳͷͰ ͥͻ࡞ͬͯΈ·͠ΐ͏ʂ 33