Truques com Dist::Zilla

Alexei Znamensky
Publicado em 01/09/2011

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 
  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 ser (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 número 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 automaticamente 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 automaticamente, 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 
  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 
  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.

Revisão: blabos

Obrigado pelo olho clínico, revisando este artigo.

Nota do revisor: Nem adianta vir querendo botar no meu bundle, ok? O mérito é todo seu.

Autor

Alexei "Russo" Znamensky < russoz no cpan org >

* Twitter: russoz
* Blog: http://russoz.org/
* LinkedIn: http://www.linkedin.com/profile?viewProfile=&key=754668&trk=tab_pro

Fonte

Licença

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

Licença Creative Commons
This work is licensed under a Creative Commons Attribution-ShareAlike License.
blog comments powered by Disqus