読者です 読者をやめる 読者になる 読者になる

酔いどれエンジニアのブログ

有限会社wisdomのスタッフブログです。主にプログラミングやアプリケーション開発の話題を書いていきます。

Rubyで作ったスクリプトをgem化して、一人でひっそりと使う方法

Rubyでスクリプトを書いていたんですが、色々なプロジェクトで使うので、非公開でgem化できないかと調べていました。

結果としては、ソースはprivate repositoryで管理して、gemはそのソースを元に作成することにしました。

以下はその手順です。

前提

既にスクリプトはRubyで作ってあるものとします。 便宜上、gem_testという名前のgemを作成することにします。 なお、名前に-(ハイフン)を入れると、そこで切られてしまいModule名やフォルダが分けられてしまいますので、お気をつけ下さい。

手順

gemプロジェクトのテンプレート作成

$ bundle gem gem_test

これによりgem_testフォルダ配下にファイルが作成されます。 これからの作業は全てgem_test配下で行います。

起動ファイルを配置

binフォルダを作りコマンドと同じ名前でrubyのスクリプトファイルを配置します。 たとえば、gem_test_startというコマンドで実行したい場合は、以下のようになります。

gem_test/bin/gem_test_start
gem_test/lib/gem_test.rb
gem_test/lib/gem_test/version.rb
gem_test/Gemfile
gem_test/LICENSE.txt
gem_test/gem_test.gemspec
gem_test/Rakefile
gem_test/README.md

Gemspecファイルを修正

gem_test/gem_test.gemspecを編集します。 最低限、下記の項目を書き換えておきましょう。 書き換えて置かないとgemファイル作成時にこけたり、警告されたりします。

  spec.description   = %q{<<適切な説明>>}
  spec.summary       = %q{<<適切な概要>>}
  spec.homepage      = "https://適切なURL"

次にコマンド名をexecutablesに設定します。 たとえば、、gem_test_startというコマンドで実行したい場合は、以下のように設定します。

spec.executables   = ['gem_test_start']

複数設定したい場合はカンマで区切ります。

spec.executables   = ['gem_test_start', 'gem_test_end']

起動ファイル以外のファイルを配置

起動ファイル以外のファイルはlib配下に配置します。 例えばinstall.rbstart.rbgem_test_startでrequireする場合は以下のようになります。

gem_test/bin/gem_test_start
gem_test/lib/gem_test.rb
gem_test/lib/gem_test/version.rb
gem_test/lib/gem_test/install.rb
gem_test/lib/gem_test/start.rb
gem_test/Gemfile
gem_test/LICENSE.txt
gem_test/gem_test.gemspec
gem_test/Rakefile
gem_test/README.md

requireのパスを変更

libがrequireの開始位置となりますので、それ以下のパスを指定します。 具体的には以下のように指定します。

require "gem_test/install"
require "gem_test/start"

新しく追加したファイルをgitに追加する

bundle gemした時点でgitのローカルリポジトリが作成され、初期ファイルは追加された状態になっています。 また、gemファイルを作る際にはgitに追加されいるファイルを、gemファイル内に含めるようになっています。

git add .

gemファイルを作成する

gem build gem_test.gemspec

gemファイルをインストールする

rake install

実行する

gem_test

最後に

以上で終了です。 gemに含めるファイルをgitに追加しましたが、gemspecファイルを書き換えることでgit以外にも対応可能です。 書き換え対象は以下の場所です。

  spec.files         = `git ls-files`.split($/)

またrequireの開始位置も以下の場所を変えることによって、変更可能です。

  spec.require_paths = ["lib"]