Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Thor

 Thor

Charla de Thor para meetup ruby, Santiago, Chile

More Decks by Miguel Michelson Martinez

Other Decks in Programming

Transcript

  1. Thor is a toolkit for building powerful command-line interfaces. It

    is used in Bundler, Vagrant, Rails, and 197 other gems. Monday, September 2, 13
  2. class Pullentity::Client < Thor desc "hello NAME", "say hello to

    NAME" def hello(name) puts "Hello #{name}" end end A simple Thor class exposes an executable with a number of subcommands, like git or bundler. In a Thor class, public methods become commands. Monday, September 2, 13
  3. You can start the CLI with a call to Pullentity::Client.start(ARGV).

    Typically, you would do this in an executable in the bin directory of your gem. Monday, September 2, 13
  4. If the arguments you pass to start are empty, Thor

    will print out a help listing for your class. Monday, September 2, 13
  5. require "thor" class MyCli < Thor # contents of the

    Thor class end MyCLI.start(ARGV) Monday, September 2, 13
  6. Thor will automatically use the executable name in the help

    it generates for a Thor class. $ ruby ./cli Tasks: cli hello NAME # say hello to NAME cli help [TASK] # Describe available tasks o Monday, September 2, 13
  7. If you execute the hello task with a parameter, it

    will call your method: $ ruby ./cli hello Yehuda Hello Yehuda Monday, September 2, 13
  8. You can also use Ruby’s optional arguments to make a

    CLI argument optional: class MyCLI < Thor desc "hello NAME", "say hello to NAME" def hello(name, from=nil) puts "from: #{from}" if from puts "Hello #{name}" end end Monday, September 2, 13
  9. When you execute it: $ ruby ./cli hello "Yehuda Katz"

    Hello Yehuda Katz $ ruby ./cli hello "Yehuda Katz" "Carl" from: Carl Hello Yehuda Katz Monday, September 2, 13
  10. Options and Flags Thor makes it easy to specify options

    and flags as metadata about a Thor command: class MyCLI < Thor desc "hello NAME", "say hello to NAME" option :from def hello(name) puts "from: #{options[:from]}" if options[:from] puts "Hello #{name}" end end Monday, September 2, 13
  11. Options and Flags Now, your users can specify the from

    option as a flag: $ ruby ./cli hello --from "Carl Lerche" Yehuda from: Carl Lerche Hello Yehuda $ ruby ./cli hello Yehuda --from "Carl Lerche" from: Carl Lerche Hello Yehuda $ ruby ./cli hello Yehuda --from="Carl Lerche" from: Carl Lerche Hello Yehuda Monday, September 2, 13
  12. Options and Flags class MyCLI < Thor option :from option

    :yell, :type => :boolean desc "hello NAME", "say hello to NAME" def hello(name) .... By default, options are Strings, but you can specify an alternate type for any options: Monday, September 2, 13
  13. Options and Flags class MyCLI < Thor option :from, :required

    => true option :yell, :type => :boolean desc "hello NAME", "say hello to NAME" def hello(name) .... end end You can also specify that a particular option is required. Monday, September 2, 13
  14. Options and Flags $ ./cli hello Yehuda No value provided

    for required options '--from Now, if I try to run the command without the required option: Monday, September 2, 13
  15. Options and Flags • :desc: A description for the option.

    When printing out full usage for a command using cli help hello, this description will appear next to the option. • :banner: The short description of the option, printed out in the usage description. By default, this is the upcase version of the flag (from=FROM). • :required: Indicates that an option is required • :default: The default value of this option if it is not provided. An option cannot be both :required and have a :default. • :type: :string, :hash, :array, :numeric, or :boolean • :aliases: A list of aliases for this option. Typically, you would use aliases to provide short versions of the option. The full list of metadata you can provide for an option: Monday, September 2, 13
  16. Options and Flags class MyCLI < Thor desc "hello NAME",

    "say hello to NAME" options :from => :required, :yell => :boolean def hello(name) .... end You can use a shorthand to specify a number of options at once if you just want to specify the type of the options. You could rewrite the previous example as: Monday, September 2, 13
  17. Class Options You can specify an option that should exist

    for the entire class by using class_option. Class options take exactly the same parameters as options for individual commands, but apply across all commands for a class. The options hash in a given task will include any class options. Monday, September 2, 13
  18. Class Options You can specify an option that should exist

    for the entire class by using class_option. Class options take exactly the same parameters as options for individual commands, but apply across all commands for a class. The options hash in a given task will include any class options. class MyCLI < Thor class_option :verbose, :type => :boolean desc "hello NAME", "say hello to NAME" options :from => :required, :yell => :boolean def hello(name) ... Monday, September 2, 13
  19. Subcommands As your CLI becomes more complex, you might want

    to be able to specify a command that points at its own set of subcommands. One example of this is the git remote command, which exposes add, rename, rm, prune, set-head, and so in. Monday, September 2, 13
  20. Subcommands module GitCLI class Remote < Thor desc "add <name>

    <url>", "Adds a remote named <name> for the <url>" option :t, :banner => "<branch>" option :m, :banner => "<master>" options :f => :boolean, :tags => :boolean, :mirror => :string def add(name, url) # implement git remote add end desc "rename <old> <new>", "Rename the remote named <old> to <new>" def rename(old, new) end end class Git < Thor desc "fetch <repository> [<refspec>...]", "Download objects and refs from repository" options :all => :boolean, :multiple => :boolean option :append, :type => :boolean, :aliases => :a def fetch(respository, *refspec) # implement git fetch here end Monday, September 2, 13
  21. Namespaces FALTA NAMESPACE class CLI < Thor include Utils include

    Thor::Actions ........ register Pullentity::Generate::Project, :project, "project", "project g Monday, September 2, 13
  22. Utils include Thor::Actions say, ask, yes?, no?, add_file, remove_file, copy_file,

    template, directory, inside, run, inject_into_file ...... Monday, September 2, 13
  23. NO TASKS module Generate class Auth < Thor include ::Pullentity::Client::Utils

    no_tasks { def domain "http://pullentity.com" end } ..... Monday, September 2, 13