Alexei ZnamenskyPublicado em 01/09/2011
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.
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.
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.
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/.
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.
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.
Usando o bundle Dist::Zilla::PluginBundle::Git, você pode automaticamente fazer com que o seu repositório git seja atualizado a cada release.
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.
Use o plugin Dist::Zilla::Plugin::Twitter para anunciar no http://twitter.com/ o release das novas versões da sua distribuição.
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.
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
.
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
.
Pelo Dist::Zilla e pela sua prestatividade.
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.
Pelo companheirismo, pelas infinitas risadas, pela dedicação com que todos zelam pela nossa linguagem de programação predileta.
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.
Alexei "Russo" Znamensky < russoz no cpan org >
O fonte deste artigo encontra-se disponível em:
https://github.com/russoz/artigos/blob/master/2011/09-sppm-equinocio/p2-distzilla/distzilla.pod
Este texto está licenciado sob os termos da Creative Commons by-sa, http://creativecommons.org/licenses/by-sa/3.0/br/