🦁

HelloWorldするだけのgemを作る

2023/04/21に公開

何年もRuby on Railsを使っていながら、gemの構造などよく理解していなかったので、試しにHelloWorldするだけのgemを作ってみました。

作り方

1. RubyGemsのアカウントを作成

以下のページより、RubyGemsのアカウントを作成します。
https://rubygems.org/sign_up

2. gemの雛形を生成

ローカルにbundlerがない場合、インストールする

$ gem install bundler

d0ne1s_hello_worldという名前のgemの雛形を生成。gem名に-(ハイフン)を使うと、ディレクトリ構造などに影響が出てしまうので注意。

$ bundle gem d0ne1s_hello_world

コマンドを実行すると、色々聞かれます。とりあえず最小構成で作りたかったので、全てnoneとかnoとかで答えました。

# テストフレームワークは何を使うか
Do you want to generate tests with your gem?
Enter a test framework. rspec/minitest/test-unit/(none):none
# CIは何を使うか
Do you want to set up continuous integration for your gem?
Enter a CI service. github/gitlab/circle/(none):none
# MITライセンスにするか?(LICENSE.txtを生成するか?) yes/no
Do you want to license your code permissively under the MIT license?
y/(n):n
# Code of conduct(行動規範)を作るか yes/no
Do you want to include a code of conduct in gems you generate?
y/(n):n
# チェンジログのファイル(CHANGELOG.md)を生成するか?
Do you want to include a changelog?
y/(n):n
# Linterを使うか?
Do you want to add a code linter and formatter to your gem?
Enter a linter. rubocop/standard/(none):none

      create  d0ne1s_hello_world/Gemfile
      create  d0ne1s_hello_world/lib/d0ne1s_hello_world.rb
      create  d0ne1s_hello_world/lib/d0ne1s_hello_world/version.rb
      create  d0ne1s_hello_world/sig/d0ne1s_hello_world.rbs
      create  d0ne1s_hello_world/d0ne1s_hello_world.gemspec
      create  d0ne1s_hello_world/Rakefile
      create  d0ne1s_hello_world/README.md
      create  d0ne1s_hello_world/bin/console
      create  d0ne1s_hello_world/bin/setup
      create  d0ne1s_hello_world/.gitignore

答えた内容は、~/.bundle/configに記録され、次回以降は聞かれなくなります。
設定を変えたい場合は、このファイルを削除して再度プロンプトで質問されるようにするか、このファイルを直接編集します。

3. GitHubにリポジトリを作成

GitHub上で新規publicリポジトリを作成後、ローカルで以下のコマンドを実行

$ git remote add origin git@github.com:nyshk97/d0ne1s_hello_world.git
$ git branch -M main
$ git push -u origin main

4. gemspecを修正

summarydescriptionhomepageを設定。
allowed_push_hostsource_code_urichangelog_uriをコメントアウト。

d0ne1s_hello_world.gemspec
Gem::Specification.new do |spec|
  #...
  spec.summary = "HelloWorldするためのgemです。"
  spec.description = "Gemの構造を理解するために、HelloWorldするためのgemを作りました。"
  spec.homepage = "https://github.com/nyshk97/d0ne1s_hello_world"
  #...
  # 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."
  #...
end

5. 処理の中身を書く

"Hello World"と出力するだけのhelloメソッドを、lib/d0ne1s_hello_world.rbに書きます。

lib/d0ne1s_hello_world.rb
require_relative "d0ne1s_hello_world/version"

module D0ne1sHelloWorld
  class Error < StandardError; end
  # Your code goes here...
  def self.hello
    "Hello World"
  end
end

6. バージョンファイルを確認

lib/d0ne1s_hello_world/version.rb
module D0ne1sHelloWorld
  VERSION = "0.1.0"
end

初期バージョンなので、とりあえずこのまま。
バージョンを更新したい時などは、このファイルを編集する感じになりそうです。

7. gemのビルド

$ gem build d0ne1s_hello_world.gemspec

WARNING:  licenses is empty, but is recommended.  Use a license identifier from
http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.
WARNING:  See https://guides.rubygems.org/specification-reference/ for help
  Successfully built RubyGem
  Name: d0ne1s_hello_world
  Version: 0.1.0
  File: d0ne1s_hello_world-0.1.0.gem

d0ne1s_hello_world-0.1.0.gemというファイルが生成されます。

8. gemの公開

$ gem push d0ne1s_hello_world-0.1.0.gem
gem push d0ne1s_hello_world-0.1.0.gem
Enter your RubyGems.org credentials.
Don't have an account yet? Create one at https://rubygems.org/sign_up
   Email:   xxx@gmail.com
Password:   

Signed in with API key: xxxxxx.
Pushing gem to https://rubygems.org...
Successfully registered gem: d0ne1s_hello_world (0.1.0)

https://rubygems.org/gems/d0ne1s_hello_world
にアクセスすると、作ったgemがRubyGemsに公開されていることを確認できます。

作ったgemを使う

適当なRailsアプリを開いて、Gemfileを編集し、bundle install

Gemfile
gem 'd0ne1s_hello_world'
$ bundle install

rails consoleから、gemのメソッドを呼び出せることを確認しましょう。

$ rails console
irb(main):001:0> D0ne1sHelloWorld.hello
=> "Hello World"

gemを修正する

gemの内容を修正したい場合、gemを作る時のステップのうち、以下の部分を実行します。

  1. 処理の中身を書く
  2. バージョンファイルを確認(修正)
  3. gemのビルド
  4. gemの公開

shellでコマンドを実行できるようにする

実行ファイルを作成

$ touch bin/hello
$ chmod +x bin/hello
bin/hello
require_relative '../lib/d0ne1s_hello_world'

D0ne1sHelloWorld.hello_from_command_line

実行したい処理を作成

lib/d0ne1s_hello_world.rb
# ...
module D0ne1sHelloWorld
  # ...
  def self.hello_from_command_line
    puts "Hello from command line!"
  end
end

gemspecを修正

d0ne1s_hello_world.gemspec
Gem::Specification.new do |spec|
  # ...
-  spec.bindir = "exe"
-  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
+  spec.bindir = 'bin'
+  spec.executables = ['hello']
  # ...
end

その他

$ gem build d0ne1s_hello_world.gemspec

を実行した時に生成されるd0ne1s_hello_world-0.1.0.gemのようなファイルは、
ソースコードを元に生成でき、直接編集する必要もないファイルなので、gitに載せる必要がありません。

だからignoreしておくのが無難です。

.gitignore
*.gem

参考

今までは最後に参考にした記事を紹介していたのですが、今回は全部ChatGPTに言われるがままやってたらうまくいきました。
https://chat.openai.com/
用語とかちょこちょこググったけど、それも大体Googleの検索結果画面で返してくれました。
https://www.google.com/

Discussion