Clive

Commands

Commands are defined using the #command method. You can use them to group together related options, to act like options or as both. Unlike Options, Commands can have multiple names, not just a short and long name. But Commands can still have arguments.

desc 'Create a new project'
command :new, :create, arg: '<dir>', as: Pathname do
  
  # Set the default type to always be basic
  set :type, :basic
  
  desc 'Type of template to use (default: basic)'
  opt :type, arg: '<choice>, 
             in: %w(basic complex custom), 
             as: Symbol
  
  bool :force, 'Force overwrite'
end

Above a command has been created which can be used with either new or create. It then has two options defined in it. So it could be used like,

$ command_test new --force ~/my-project
$ command_test new --force --type custom ~/my-project
$ command_test create --type complex ~/my-project
etc...

As with #opt(ion) a block is passed to #command, but the block for Commands defines other Options. To define a block which is run when a Command is used, use #action.

command :hello, arg: '<name>' do
  action do |name|
    puts "Hello #{name}"
  end
end

Now that seems pretty pointless, you would use an Option not a Command there, but let's complicate it by allowing other languages.

command :hello, arg: '<name>' do
  opt :lang, in: %w(english french german italian)
  
  action do |name|  
    case get(:lang)
      when 'english' then puts "Hello #{name}"
      when 'french'  then puts "Bonjour #{name}"
      when 'german'  then puts "Guten tag #{name}"
      when 'italian' then puts "Ciao #{name}"
      else puts "#{name}?"
    end
  end
end

So now you must supply a language to get a reply.

$ hello_test hello John
John?
$ hello_test hello --english John
Hello John
$ hello_test hello John --italian
Ciao John

You may have noticed the usage of the #get method in the previous example. This allows you to get a value set by an option, here by :lang.