Go to Hackademy website

Thor - Simplifier les tâches récurrentes

Nicolas Cavigneaux

Posté par Nicolas Cavigneaux dans les catégories outils

Thor ?

Thor est en autre un remplacement de Rake. Ce framework permettant de faciliter la construction d’utilitaires en ligne de commande a été écrit par Yehuda Katz ce qui en dit déjà long sur la qualité de cet outil.

Thor a plusieurs avantages par rapport à Rake :

  • traitement des options de ligne de commande en toute facilité
  • génération automatique des aides d’utilisation
  • des helpers pour faciliter la manipulation du système de fichier, la création de templates, …
  • les tâches peuvent être installées pour être utilisées de n’importe où dans l’arborescence

Installation

Rien de bien nouveau :

gem install thor

Première tâche

On peut créer un fichier Thorfile (équivalent au Rakefile) qui contiendra nos tâches.

Un exemple des plus simple pourrait être :

class Test < Thor
  desc "bonjour", "Disons nous bonjour"
  def bonjour
    puts "Bonjour !"
  end
end

Si on essaie ensuite un thor list ou thor -T, nous verrons notre nouvelle tâche apparaitre :

test
----
thor test:bonjour  # Disons nous bonjour

Ajout d’un paramètre

Nos tâches sont tout à fait capable de recevoir des arguments. Plus besoin de passer par des variables d’environnement, Thor va gérer cela pour nous :

class Test < Thor
  desc "bonjour NOM", "Disons nous bonjour"
  def bonjour(nom)
    puts "Bonjour #{nom} !"
  end
end

Demandons de l’aide à Thor :

$ thor help test:bonjour

Usage:
  thor test:bonjour NOM

Disons nous bonjour

Essayons maintenant notre tâche améliorée :

$ thor test:bonjour Nico

Bonjour Nico !

Il est à noter que nous avons défini un paramètre, il est donc obligatoire de le spécifier lors de l’appel de la tâche. Si les paramètres obligatoires ne sont pas fournis, Thor s’en plaindra :

"bonjour" was called incorrectly. Call as "thor test:bonjour NOM".

Définir des options

Vous pouvez très facilement en plus des paramètres obligatoires, définir des options pour modifier le comportement de votre tâche :

class Test < Thor
  desc "bonjour NOM", "Disons nous bonjour"
  method_option :verbose, :aliases => "-v", :desc => "Parle plus que de raison"
  def bonjour(nom)
    puts "Bonjour #{nom} !"
    puts "Quelle belle journée." if options[:verbose]
  end
end

Essayons donc notre nouvelle option :

$ thor test:bonjour Nico -v

Bonjour Nico !
Quelle belle journée

Il est possible de définir plus finement les options :

method_option :path, :type => :string, :default => "~/", :required => false, :aliases => "-p"

Les types disponibles étant les suivants :

:boolean : --option / --option=true / --no-option

:string : --option=VALEUR

:numeric : --option=2

:array : --option=nico martin jr

:hash : --option=nom:Nico lang:ruby

Créer des dépendances entre tâches

Thor permet d’invoquer une tâche depuis une autre ce qui permet de chaines des appels et donc définir des dépendances :

class Compteur < Thor
  desc "un", "Affiche 1"
  def one
    puts 1
  end

  desc "deux", "Affiche 1, 2"
  def two
    invoke :un
    puts 2
  end

  desc "trois", "Affiche 1, 2, 3"
  def three
    invoke :deux
    puts 3
  end
end

La classe Thor::Group permet de produire le même type de comportement en exécutant toutes les méthodes du groupe, une à une, dans l’ordre de définition :

class Compteur < Thor::Group
  desc "Affiche 1 2 3"

  def un
    puts 1
  end

  def deux
    puts 2
  end

  def trois
    puts 3
  end
end
$ thor compteur
# => 1
# => 2
# => 3

Interactions utilisateur

Thor met à disposition un certain nombre de méthodes qui facilitent les interactions utilisateur. En voici quelque unes :

  • say
  • ask
  • yes?
  • no?
  • add_file
  • remove_file
  • copy_file
  • template
  • directory
  • inside
  • run
  • inject_into_file

Pour pouvoir les utiliser, n’oubliez pas d’inclure Thor::Actions dans votre classe.

Jetez un œil à la documentation de ces méthodes qui évitent de ré-inventer la roue.

Moi je veux un namespace pour la gloire !

Pas de problème, si vous avez besoin d’ajouter un namespace à vos tâches, rien de plus simple :

module Synbioz
  class App < Thor
    # taches
  end
end
$ thor synbioz:app:tache

System-wide !

Dernier gros avantage, lorsque l’une de vos tâches pourrait être ré-utilisé dans d’autres projets, inutile de recopier votre Thorfile dans chacun de vos projets. Il suffit, dans le répertoire contenant votre Thorfile, de lancer :

thor install Thorfile

Désormais, quelque soit le répertoire dans lequel vous vous trouvez, vos tâches sont disponibles !

Conclusion

Avec un tel framework, il devient très facile d’automatiser ses tâches récurrentes ou même encore de mettre rapidement en place un générateur comme on peut le connaitre dans Rails 3 (qui utilise Thor justement). On peut même à partir d’un Thorfile, créer une version exécutable avec très peu de modification.

L’équipe Synbioz.

Libres d’être ensemble.

Articles connexes

Un plugin Vim à la mimine

03/01/2019

Dans l’article précédent, intitulé une assez bonne intimité, je vous présentais GPG et le chiffrement de courriels. Nous avons alors remarqué que le contenu d’un courriel était encodé de sorte que le...

Une assez bonne intimité

20/12/2018

Si vous êtes utilisateur de MacOS, il y a de fortes chances que vous utilisiez Apple Mail pour échanger des courriels. Et comme vous êtes sensible à la confidentialité des informations que vous...

Tests end to end avec Jest et Puppeteer

05/07/2018

Dans cet article, on va partir sur des tests end to end. Pour planter le décor, un test end to end (e2e) est un test logiciel qui a pour but de valider que le système testé répond correctement à un...

Chasser les requêtes N+1 avec Bullet

05/04/2018

Aujourd’hui nous allons parler des requêtes N+1 dans une application Rails : vous savez ces lignes quasiment identiques, qui s’ajoutent de manière exponentielle aux logs, dès lors que l’on appelle...