Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
350 lines (251 sloc) 10.1 KB

Truques com Dist::Zilla

No artigo do equinócio passado, falamos sobre como o Dist::Zilla pode facilitar a sua vida de desenvolvedor Perl. Mostramos como migrar de um módulo "tradicional", para um módulo usando Dist::Zilla.

Para fim de evitar confusões, repetimos que o Dist::Zilla não é um instalador, ele não substitui instaladores como ExtUtils::MakeMaker, Module::Install ou Module::Build. O que o Dist::Zilla faz é ajudar a gerar o pacote de instalação da distribuição, que irá utilizar um (ou mais) desses sistemas para ser instalado em seus destinos finais.

Neste artigo, vamos mostrar como levar a sua experiência com o Dist::Zilla para o próximo nível.

Depois de algum tempo de uso...

O seu arquivo dist.ini pode acabar se parecendo com algo assim:

name    = DataFlow
author  = Alexei Znamensky <russoz@cpan.org>
license = Perl_5
copyright_holder = Alexei Znamensky

[AutoVersion]
[MetaResources]
bugtracker.web  = http://github.com/russoz/DataFlow/issues
repository.web  = http://github.com/russoz/DataFlow
repository.url  = git://github.com/russoz/DataFlow.git
repository.type = git

[@Basic]
[MetaJSON]
[ReadmeFromPod]
[InstallGuide]
[GitFmtChanges]
max_age    = 365
tag_regexp = ^.*$
file_name  = Changes
log_format = short

[OurPkgVersion]
[PodWeaver]
[AutoPrereqs]
[Prereqs]
perl = 5.008
LWP::Curl = 0.08

[Prereqs / TestRequires]
aliased                  = 0
Test::UseAllModules      = 0

[ReportVersions::Tiny]
[CompileTests]
[EOLTests]
[PodCoverageTests]
[UnusedVarsTests]
[CriticTests]
[HasVersionTests]
[KwaliteeTests]
[MetaTests]
[PodSyntaxTests]

[@Git]
[Twitter]
tweet_url = http://search.cpan.org/~{{$AUTHOR_LC}}/{{$DIST}}
hash_tags = #perl #cpan #opendata #dataflow
url_shortener = TinyURL

Este exemplo, na verdade, é como estava de fato o arquivo dist.init da distribuição DataFlow no dia até o começo de Maio de 2011, como podemos ver no seu repositório.

Enquanto era apenas um arquivo, em um projeto, não há nenhuma grande dificuldade. Quando precisamos de mais um plugin, acrescentamos ele ao dist.ini, quando não queremos o removemos, e modificações estão a um :wq de distância.

O problema acontece, no entanto, quando começamos a cuidade de vários módulos diferentes, porque o nosso conjunto "preferido" de plugins para o Dist::Zilla precisa ser (ou gostaríamos que fosse) o mesmo para todos os projetos. A partir daí começa um o pesadelo da sincronização de dist.ini.

Mas existe um jeito mais fácil.

Use o Bundle dos Outros

O Dist::Zilla possui um role que define um PluginBundle, mais especificamente Dist::Zilla::Role::PluginBundle.

Um bundle nada mais é que uma coleção de plugins e/ou outros bundles (sim, podemos "aninhar" bundles). Eles ficam tipicamente no namespace Dist::Zilla::PluginBundle::, mas isso não obrigatório.

No exemplo de dist.ini acima, estamos usando bundles. As linhas:

[@Basic]
...

[@Git]

Denotam a utilização, respectivamente do bundle Dist::Zilla::PluginBundle::Basic e Dist::Zilla::PluginBundle::Git.

Os plugins favoritos de cada autor também podem ser vistos como coleções, e por conseguinte cada um pode criar um bundle com essa coleção. De fato, vários autores fazem isso.

Criando o seu Bundle

Para fazer o seu próprio bundle, a melhor forma é usar o role Dist::Zilla::Role::PluginBundle::Easy, que já vem com o próprio Dist::Zilla. O dist.init acima pode (e foi) parcialmente convertido no seguinte código:

package Dist::Zilla::PluginBundle::Author::RUSSOZ;

use Moose 0.99;
use namespace::autoclean 0.09;

use Dist::Zilla 4.102341;    # dzil authordeps
with 'Dist::Zilla::Role::PluginBundle::Easy';

sub configure {
  my $self = shift;

  $self->add_bundle('Basic');

  $self->add_plugins(
    'MetaJSON',
    'ReadmeFromPod',
    'InstallGuide',
    [
      'GitFmtChanges' => {
        max_age    => 365,
        tag_regexp => q{^.*$},
        file_name  => q{Changes},
        log_format => q{short},
      }
    ],

    'OurPkgVersion',
    'AutoPrereqs',
  
    'ReportVersions::Tiny',
    'CompileTests',
    'EOLTests',
    'PodCoverageTests',
    'UnusedVarsTests',
    'CriticTests',
    'HasVersionTests',
    'KwaliteeTests',
    'MetaTests',
    'PodSyntaxTests',
    'NoTabsTests',
  );
}

Para utilizar esse bundle posteriormente, basta acrescentar ao dist.ini a linha:

[@Author::RUSSOZ]

Todos esses plugins, mais o bundle Basic são automaticamente incluídos na sua configuração, devemos removê-los do dist.ini.

O bundle é uma classe Perl, que utiliza o Moose. Dessa forma, podemos também customizar o bundle programaticamente. Por exemplo, numa versão mais recente do Dist::Zilla::PluginBundle::Author::RUSSOZ temos:

has signature => (
  is      => 'ro',
  isa     => 'Bool',
  lazy    => 1,
  default => sub {
      ( defined $_[0]->payload->{signature}
            and $_[0]->payload->{signature} == 1 ) ? 1 : 0;
  },
);

sub configure {
  ...
        $self->add_plugins('Signature') if $self->signature;
}

Na hora de usar, dentro do dist.ini, podemos usar a opção signature:

[@Author::RUSSOZ]
signature = 0

E o Dist::Zilla incluirá o plugin Dist::Zilla::Plugin::Signature somente se o valor de signature for igual a 1.

A versão mais recente de Author::RUSSOZ está disponível em http://github.com/russoz/Dist-Zilla-PluginBundle-Author-RUSSOZ/.

Números de Versão

O Dist::Zilla, por si só, já provê a propagação do número de versão do módulo para os diversos arquivos que compõe a distribuição.

No entanto, se você quiser ir além disso, você pode também automatizar a configuração (e propagação para os diversos arquivos) do numero de versão do módulo. Os principais plugins que fornecem essa funcionalidade são o Dist::Zilla::Plugin::Git::NextVersion e o Dist::Zilla::Plugin::AutoVersion.

No @Author::RUSSOZ colocamos uma opção version dentro do bundle, que pode ter, entre outros, os valores gitnext e auto, respectivamente.

Bundle de Teste

Ao invés de listar todos esses plugins de teste, existe um bundle que já faz quase todo o serviço para você: Dist::Zilla::PluginBundle::TestingMania.

Git Bundle

Usando o bundle Dist::Zilla::PluginBundle::Git, você pode automaticamente fazer com que o seu repositório git seja atualizado a cada release.

Meta no Bundle

Se você usa git e mantém os seus repositórios no github, então o plugin Dist::Zilla::Plugin::GithubMeta irá preencher automagicamente as meta-informações da sua distribuição.

Twittando do seu Bundle

Use o plugin Dist::Zilla::Plugin::Twitter para anunciar no http://twitter.com/ o release das novas versões da sua distribuição.

POD no Bundle?

O plugin Dist::Zilla::Plugin::PodWeaver permite que vários pedaços do seu POD sejam gerados automagicamente, em conformidade com as boas práticas de documentação de Perl.

Espiando o Dist::Zilla

Se quiser "espiar" o que o Dist::Zilla está fazendo, um plugin muito legal é o Dist::Zilla::Plugin::ReportPhase, que mostra cada fase de execução do Dist::Zilla.

Resultado Final

Hoje o dist.ini do projeto DataFlow está assim:

name    = DataFlow
author  = Alexei Znamensky <russoz@cpan.org>
license = Perl_5
copyright_holder = Alexei Znamensky

[@Author::RUSSOZ]
version = auto
twitter_tags = #opendata #dataflow

[Prereqs]
perl = 5.008

E um outro projeto qualquer? Como por exemplo o Queue::Base, deste mesmo autor:

name    = Queue-Base
author  = Alexei Znamensky <russoz@cpan.org>
license = Perl_5
copyright_holder = Farkas Arpad, Alexei Znamensky
copyright_year   = 2011

[@Author::RUSSOZ]
version = gitnext
twitter_tags = #queue-base

Todo e qualquer projeto agora poderá se beneficiar desse bundle de plugins chamado Author::RUSSOZ.

Agradecimentos

Ricardo Signes (RJBS)

Pelo Dist::Zilla e pela sua prestatividade.

Fayland Lam (FAYLAND)

Pelo novo release do Dist::Zilla::Plugin::PerlTidy com a correção que forneci, permitindo que ele conviva em paz com Dist::Zilla::Plugin::ReportVersions::Tiny.

Comunidade São Paulo Perl Mongers

Pelo companheirismo, pelas infinitas risadas, pela dedicação com que todos zelam pela nossa linguagem de programação predileta.

REVISOR_INSIRA_SEU_NOME_AQUI

Obrigado pelo olho clínico, revisando este artigo.

Autor

Alexei "Russo" Znamensky < russoz no cpan org >

Fonte

O fonte deste artigo encontra-se disponível em:

https://github.com/russoz/artigos/blob/master/2011/09-sppm-equinocio/p2-distzilla/distzilla.pod

Licença

Este texto está licenciado sob os termos da Creative Commons by-sa, http://creativecommons.org/licenses/by-sa/3.0/br/