Thor un outil pour créer des excellent pour créer des interfaces en ligne de commande en Ruby, Il est utilisé dans Vagrant, Ruby On Rails, Bundler etc.
Thor se présente sous forme de gem que vous pouvez installer et inclure dans votre projet.Une simple class Thor expose un exécutable et des sous-commandes comme git, bundler ou rails…
Une fois que vous incluez Thor dans votre classe, les méthodes publiques de votre classe deviennent des commandes.
Exemple:
# Require thor library. require "thor" class MyCLI < Thor desc "hello NAME", "say hello to NAME" def hello(name) puts "Hello #{name}" end end # Start CLI MyCLI.start(ARGV)
A la fin de votre classe il faudra imperativement demarrer votre CLI (Interface de Ligne de Commande). Typiquement vous pouvez faire cela dans le repertoire d’excutable « bin » de votre gem.
Si l’argument passé à la méthode « start » est vide, Thor affiche une d’aide de votre class.
Appel à la méthode ci-dessus sans argument :
$ ruby ./cli Tasks: cli hello NAME # say hello to NAME cli help [TASK] # Describe available tasks or one specific task
Appel à la méthode ci-dessus avec argument :
$ ruby ./cli hello Yehuda Hello Yehuda
Vous pouvez aussi utilisé des arguments optionnel de ruby, pour rendre les arguments de votre programme optionnels :
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
Quand vous exécutez ce code, vous obtenez :
$ ruby ./cli hello "Yehuda Katz" Hello Yehuda Katz
$ ruby ./cli hello "Yehuda Katz" "Carl Lerche" from: Carl Lerche Hello Yehuda Katz
Long Description
Par défaut Thor utilise la description courte pour vos commande en utilisant la méthode de class « desc » qui reçoit deux paramètres au minimum, le premier étant l’usage de la commande et le second la description courte de la commande.
$ ruby ./cli help hello Usage: test.rb hello NAME say hello to NAME
Souvent, vous avez besoin d’afficher une description un peu long pour vos commandes, dans cas vous pouvez utiliser la méthode de class « long_desc » fournie par Thor.
class MyCLI < Thor desc "hello NAME", "say hello to NAME" long_desc <<-LONGDESC `cli hello` will print out a message to a person of your choosing. You can optionally specify a second parameter, which will print out a from message as well. > $ cli hello "Yehuda Katz" "Carl Lerche" > from: Carl Lerche LONGDESC def hello(name, from=nil) puts "from: #{from}" if from puts "Hello #{name}" end end
Options et Flags
Thor rend facile l’utilisation des options et flags comme métadonnées.
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
Maintenant vos utilisateurs peuvent spécifier l’option « from » comme un 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
Il faut noter que par défaut, les options sont des chaines de caractères « String », mais vous pouvez spécifier les types alternative pour chaque commande.
class MyCLI < Thor option :from option :yell, :type => :boolean desc "hello NAME", "say hello to NAME" def hello(name) output = [] output << "from: #{options[:from]}" if options[:from] output << "Hello #{name}" output = output.join("\n") puts options[:yell] ? output.upcase : output end end
Quand vous exécutez ce code vous obtiendrez :
$ ./cli hello --yell Yehuda --from "Carl Lerche" FROM: CARL LERCHE HELLO YEHUDA
$ ./cli hello Yehuda --from "Carl Lerche" --yell FROM: CARL LERCHE HELLO YEHUDA
Il faut noter que vous spécifier si une option est requise avec la fonction « required » lors de la declaration de l’option.
class MyCLI < Thor option :from, :required => true option :yell, :type => :boolean desc "hello NAME", "say hello to NAME" def hello(name) output = [] output << "from: #{options[:from]}" if options[:from] output << "Hello #{name}" output = output.join("\n") puts options[:yell] ? output.upcase : output end end
Si vous essayez d’exécuter ce code sans l’option requise :
$ ./cli hello Yehuda No value provided for required options '--from'
Sous-commandes
Comme votre CLI devient un peu plus complexe, vous pouvez vouloir utiliser des sous-commandes. Comme par exemple pour la command « git remote » qui contient
des sous commandes : add, rename, rm, prune, set-head etc.
Dans Thor vous pouvez faire
la meme chose facilement en créant des classes pour chaque
sous-commandes et pointer apres ces sous-commandes dans la commande
principale.
Exemple :
module GitCLI class Remote < Thor desc "add <name> <url>", "Adds a remote named <name> for the repository at <url>" long_desc <<-LONGDESC Adds a remote named <name> for the repository at <url>. The command git fetch <name> can then be used to create and update remote-tracking branches <name>/<branch>. With -f option, git fetch <name> is run immediately after the remote information is set up. With --tags option, git fetch <name> imports every tag from the remote repository. With --no-tags option, git fetch <name> does not import tags from the remote repository. With -t <branch> option, instead of the default glob refspec for the remote to track all branches under $GIT_DIR/remotes/<name>/, a refspec to track only <branch> is created. You can give more than one -t <branch> to track multiple branches without grabbing all branches. With -m <master> option, $GIT_DIR/remotes/<name>/HEAD is set up to point at remote's <master> branch. See also the set-head command. When a fetch mirror is created with --mirror=fetch, the refs will not be stored in the refs/remotes/ namespace, but rather everything in refs/ on the remote will be directly mirrored into refs/ in the local repository. This option only makes sense in bare repositories, because a fetch would overwrite any local commits. When a push mirror is created with --mirror=push, then git push will always behave as if --mirror was passed. LONGDESC 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 another repository" options :all => :boolean, :multiple => :boolean option :append, :type => :boolean, :aliases => :a def fetch(respository, *refspec) # implement git fetch here end desc "remote SUBCOMMAND ...ARGS", "manage set of tracked repositories" subcommand "remote", Remote end end
Vous pouvez avoir accès aux
options de la commande parente dans les sous-commandes en utilisant
la méthode de class « parent_options » fournie par Thor.
NB : ce tuto est
inspiré du officiel sur le site de Thor « http://whatisthor.com/ »,
qui est disponible en Anglais.
Amonce DEMBELE
LIRE AUSSI: Comment programmer des tâches Cron en Ruby On Rails ?
7 Comments