Utiliser Bundler dans un script ruby sans rien afficher dans le terminal

Il est possible d’utiliser Bundler pour installer des gemmes dans un script ruby, et c’est super pratique ! Voici comment empêcher Bundler d’afficher quoi que ce soit pendant l’installation des gemmes, et une solution pour un problème qui peut se produire quand on utilise cette option.

Tags : Bundler Ruby

Publié le 13 mars 2024

Ruby est très pratique pour écrire des scripts exécutables: interpréter les paramètres est particulièrement simple avec OptionParser, et manipuler le système de fichier avec les utilitaires File et Dir est beaucoup plus agréable que de basculer sur des commandes shell.

Mais bien que la librairie standard de Ruby propose un grand nombre de fonctionnalités, les gemmes peuvent nous emmener encore plus loin. Et Bundler est là pour nous aider à les installer dans le contexte du script uniquement ! Il suffit d’appeler bundler/inline et de lister les gemmes nécessaires dans un bloc gemfile pour qu’elles soient automatiqument disponibles dans le script.

Si besoin, il est possible de forcer Bundler à vérifier et installer la dernière version des gemmes à chaque invocation du script en passant le paramètre true à la commande gemfile. Cela rallonge le temps d’exécution du script, donc il vaut mieux ne le faire que si c’est vraiment utile. Par ailleurs, en activant ce paramètre le script affichera le résultat de la commande bundle install dans le terminal, ce qui n’est pas forcément utile. Il est donc possible de combiner ce premier paramètre avec l’option quiet: true pour télécharger sans rien afficher.

Exemple de script basique :

#!/usr/bin/env ruby

require "bundler/inline"
gemfile do
  source "https://rubygems.org"
  # Lister ici les gemmes nécessaires. Par exemple : gem "colorize"
end

Pour forcer l’installation sans afficher le résultat de bundle install :

#!/usr/bin/env ruby

require "bundler/inline"
gemfile(true, quiet: true) do
  source "https://rubygems.org"
  # Lister ici les gemmes nécessaires. Par exemple : gem "colorize"
end

Attention cependant : si le script est interrompu pendant l’installation des gemmes, le terminal n’affichera plus ce qui est tapé (comme quand vous tapez un mot de passe par exemple). Cette situation est assez rare, mais je ne dois pas être le seul à qui c’est arrivé !

Heureusement, nous pouvons facilement corriger ce problème, en remettant l’environnement au propre au moment où le script est interrompu. Ruby permet de répondre aux signaux envoyés aux scripts grâce à la commande Signal.trap, ce qui est exactement ce dont nous avons besoin ici.

# Réagir à l'interruption du script
Signal.trap("SIGINT") do
  # Réactiver l'affichage du terminal si le script est interrompu pendant l'installation silencieuse de gemmes
  system "stty echo"
  # Oblige le retour à la ligne
  puts ""
  # Annuler toute les opérations en cours…
  # Indiquer que le script a été interrompu proprement
  exit true
end