Making An Executable

Neil Souza edited this page Feb 25, 2018 · 4 revisions

You may want to make a script as an executable command. To do this with Thor:

  • include the ruby shebang line.
  • require "thor" in your script.
  • define your Thor class.
  • add #{YourThorClassname}.start to the bottom of your script.

Example: mythorcommand.rb

#!/usr/bin/env ruby
require "rubygems" # ruby1.9 doesn't "require" it though
require "thor"

class MyThorCommand < Thor
  desc "foo", "Prints foo"
  def foo
    puts "foo"
  end
end

MyThorCommand.start

Make the script executable:

chmod a+x mythorcommand.rb

Now you can type:

./mythorcommand.rb foo

WARNING

It is important to note that executables written in this manner will report success to the operating system or parent process when they fail due to a bad command name or arguments (they will exit with status 0, which indicates success):

$ ./mythorcommand.rb boo
Could not find command "boo".
$ echo $?
0

If you only use the executable by itself in your terminal this is unlikely to be a problem, since you are there to read the error message and are not relying on the exit status, but the executable will not behave as expected when called from shell scripts, used in shell conditionals (if, &&, etc.), spawned from other processes, and invoked by applications and tools like Capistrano, Ansible, Docker, etc., which can lead to serious problems.

If you want your executable to correctly report failure when it fails in these cases you must modify the script as follows:

#!/usr/bin/env ruby
require "rubygems" # ruby1.9 doesn't "require" it though
require "thor"

class MyThorCommand < Thor
  def self.exit_on_failure?
    true
  end
  
  desc "foo", "Prints foo"
  def foo
    puts "foo"
  end
end

MyThorCommand.start
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.