Perle skapelse med Bundler

Å bygge en perle pleide å være en kompleks oppgave som ville kreve enten en presis kunnskap om perleformatet, seg selv, eller noen dedikerte verktøy for å generere en passende boilerplate. I disse dager kan vi bruke den gode Bundler til å fjerne denne kompleksiteten og holde mengden generert kode til et minimum.


Hva vi bygger

Test-perlen vi skal bygge er en dummy-innholdgenerator du kan bruke under utvikling. I stedet for å generere "lorem ipsum" setninger, bruker den Bram Stoker's Dracula til å generere en vilkårlig mengde setninger tatt fra boken. Arbeidsflyten vår starter ved å generere perlen, teste og implementere den minste mengden kode som er nødvendig for å få vår perle klar, og deretter publisere den på RubyGems.


Genererer et skjelett

Jeg kommer til å anta at du allerede har et Ruby-miljø. For denne opplæringen bruker vi Ruby 1.9.3 som utgangspunkt. Hvis du imidlertid planlegger å utvikle en ekte perle, kan det være bra å også teste den mot Ruby 1.8 og andre tolker. Til det formål er et verktøy som Travis CI en godsend; Med en solid testpakke på plass, vil Travis la deg teste din perle mot et bredt utvalg av plattformer uten problemer. La oss starte med å generere skjelettet:

bundt perle bramipsum

Jeg er virkelig lei meg hvis du ikke liker navnet jeg valgte, faktisk er det en av de vanskeligste oppgavene å utvikle en perle, å finne riktig navn. Kommandoen vil opprette en katalog, kalt bramipsum med noen få filer:

Gemfile

Gemfile er veldig minimal:

kilde 'http://rubygems.org' # Angi perlenes avhengigheter i bramipsum.gemspec gemspec

Legg merke til at det tydeligvis forteller deg at du skal flytte dine perleavhengigheter til bramipsum.gemspec, for å få alle relevante data for din perle i filen som vil bli brukt til å fylle metadataene på Rubygems.

bramipsum.gemspec

De gemspec filen inneholder mye informasjon om vår perle; vi kan se at det stoler sterkt på Git å tildele de riktige verdiene til alle variablene som involverer filoppføring.

# - * - koding: utf-8 - * - krever File.expand_path ('... / lib / bramipsum / version', __FILE__) Perle :: Spesifikasjon.nye gjør | perle | gem.authors = ["Claudio Ortolina"] gem.email = ["[email protected]"] gem.description =% q TODO: Skriv en perlebeskrivelse gem.summary =% q TODO: Skriv en perleoppsummering  gem.homepage = "" gem.executables = 'git ls-filer - bin / *'. split ("\ n"). kart | f | File.basename (f) gem.files = 'git ls-files'.split ("\ n") gem.test_files =' git ls-filer - test, spec, features / * '. \ n ") gem.name =" bramipsum "gem.require_paths = [" lib "] gem.version = Bramipsum :: VERSION gem.add_development_dependency 'rake' end

Deretter kan vi løpe bunt å installere Rake. Som det ble lagt til som en utviklingsavhengighet, vil den ikke bli installert av Bundler når noen bruker vår perle.

Noen interessante notater om filen:

  • Den inneholder Ruby 1.9-åpningskommentaren som spesifiserer filkodingen. Dette er viktig, ettersom noen data i filen (som e-post eller forfatternavn) kan være et ikke-ascii-tegn.
  • beskrivelse og sammendrag må endres for å være riktig vist på Rubygems.
  • Versjonen er definert inne i lib / bramipsum / versjon fil, kreves øverst. Det definerer VERSJON konstant, kalt rett før slutten av filen.

Lib-mappen

De lib mappen inneholder en generisk bramipsum.rb fil som krever versjon modul. Selv om kommentaren i filen antyder at du legger til kode direkte til selve filen, bruker vi den bare for å kreve de separate klassene som vil danne vår lille perle.


Oppdaterer basdata og legger til en testramme

La oss begynne med å oppdatere dataene i bramipsum.gemspec:

... gem.description =% q Tilfeldige setninger fra Bram Stoker's Dracula gem.summary =% q Generer en eller flere dummy setninger tatt fra Bram Stoker's Dracula ... 

Veldig enkle ting. Deretter legger vi til støtte for riktig testing. Vi vil bruke Minitest, som det er inkludert som standard i Ruby 1.9. La oss legge til en test katalogen:

mkdir test

Deretter trenger vi en test_helper.rb fil og en test for tilstedeværelsen av Bramipsum :: VERSJON konstant.

touch test / test_helper.rb mkdir -p test / lib / bramipsum berøringstest / lib / bramipsum / version_test.rb

La oss åpne test_helper.rb fil og legg til noen linjer:

krever 'minitest / autorun' krever 'minitest / pride' krever File.expand_path ('... / ... /lib/bramipsum.rb', __FILE__)

Det krever både Minitest og Pride for farget utdata; da krever det den viktigste bramipsumfilen.

De version_test.rb filen må oppdateres med følgende kode:

need_relative '... / ... / test_helper' beskriver Bramipsum gjør det 'må defineres "gjør Bramipsum :: VERSION.wont_be_nil slutten

Vi bruker forventningsformatet for våre tester. Selve testen er ganske selvforklarende og kan lett kjøres ved å skrive:

rubin test / lib / bramipsum / version_test.rb

Du bør ha en bestått test!

La oss nå oppdatere Rakefile å ha en mer behagelig måte å kjøre våre tester på. Slett alt og lim inn følgende kode:

#! / usr / bin / env rake krever "bundler / gem_tasks" krever "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 => :test

Dette vil la oss kjøre testene våre ved å skrive rake fra perlen rotmappen.


Legge til funksjonalitet

Som fokus på denne opplæringen er å lage en perle, vil vi begrense mengden funksjonalitet vi skal legge til.


Base klasse

Bramipsum er fortsatt et tomt skall. Som vi vil bruke Dracula's bok for å generere setninger, er det på tide å legge det til depotet. Jeg har utarbeidet en versjon av boka der jeg har fjernet noe innhold, bortsett fra historien selv: la oss legge til prosjektet.

mkdir -p bokkrøll https://raw.github.com/cloud8421/bundler-gem-tutorial/master/book/dracula.txt -o bok / dracula.txt

La oss nå lage en Utgangspunkt klasse, hvor vil legge til alle metodene som trengs for å trekke ut data fra boken.

berør lib / bramipsum / base.rb berøringstest / lib / bramipsum / base_test.rb

Testfilen har bare noen få forventninger:

need_relative '... / ... / test_helper' beskrive Bramipsum :: Base-emne Bramipsum :: Base beskriver "lesing fra fil" gjør det "må ha en kilde" gjør subject.must_respond_to (: source) end it "må ha dracula fil som kilde "gjør subject.source.must_be_instance_of (String) endendat beskrive" splitting into lines "gjør det" må splitte filen riktig i linjer "gjør subject.processed_source.must_be_instance_of (Array) avslutte det" må fjerne tomme linjer på riktig måte "gjør subject.processed_source.wont_include (nil) slutten slutten

Løping rake Nå vil det vise et unntak, som base.rb filen er fortsatt tom. Utgangspunkt vil ganske enkelt lese innholdet i filen og returnere en rekke linjer (fjerne de tomme).

Gjennomføringen er veldig enkel:

modul Bramipsum klasse Base def self.source @source || = self.read ende def self.processed_source @processed_source || = self.source.split ("\ n"). uniq end privat def self.read File.read (File .expand_path ('book / dracula.txt')) slutten slutten

Vi definerer en serie klassemetoder som holder den opprinnelige teksten og en behandlet versjon, caching resultater etter første runde.

Vi må da åpne lib / bramipsum.rb og legg til den rette kravoppgaven:

require_relative "./bramipsum/base"

Hvis du lagrer og kjører rake Nå bør du se alle tester som passerer.


Setningsklasse

Deretter må vi legge til en ny klasse for å generere setninger. Vi vil kalle det Setning.

berør lib / bramipsum / sentence.rb berøringstest / lib / bramipsum / sentence_test.rb

Som før må vi åpne lib / bramipsum.rb og krever den nyopprettede filen:

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

Denne klassen vil arve fra Utgangspunkt, slik at vi kan holde implementeringen minimal. Testen vil bare ha tre forventninger:

required_relative '... / ... / test_helper' beskrive Bramipsum :: Setning gjør emne Bramipsum :: Setning det "må returnere en tilfeldig setning" gjør subject.sentence.must_be_instance_of (String) avslutte det "må returnere 5 setninger som standard" gjør emne .sentences.size.must_equal (5) avslutte det "må returnere den angitte mengden setninger" gjør subject.sentences (10) .size.must_equal (10) end-end

Tanken er at vi kan ringe Bramipsum :: Sentence.sentence eller Bramipsum :: Sentence.sentences (10) å generere det vi trenger.

Innholdet for sentence.rb er også veldig kortfattet:

modul Bramipsum klasse setning < Base def self.sentence self.processed_source.sample end def self.sentences(n=5) self.processed_source.sample(n) end end end

Som vi er på Ruby 1.9, kan vi bruke prøve metode for å returnere et tilfeldig element fra en matrise.

Nok en gang kjører rake skal vise alle tester som passerer.


Bygg og distribuere perlen

Hvis du kjører perle bygge Fra kommandolinjen vil en lokal kopi av perlen bli bygget og pakket for deg. Hvis du ikke trenger å distribuere den, eller hvis du trenger å holde den privat, kan du stoppe her. Men hvis det er et prosjekt du kan åpne kilde, oppfordrer jeg deg til å gjøre det.

Det åpenbare skrittet er å legge til vår helt nye perle til RubyGems.org.

Etter å ha opprettet en konto på nettstedet, besøk din profil. Du finner en kommando du må løpe for å autorisere datamaskinen din. I mitt tilfelle var det:

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

Du er nå bare ett skritt unna for å publisere perlen på Rubygems, men gjør det ikke med mindre du virkelig vil. Kommandoen du vil kjøre er:

perle push bramipsum-0.0.1.gem

Konklusjon

Gratulerer! Du vet nå hvordan du lager en perle fra bunnen bare ved hjelp av Bundler. Det er imidlertid andre ting å ta hensyn til:

  • kompatibilitet: Du vil kanskje også støtte Ruby 1.8. Det vil kreve refactoring alle require_relative samtaler; I tillegg må du bruke Minitest perle som den ikke er inkludert som standard i Ruby 1.8
  • Kontinuerlig integrering: Du kan legge til støtte til Travis CI og din perle vil bli testet i skyen mot alle de store Ruby-utgivelsene. Dette vil gjøre det enkelt å være sikker på at det ikke er noen problemer med plattformspesifikke atferdsendringer.
  • dokumentasjon: dette er viktig, det er godt å ha RDoc-kommentarer som kan bidra til å generere automatiske dokumenter og en god README-fil med eksempler og retningslinjer.

Takk for at du leste! Noen spørsmål?