Run a Cli Thor App Without Arguments or Task Name

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



Leave a reply



Submit