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. ࣗݾ঺հ • ໊લ: ਖ਼ಙ ޼(aka: ਆ଎) • ձࣾ: - •

    GitHub: @sinsoku (ը૾ӈ্) • Twitter: @sinsoku_listy (ը૾ӈԼ) • ޷͖ͳݴޠ: Rust • Railsྺ: 8೥͘Β͍ 2
  2. Rails Engineܥ RailsΞϓϦʹ؅ཧը໘2Λؙ͝ͱఏڙ͢Δɻ • Active Admin • ؅ཧը໘Λఏڙ͢Δ • Flipper

    • ػೳϑϥάͷ؅ཧը໘Λఏڙ͢Δ 2 Model, View, Controller, DBΛؚΊͨҰࣜ 9
  3. GemͷσΟϨΫτϦߏ଄ ./ ├ exe/ │ └ foo # ࣮ߦϑΝΠϧʢCLIͷ৔߹ͷΈʣ ├

    lib/ │ ├ foo.rb # ϝΠϯͷॲཧ │ └ foo/ │ └ version.rb # όʔδϣϯ └ foo.gemspec # ઃఆϑΝΠϧ 11
  4. 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
  5. ศརϝιουܥ ศརͳΫϥεΛఆ͓ٛͯ͠ ͘ɻ # lib/foo.rb module Foo class Omotesandorb #

    do something end end # ผϑΝΠϧͷΫϥεΛಡΈࠐΉ͜ͱ΋Մೳ require 'foo/api' ࢖͏ଆ͸͜Μͳײ͡ɻ # lib/example.rb require 'foo' obj = Foo::Omotesandorb.new 14
  6. 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
  7. Gemͷ໊෇͚ • ! ී௨: annotate, letter_opener, rspec, simple_form • pros:

    ػೳ໊ʹؔ࿈໊ͨ͠લͩͱ֮͑΍͍͢ • ✨ ΩϥΩϥωʔϜ: kaminari ⚡ , nokogiri , Hanami • pros: Ϟδϡʔϧ໊͕ඃΓʹ͍͘ 18
  8. 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
  9. BundlerʹGitHubͷϢʔβʔ໊Λઃఆ6 <USERNAME> ͸ࣗ෼ͷGitHubͷΞΧ΢ϯτʹมߋ࣮ͯ͠ߦ͠·͢ɻ $ bundle config set gem.github_username <USERNAME> bundle

    gem ίϚϯυͰੜ੒ͨ͠READMEͰɺࣗಈతʹGitHubͷΞ Χ΢ϯτ໊͕࢖༻͞ΕΔɻ 6 https://github.com/rubygems/rubygems/pull/3687 23
  10. gem, bundler ΛΞοϓάϨʔυ bundle gem ίϚϯυΛ࣮ߦ͢ΔલʹΞοϓάϨʔυ͓ͯ͘͠ɻ7 $ gem update --system

    $ gem update bundler 7 ΞοϓάϨʔυ͸ඞਢͰ͸ͳ͍͕ɺͨ·ʹศརػೳ͕૿͑ͯͨΓ͢Δ 25
  11. GemΛϦϦʔε͢Δ 1. ػೳΛ࣮૷͢Δ • rake Λ࣮ߦͯ͠ɺςετΛ௚͢ 2. lib/<GEMNAME>/version.rb Λߋ৽͢Δ8 3.

    ίϛοτͯ͠ɺGitHubʹϓογϡ͓ͯ͘͠ 4. rake release Λ࣮ߦ͢Δ 8 ࠷ॳͷϦϦʔεͰ͸ෆཁ 28
  12. 30

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