18
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

自作Gemに設定コマンドを導入する

Last updated at Posted at 2016-01-18

はじめに

 rubyのgemはthorを利用することで簡単にコマンドを作成することができる. コマンドをつける目的としては, なんらかの操作(APIを叩く,ファイル生成など)を自動化するというものが多いだろう.
 そういった操作には, しばしば入力が必要となるが, 毎回同じ入力をするのは非常にめんどくさい.
 そこで, 入力する情報や設定を保存し, それを利用する方法について書く. 具体的には, configコマンドを作成し, 設定を保存するとともに, 他のコマンドからその情報を利用してみる.

最終的にできあがるものは, 以下のようなものである.

$ bundle exec mygem config
Input your name: User name # User nameを入力
Update Your name to [User name].

$ bundle exec mygem hello 
Hello!, User name # 保存したデータを利用する

準備: gemの作成とhelloコマンドの作成

gemの準備

まずは、bundlerを利用してgemを作成する。

$ bundle gem mygem
$ cd mygem

mygem.gemspecのTODOとなっているところを編集する。また、thorをインクルードしておく。

./mygem.gemspec
  .
  .
  spec.summary       = %q{mygem}
  spec.description   = %q{mygem}
  spec.homepage      = "#githubのレポジトリなど"
  .
  .
  # thorを依存gemに追加
  spec.add_dependency "thor"
end

helloコマンドの作成

thorについて詳しくない方のために,
本題に入る前にHello!と出力するだけのhelloコマンドを作ってみる.
以下のようにファイルを準備する.

./lib/mygem/command/hello.rb
require 'mygem'
require 'mygem/command'

module Mygem
  class Command < Thor
    desc 'hello', 'say Hello!'
    def hello
      puts "Hello!"
    end
  end
end

./lib/mygem/command.rb
require 'mygem'
require 'thor'
require 'mygem/command/hello'

module Mygem
  class Command < Thor
  end
end

./lib/mygem.rb
require "mygem/version"
require "mygem/command"

module Mygem
end

gemの実行ファイルを作成する.

./mygem/exe/mygem
require 'mygem'
Mygem::Command.start

ビルド&インストール&実行する.

$ git add -A .
$ git commit -m 'init'
$ rake build
$ rake install
$ bundle install
$ bundle exec myconfig
Commands:
  mygem hello           # Say Hello!
  mygem help [COMMAND]  # Describe available commands or one specific command
$ bundle exec mygem hello
Hello!

これでmygemにhelloコマンドが追加された.

本題: configコマンドの作成と実行

 今回は,データの保存先をホームディレクトリ直下の, gem名の隠しディレクトリ以下とする.
つまり, ~/.mygem/settings.yml である.

ヘルパーメソッドの作成

 さて, configコマンドを作成するに当たり, やりたいことは以下の3つである.

  • コンフィグを設定する
  • コンフィグを保存する
  • コンフィグを取得する

 settings.ymlに対して上の3つを行うヘルパーメソッドを以下のように作成する.

./lib/mygem/helper/config_helper.rb
require 'fileutils'
require 'yaml'
require 'psych'

module Mygem
  # Configuration defaults
  @config = {
      name: 'default'
  }
  @valid_config_keys = @config.keys

  # Configure through hash
  def self.configure(opts = {})
    self.config
    opts.each do |k, v|
      @config[k.to_sym] = v if @valid_config_keys.include? k.to_sym
    end
    self.save_config
  end

  def self.get_config_path
    config_path = Dir.home + '/.mygem'
    if Dir.exists?(config_path)
      # use user settings
      config_path
    else
      raise "Can't find config directory. please init by command: 'mygem config'.'"
    end
  end

  # configをyamlから@cofigに取得
  def self.config
    yml_path = get_config_path + '/settings.yml'
    yml_file = YAML.load_file(yml_path)
    if yml_file
      @config = yml_file
    else
      File.open(yml_path, 'w') { |f| YAML.dump(@config, f) }
    end
  end

  # 現在の@configをyamlに保存
  def self.save_config
    yml_path = get_config_path + '/settings.yml'
    if File.exists?(yml_path)
      File.open(yml_path, 'w') { |f| YAML.dump(@config, f) }
    else
      raise "Can't find #{yml_path}. please set configure."
    end
  end
end

./lib/mygem.rb
require 'fileutils'
require 'yaml'
require 'psych'
require "mygem/version"
require "mygem/command"
require 'mygem/helper/config_helper' # 追加

module Mygem
end

config_helperでは, Mygem.configure(name: 'name')とした後で, save_configで現在のconfigをyamlに保存する.
そして, データが保存してあれば Myconfig.config[:name] でデータが取り出せるようになる.

configコマンドの作成

 configの設定, 保存, 参照ができるようになったので, いよいよconfigコマンドを作成する.
 configコマンドでやることは, 以下の3つである.

  • 初回起動時に設定ファイルを作成
  • 入力を受け付ける
  • 入力を設定として保存する

 これを以下のように実装する.

./mygem/lib/mygem/command/config.rb
require 'mygem'
require 'mygem/command'

module Mygem
  class Command < Thor
    desc 'config', 'change settings'
    def config
      # 初回起動時に設定ファイルを作成
      config_path = Dir.home + '/.mygem'
      if Dir.exists?(config_path)
        puts "Your current name is [#{Mygem.config[:name]}]."
      else
        Dir.mkdir(config_path)
        yml_path = Mygem.get_config_path + '/settings.yml '
        File.open(yml_path, 'w').close
      end

      # 入力を受け付ける
      print 'Input your name: '
      loop do
        s = $stdin.gets.chomp!
        if s.size != 0
          # 設定を更新
          Mygem.configure(name: s)
          break
        else
          puts 'Invalid Name. please try again:'
        end
      end
      puts "Update Your name to [#{Mygem.config[:name]}]."
    end
  end
end


./lib/myconfig/command.rb
require 'myconfig'
require 'thor'
require 'myconfig/command/hello'
require 'myconfig/command/config' # 追加

module Myconfig
  class Command < Thor
  end
end

設定を利用する

 これで自由にnameを設定できるようになったので, 最後にhelloを更新して設定を利用するようにする.

./mygem/lib/mygem/command/hello.rb
require 'mygem'
require 'mygem/command'

module Mygem
  class Command < Thor
    desc 'hello', 'call your name and say Hello!'
    def hello
      puts "Hello, #{Mygem.config[:name]}!"
    end
  end
end

以上で完成したので, ビルド&インストールして使ってみる.

$ rake build; rake install
$ bundle install
$ bundle exec mygem
Commands:
  mygem config          # Change settings
  mygem hello           # Call your name and say Hello!
  mygem help [COMMAND]  # Describe available commands or one specific command
$ bundle exec mygem hello
# 設定をしていないのでエラーが表示される
$ bundle exec mygem config                                                                                                                             
Input your name: Myname
Update Your name to [Myname].
$ bundle exec mygem hello
Hello!, Myname
$ bundle exec mygem config
Your current name is [Myname].  # 現在の設定が表示される
Input your name: New Name
Update Your name to [New Name]. # 設定を更新
$ bundle exec mygem hello
Hello!, New Name                # 新しい名前が表示される

保存されているファイルを見てみると, 以下のように保存されている.

~/.myconfig/settings.yml
---
:name: New Name

おわり

参考

今回作成したgem
https://github.com/keigo-brook/gem_myconfig

18
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?