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

💎のつくりかた 2023 / How to make gems 2023

Takumi Shotoku
September 07, 2023

💎のつくりかた 2023 / How to make gems 2023

Takumi Shotoku

September 07, 2023
Tweet

More Decks by Takumi Shotoku

Other Decks in Technology

Transcript

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

    View full-size slide

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

    View full-size slide

  3. ࿩͢͜ͱ

    !
    Gemͷछྨ

    "
    Gemͷ࢓૊Έ

    #
    Gemͷ࡞Γํ
    3

    View full-size slide

  4. !
    Gemͷछྨ
    4

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  10. !
    Gemͷ࢓૊Έ
    10

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  13. 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

    View full-size slide

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

    View full-size slide

  15. 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

    View full-size slide

  16. !
    Gemͷ࡞Γํ
    16

    View full-size slide

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

    View full-size slide

  18. Gemͷ໊෇͚

    !
    ී௨: annotate, letter_opener, rspec, simple_form
    • pros: ػೳ໊ʹؔ࿈໊ͨ͠લͩͱ֮͑΍͍͢


    ΩϥΩϥωʔϜ: kaminari

    , nokogiri , Hanami
    • pros: Ϟδϡʔϧ໊͕ඃΓʹ͍͘
    18

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  22. 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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  29. --- 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

    View full-size slide

  30. --- 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

    View full-size slide

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

    View full-size slide