Création de gemmes avec Bundler

Construire une gemme était une tâche complexe qui nécessitait soit une connaissance précise du format de la gemme, soit des outils dédiés pour générer un passe-partout adapté. Ces jours-ci, nous pouvons utiliser l'excellent Bundler pour éliminer cette complexité et réduire au minimum la quantité de code généré..


Ce que nous construisons

La gemme de test que nous allons créer est un générateur de contenu factice que vous pourriez utiliser lors du développement. Au lieu de générer des phrases "lorem ipsum", il utilise Dracula de Bram Stoker pour générer un nombre arbitraire de phrases extraites du livre. Notre flux de travail commencera par générer la gemme, tester et implémenter le minimum de code nécessaire à la préparation de la gemme, puis le publier sur RubyGems..


Générer un squelette

Je vais supposer que vous avez déjà un environnement Ruby configuré. Pour ce tutoriel, nous utiliserons Ruby 1.9.3 comme base. Si vous envisagez toutefois de développer un véritable joyau, il peut être intéressant de le tester également contre Ruby 1.8 et d'autres interprètes. À cet effet, un outil tel que Travis CI est une aubaine; Avec une solide suite de tests en place, Travis vous permettra de tester votre bijou sans problème sur une grande variété de plates-formes. Commençons par générer le squelette:

bundle gem bramipsum

Je suis vraiment désolé si vous n'aimez pas le nom que j'ai choisi. En fait, l'une des tâches les plus difficiles lors du développement d'un bijou est de trouver le bon nom. La commande va créer un répertoire, appelé bramipsum avec quelques fichiers:

Gemfile

Le Gemfile est très minime:

source 'http://rubygems.org' # Spécifiez les dépendances de votre gemme dans bramipsum.gemspec gemspec

Notez qu'il vous indique clairement de déplacer vos dépendances de gemmes vers bramipsum.gemspec, afin d'avoir toutes les données pertinentes pour votre gem dans le fichier qui sera utilisé pour remplir les métadonnées sur Rubygems.

bramipsum.gemspec

le gemspec Ce fichier contient de nombreuses informations sur notre gemme; nous pouvons voir qu'il repose fortement sur Git assigner les bonnes valeurs à toutes les variables impliquant une liste de fichiers.

# - * - encoding: utf-8 - * - require File.expand_path ('… / lib / bramipsum / version', __FILE__) Gem :: Specification.new do | gem | gem.authors = ["Claudio Ortolina"] gem.email = ["[email protected]"] gem.description =% q TODO: écrivez une description de gem gem.summary =% q TODO: écrivez un résumé de gem  gem.homepage = "" gem.executables = "git ls-files - bin / *". split ("\ n"). map | f | Fichier.nom_fichiers (f) gem.files = 'git fichiers-lus' .split ("\ n") gem.test_files = 'git fichiers-lus - test, spéc., Fonctionnalités / *'. Split (" \ n ") gem.name =" bramipsum "gem.require_paths = [" lib "] gem.version = Bramipsum :: VERSION gem.add_development_dependency 'rake' end

Ensuite, nous pouvons courir paquet installer Rake. Comme il a été ajouté en tant que dépendance de développement, il ne sera pas installé par Bundler si quelqu'un utilise notre gem.

Quelques notes intéressantes sur le fichier:

  • Il inclut le commentaire d'ouverture Ruby 1.9 qui spécifie l'encodage du fichier. Ceci est important, car certaines données du fichier (comme l’email ou le nom de l’auteur) peuvent être un caractère non ascii..
  • la description et résumé doivent être changés pour être correctement affichés sur Rubygems.
  • La version est définie à l'intérieur du lib / bramipsum / version fichier, requis en haut. Il définit le VERSION constante, appelée juste avant la fin du fichier.

Le dossier lib

le lib dossier contient un générique bramipsum.rb fichier qui nécessite le version module. Même si le commentaire dans le fichier suggère que vous ajoutiez du code directement au fichier lui-même, nous l'utiliserons simplement pour exiger les classes séparées qui formeront notre petit bijou..


Mise à jour des données de base et ajout d'un framework de test

Commençons par mettre à jour les données dans bramipsum.gemspec:

… Gem.description =% q Phrases aléatoires de Dracula de Bram Stoker gem.summary =% q Génère une ou plusieurs phrases muettes extraites de Dracula de Bram Stoker… 

Des choses très simples. Ensuite, ajoutons un support pour des tests appropriés. Nous utiliserons Minitest, comme il est inclus par défaut dans Ruby 1.9. Ajoutons un tester annuaire:

test mkdir

Ensuite, nous avons besoin d'un test_helper.rb fichier et un test pour la présence de la Bramipsum :: VERSION constant.

test tactile / test_helper.rb mkdir -p test / lib / bramipsum toucher test / lib / bramipsum / version_test.rb

Ouvrons le test_helper.rb déposer et ajouter quelques lignes:

require 'minitest / autorun' require 'minitest / pride' nécessite File.expand_path ('… /… /lib/bramipsum.rb', __FILE__)

Il faut à la fois Minitest et Pride pour une sortie en couleurs; alors il faut le fichier principal bramipsum.

le version_test.rb Le fichier doit être mis à jour avec le code suivant:

require_relative '… /… / test_helper' décrit Bramipsum do it "doit être défini" do Bramipsum :: VERSION.wont_be_nil end end

Nous utilisons le format d'attente pour nos tests. Le test lui-même est assez explicite et peut facilement être exécuté en tapant:

ruby test / lib / bramipsum / version_test.rb

Vous devriez avoir un test de réussite!

Mettons maintenant à jour le Rakefile d'avoir un moyen plus confortable d'exécuter nos tests. Tout effacer et coller le code suivant:

#! / usr / bin / env rake require "bundler / gem_tasks" nécessite 'rake / testtask' Rake :: TestTask.new do | t | t.libs << 'lib/bramipsum' t.test_files = FileList['test/lib/bramipsum/*_test.rb'] t.verbose = true end task :default => :tester

Cela nous permettra de lancer nos tests en tapant râteau depuis le dossier racine de gem.


Ajout de fonctionnalités

L'objectif de ce didacticiel étant de créer une gemme, nous limiterons le nombre de fonctionnalités que nous allons ajouter..


Classe de base

Bramipsum est toujours une coquille vide. Comme nous voulons utiliser le livre de Dracula pour générer des phrases, il est temps de l'ajouter au référentiel. J'ai préparé une version du livre dans laquelle j'ai supprimé tout contenu, à l'exception du récit lui-même: ajoutons-le au projet..

mkdir -p book curl https://raw.github.com/cloud8421/bundler-gem-tutorial/master/book/dracula.txt -o book / dracula.txt

Créons maintenant un Base classe, où ajoutera toutes les méthodes nécessaires pour extraire les données du livre.

touchez lib / bramipsum / base.rb touchez le test / lib / bramipsum / base_test.rb

Le fichier de test n'aura que quelques attentes:

require_relative '… /… / test_helper' décrit Bramipsum :: Base do sujet Bramipsum :: Base décrit "la lecture du fichier" do it "doit avoir une source" do subject.must_respond_to (: source) end it "doit avoir le dracula fichier en tant que source "do subject.source.must_be_instance_of (String) end end décrire" le fractionnement en lignes "do it" doit correctement fractionner le fichier en lignes "do subject.processed_source.must_be_instance_of (Array) end" doit supprimer correctement les lignes vides "do subject.processed_source.wont_include (nil) end end end

Fonctionnement râteau va maintenant montrer une exception, comme le base.rb le fichier est toujours vide. Base va simplement lire le contenu du fichier et retourner un tableau de lignes (en supprimant les lignes vides).

La mise en œuvre est très simple:

module Bramipsum classe Base def self.source @source || = self.read end def self.processed_source @processed_source || = self.source.split ("\ n"). uniq end private def self.read File.read (Fichier .expand_path ('book / dracula.txt')) fin fin fin

Nous définissons une série de méthodes de classe contenant le texte d'origine et une version traitée, en mettant en cache les résultats après la première exécution..

Nous devons ensuite ouvrir lib / bramipsum.rb et ajoutez la bonne instruction require:

require_relative "./bramipsum/base"

Si vous enregistrez et exécutez râteau maintenant, vous devriez voir passer tous les tests.


Classe de peine

Ensuite, nous devons ajouter une nouvelle classe pour générer des phrases. Nous l'appellerons Phrase.

touchez lib / bramipsum / sentence.rb touchez le test / lib / bramipsum / sentence_test.rb

Comme auparavant, nous devons ouvrir lib / bramipsum.rb et requièrent le fichier nouvellement créé:

require_relative "./bramipsum/base" require_relative "./bramipsum/sentence"

Cette classe héritera de Base, afin que nous puissions garder la mise en œuvre minimale. Le test n'aura besoin que de trois attentes:

require_relative '… /… / test_helper' décrit Bramipsum :: Sentence do subject Bramipsum :: Sentence it "doit renvoyer une phrase aléatoire" do subject.sentence.must_be_instance_of (String) end it "doit renvoyer 5 phrases par défaut" do subject .sentences.size.must_equal (5) end it "doit renvoyer le nombre spécifié de phrases" do subject.sentences (10) .size.must_equal (10) end end

L'idée est que nous pouvons appeler Bramipsum :: Sentence.sentence ou Bramipsum :: Phrase.sentences (10) générer ce dont nous avons besoin.

Le contenu de phrase.rb est également très concis:

module Bramipsum class Phrase < Base def self.sentence self.processed_source.sample end def self.sentences(n=5) self.processed_source.sample(n) end end end

Comme nous sommes sur Ruby 1.9, nous pouvons utiliser le échantillon méthode pour renvoyer un élément aléatoire d'un tableau.

Encore une fois, en cours d'exécution râteau devrait montrer tous les tests réussis.


Construire et distribuer le joyau

Si vous courez bijou de construction à partir de la ligne de commande, une copie locale de la gemme sera construite et emballée pour vous. Si vous n'avez pas besoin de le distribuer, ou si vous devez le garder privé, vous pouvez vous arrêter ici. Mais si c'est un projet que vous pouvez open-source, je vous encourage à le faire.

L'étape évidente consiste à ajouter notre nouveau joyau à RubyGems.org.

Après avoir créé un compte sur le site, visitez votre profil. Vous trouverez une commande à exécuter pour autoriser votre ordinateur. Dans mon cas c'était:

curl -u cloud8421 https://rubygems.org/api/v1/api_key.yaml> ~ / .gem / credentials

Vous n'êtes plus qu'à une étape de publier le joyau sur Rubygems, mais ne le faites pas à moins que vous ne le souhaitiez vraiment. La commande à exécuter est la suivante:

bijou pousser bramipsum-0.0.1.gem

Conclusion

Toutes nos félicitations! Vous savez maintenant comment créer un bijou à partir de rien en utilisant Bundler. Il y a cependant d'autres éléments à prendre en compte:

  • Compatibilité: vous voudrez peut-être aussi supporter Ruby 1.8. Cela nécessitera de refactoriser tous les require_relative appels; De plus, vous devrez utiliser le Minitest joyau car il n'est pas inclus par défaut dans Ruby 1.8
  • Intégration continue: vous pouvez ajouter un support à Travis CI et votre pierre précieuse sera testée dans le cloud par rapport à toutes les versions majeures de Ruby. Cela facilitera la tâche pour s'assurer qu'il n'y a pas de problèmes avec les changements de comportement spécifiques à la plate-forme.
  • Documentation: c'est important, il est bon d'avoir des commentaires RDoc qui peuvent aider à générer des documents automatiques et un bon fichier README avec des exemples et des instructions..

Merci d'avoir lu! Des questions?