高木のブログ

Thorを使ってCLIを作る時に書くおまじない

2022/01/12

Thor を使ってCLIを作る時に書かないといけないおまじないがある

以下のように引数が必要なサブコマンドを書いて、引数なしでコマンドを実行するとDeprecation warinigが出る

exe/sample
#!/usr/bin/env ruby

require 'thor'

module Sample
  class Cli < Thor
    desc 'hello NAME', 'say hello'
    def hello(name)
      puts "hello, #{name}"
    end
  end
end

Sample::Cli.start
$ bundle exec exe/sample hello
ERROR: "sample hello" was called with no arguments
Usage: "sample hello NAME"
Deprecation warning: Thor exit with status 0 on errors. To keep this behavior, you must define `exit_on_failure?` in `Sample::Cli`
You can silence deprecations warning by setting the environment variable THOR_SILENCE_DEPRECATION.

おまじない

true を返す exit_on_failure? メソッドを定義する

def self.exit_on_failure?
  true
end
exe/sample
 #!/usr/bin/env ruby

 require 'thor'

 module Sample
   class Cli < Thor
+    def self.exit_on_failure?
+      true
+    end
+
     desc 'hello NAME', 'say hello'
     def hello(name)
       puts "hello, #{name}"
     end
   end
 end

 Sample::Cli.start
$ bundle exec exe/sample hello
ERROR: "sample hello" was called with no arguments
Usage: "sample hello NAME"

Deprecation warningは出なくなる

別の書き方

もちろんこの書き方でもOK

class Cli < Thor
  class << self
    def exit_on_failure?
      true
    end
  end
end

これは何?

Returns exit 0 when a required argument is not provided · Issue #244 · rails/thor

引数不足で異常終了するが、なぜかステータスが 0 で返ってくる不具合がある
それで、ステータスを 1 で返すようにするメソッドを追加する必要があった

$ bundle exec exe/sample hello
ERROR: "sample hello" was called with no arguments
Usage: "sample hello NAME"
Deprecation warning: Thor exit with status 0 on errors. To keep this behavior, you must define `exit_on_failure?` in `Sample::Cli`
You can silence deprecations warning by setting the environment variable THOR_SILENCE_DEPRECATION.
$ echo $?
0

2012年にIssueが立てられて、もうすぐ10年経つけどまだ解決されていない
影響範囲が大きいということで一旦v1で警告を出すだけの対応で、v2で改善される予定っぽい

詳細はIssueを見てほしい

参考


ytkg

Written by ytkg, Twitter, GitHub