Run a CLI Thor app without arguments or task name
It seems the proper Thor-way to do this is using default_task
:
class Commands < Thor
desc "whatever", "The default task to run when no command is given"
def whatever
...
end
default_task :whatever
end
Commands.start
If for whatever reason that isn't what you need, you should be able to do something like
class Commands < Thor
...
end
if ARGV.empty?
# Perform the default, it doesn't have to be a Thor task
Commands.new.whatever
else
# Start Thor as usual
Commands.start
end
Adding a --version option to a Ruby Thor CLI
I had some luck with this approach:
class CLI < Thor
map %w[--version -v] => :__print_version
desc "--version, -v", "print the version"
def __print_version
puts FooBar::VERSION
end
end
The leading underscores ensures there isn't a command like yourapp version
, and forces yourapp --version
or yourapp -v
. The desc
content will allow it to show up as -v, --version
without exposing __print_version
.
Accessing command line arguments from outside of Thor class
Instantiating your Cli
class doesn't make much sense; that's not how Thor is designed.
You have a few options to access internal data from outside the class. If there are only a few variables that you want access to, storing them as class variables and making them available through getters (and setters, if you need them) would work:
require 'thor'
class Cli < Thor
method_option :add, :type => :string, :desc => 'add servers'
method_option :prod, :type => :string, :desc => 'production stack'
desc "tier <stack folder name> <app | web>", "creates an app or web server tier for the stack"
def tier(a,b)
@@a = a
@@b = b
puts a
puts b
end
def self.get_a
@@a
end
def self.get_b
@@b
end
end
Cli.start
puts "the first argument is #{Cli.get_a}"
This works as you hope:
$ ./thor.rb tier a b
a
b
the first argument is a
I prefer the following, using a global Hash:
require 'thor'
$args = {}
class Cli < Thor
method_option :add, :type => :string, :desc => 'add servers'
method_option :prod, :type => :string, :desc => 'production stack'
desc "tier <stack folder name> <app | web>", "creates an app or web server tier for the stack"
def tier(a,b)
$args[:a] = a
$args[:b] = b
puts a
puts b
end
end
Cli.start
puts "the first argument is #{$args[:a]}"
Last, I'd be remiss not to point out that all the command line arguments are available in the global ARGV
, anyway:
require 'thor'
class Cli < Thor
method_option :add, :type => :string, :desc => 'add servers'
method_option :prod, :type => :string, :desc => 'production stack'
desc "tier <stack folder name> <app | web>", "creates an app or web server tier for the stack"
def tier(a,b)
puts a
puts b
end
end
Cli.start
puts "The first argugment is #{ARGV[1]}"
What would be best depends on how you intend to use it. If you just want raw access to the command line arguments, ARGV
is the way to go. If you want to access certain pieces after Thor has done some processing for you, one of the first two might be more helpful.
Is it possible to have a Thor method that is not an explicit task
I was able to use the no_tasks block for this.
class Update < Thor
desc "do_it", "a simple task"
def do_it
puts i_did_it
end
# no desc here !!!
no_tasks do
def i_did_it
"I did it"
end
end
end
Thor task list from within the class?
And of course, right after posting this question, I figure it out.
Foo.tasks would return a hash {task_name => [array of task info]}
Possible to call executable Thor-powered script without calling thor?
Make the shebang line
#!/usr/bin/env ruby
and then at the end of your script add
App.start
Related Topics
"Use" Keyword/Word in Ruby/Rails/Rack Code
Is There a Ruby Http Client Library with a Response Cache
How to Make the Url's in Ruby on Rails Seo Friendly Knowing a @Vendor.Name
Consuming Non-Rest APIs in Rails with Activeresource
Differences Between Literals and Constructors? ([] VS Array.New and {} VS Hash.New)
How to Pass a Variable to a Layout
How to Fix Libv8 Error from Gemfile on Mavericks
Adding Username to Devise Rails 4
Unpacking/Freezing Gems into a Non-Rails Ruby App
How to Get the File Extension from a Url
Rails 4 Update Nested Attributes
Get Time Object at Start of Day in a Particular Time Zone
Ruby, Using Regex to Find Something in Between Two Strings
Cheat Sheet for All Design Patterns Implemented in Ruby
Actiondispatch::Http::Uploadedfile.Content_Type Not Being Initialized in Rspec Test