Ako na CPAN-like modul
CPAN moduly sú distribuované vo forme .tar.gz kde sú zkomprimované a uložené
jednotlivé súbory. Takto pripravené modulu si môžu užiť širokú paletu open
source nástrojov ako je napríklad dh-make-perl, ktorý z nich
vytvorí Debian balíček. Moduly nemusia byť použité len pre upload na CPAN ale
aj na "interné" - closed source použitie. Zjednodušia organizovanie a
inštalovanie.
Na "naštartovanie" je najjednoduchšie použiť
Module::Starter. Takže
apt-get install libmodule-starter-perl alebo cpan -i Module::Starter
pridá do systému module-starter skriptík. Tento vie vytvoriť celú
súborovú štruktúru pre modul. Napríklad chceme vytvoriť modul ktorý reprezentuje
vlak. ;-) Nepýtajte sa ma prečo. (pretože nič dômyselnejšie ma momentálne nenapadlo)
$ module-starter --builder=Module::Build --module=Acme::DopravnyProstriedok::Vlak \
--author="Jozef Kutej" --email=jozef@kutej.net
Created starter directories and files
$ tree Acme-DopravnyProstriedok-Vlak/
Acme-DopravnyProstriedok-Vlak/
|-- Build.PL
|-- Changes
|-- MANIFEST
|-- README
|-- lib
| `-- Acme
| `-- DopravnyProstriedok
| `-- Vlak.pm
`-- t
|-- 00-load.t
|-- boilerplate.t
|-- pod-coverage.t
`-- pod.t
Čo znamenajú jednotlivé súbory:
Build.PL
use strict;
use warnings;
use Module::Build;
my $builder = Module::Build->new(
module_name => 'Acme::DopravnyProstriedok::Vlak',
license => 'perl',
dist_author => 'Jozef Kutej <jozef@kutej.net>',
dist_version_from => 'lib/Acme/DopravnyProstriedok/Vlak.pm',
build_requires => {
'Test::More' => 0,
},
add_to_cleanup => [ 'Acme-DopravnyProstriedok-Vlak-*' ],
create_makefile_pl => 'traditional',
);
$builder->create_build_script();
Build.PL pomocou `perl Build.PL` vytvorí Build ktorý sa dá spustiť.
Build má veľa argumentov:
$ ./Build help Usage: ./Build <action> arg1=value arg2=value ... Example: ./Build test verbose=1 Actions defined: build manifest clean manpages code pardist config_data ppd diff ppmdist dist prereq_report distcheck pure_install distclean realclean distdir retest distmeta skipcheck distsign test disttest testall docs testcover fakeinstall testdb help testpod html testpodcoverage install versioninstall Run `Build help <action>` for details on an individual action. See `perldoc Module::Build` for complete documentation.
Najdôležitejšie sú - build, test, install, clean. "build" pripraví všetky potrebné súbory pre inštalovanie modulu a skopíruje ich do adresára blib. "test" spustí na týchto súboroch všetky testy nachádzajúce sa v adresári t/. "install" nainštaluje modul do systému. A "clean" poupratuje/zmaže súbory ktoré Build vytvoril.
Bežný návod ako nainštalovať module pozostáva z
`perl Build.PL && ./Build && ./Build test && ./Build install`, v prípade
že konfigurácia/inštalácia (ako nášho module) je postavená na
Module::Build. Druhá možnosť
je ExtUtils::MakeMaker.
V tom prípade sa inštaluje pomocou
`perl Makefile.PL && make && make test && make install`. Ak je v Build.PL
zapnuté create_makefile_pl => 'traditional' tak Module::Build
vytvorí aj Makefile.PL takže sa dá inštalovať aj druhým spôsobom. Okolo toho
či používať Module::Build, alebo ExtUtils::MakeMaker sa vedú vojny, pričom
existuje ešte Module::Install a iné...
Changes
Revision history for Acme-DopravnyProstriedok-Vlak
0.01 Date/time
First version, released on an unsuspecting world.
súbor obsahuje zmeny ktoré boli urobené v konkrétnej verzií modulu.
MANIFEST
Build.PL Changes MANIFEST README lib/Acme/DopravnyProstriedok/Vlak.pm t/00-load.t t/pod-coverage.t t/pod.t
MANIFEST obsahuje zoznam súborov ktoré patria k modulu. Ostatné
súbory budú pri vytváraní distribúcie (Acme-DopravnyProstriedok-Vlak-0.01.tar.gz)
zignorované. MANIFEST treba udržiavať "up-to-date". Ľahko sa stane že sa pridá nový
súbor do distribúcie a zabudne sa na MANIFEST. Ako pomôcka slúži `./Build distcheck`
ktorý upozorní že existujú nejaké súbory ktoré sa nenachádzajú v MANIFEST-e.
Dobré je si pridať súbor MANIFEST.SKIP v ktorom sa nachádza zoznam súborov ktoré sa majú pri tomto teste ignorovať.
MANIFEST.SKIP
# Avoid version control files. \bRCS\b \bCVS\b ,v$ \B\.svn\b # Avoid Makemaker generated and utility files. \bMakefile$ \bblib \bMakeMaker-\d \bpm_to_blib$ \bblibdirs$ ^MANIFEST\.SKIP$ # Avoid Module::Build generated and utility files. \bBuild$ \b_build \bcover_db # Avoid temp and backup files. ~$ \.tmp$ \.old$ \.bak$ \#$ \b\.# \.cvsignore \.svnignore
README
Keď sa do Build.PL pridá create_readme => 1, vyupdatuje sa tento
súbor pri vytváraní distribúcie z PODu hlavného .pm súboru. V našom
prípade lib/Acme/DopravnyProstriedok/Vlak.pm. Update teda
nastane pri `./Build dist` alebo pri `./Build distmeta`.
Okrem README sa vytvoria aj nové verzie META.yml a Makefile.PL.
META.yml
Tento súbor obsahuje základné údaje
o module v YAML formáte. Je automaticky
generovaný pri `./Build dist` alebo pri `./Build distmeta` z informácií
v Build.PL .
.cvsignore
Obsahuje príklad toho čo ignorovať ak sa na revisioning control
používa CVS. Ak používate Subversion dá sa použiť -
`svn propset svn:ignore "`cat .cvsignore`" . && svn rm .cvsignore`.
Alebo pre GIT `mv .cvsignore .gitignore`.
t/ adresár
v tomto adresáre sa nachádzajú testy. Každý dobrý module/distribúcia by mala obsahovať testy. Tieto zaručia jednak pri vývoji, ale hlavne pri prerábaní, veľkých fixoch a iných zmenách, že funkcionalita zostane zachovaná. Aj vďaka testom vďačia Perl moduly za svoju kvalitu. Keď autor modulu nahrá novú verziu na CPAN, automaticky si to "všimnú" smoke testing servery a zbehnú tieto testy. Výsledky o tom či prešli, alebo neprešli a pre ktoré verzie Perl-u a ktoré operačné systémy sa dajú nájsť opäť na CPAN-e.
t/00-load.t je jednoduchý test ktorý zistí či sa dá náš
nový modul skompilovať.
t/pod-coverage.t prejde všetky súbory a zistí či sú všetky
funkcie okomentované.
t/pod.t otestuje či je pod dokumentácie bez syntaktických
chýb. Tieto posledné dva sú pomôcka pre autora modulu
a je dobre si ich nechať. Ďalej je dobre si pridať nasledujúce testy:
00-compile.t skontroluje či všetky moduly v distribúcií
sa skompilujú v poriadku -
use strict;
use Test::More;
eval "use Test::Compile 0.08";
plan skip_all => "Test::Compile 0.08 required for testing compilation"
if $@;
my @pmdirs = qw(lib blib sbin bin);
all_pm_files_ok(all_pm_files(@pmdirs));
pod-spell.t skontroluje spelling v pod dokumentácií -
use strict;
use Test::More;
if (!$ENV{TEST_SPELLING}) {
plan skip_all =>
"Set the environment variable TEST_SPELLING to enable this test.";
}
eval 'use Test::Spelling;';
plan skip_all => "Test::Spelling required for testing POD spelling"
if $@;
add_stopwords(qw(
Jozef
));
all_pod_files_spelling_ok();
distribution.t otestuje či všetky súbory distribúcie sú
v poriadku -
use Test::More; eval 'use Test::Distribution not => "sig"'; plan( skip_all => 'Test::Distribution not installed') if $@;
signature.t otestuje digitálny podpis od autora
modulu. Spustí sa len keď je nastavené $ENV{TEST_SIGNATURE} a keď
existuje SIGNATURE súbor. Tento sa dá automaticky generovať
ak sa do Build.PL pridá sign => 1, -
#!/usr/bin/perl
use strict;
use Test::More;
if (!$ENV{TEST_SIGNATURE}) {
plan skip_all =>
"Set the environment variable TEST_SIGNATURE to enable this test.";
}
elsif (!eval { require Module::Signature; 1 }) {
plan skip_all =>
"Next time around, consider installing Module::Signature, ".
"so you can verify the integrity of this distribution.";
}
elsif ( !-e 'SIGNATURE' ) {
plan skip_all => "SIGNATURE not found";
}
elsif ( -s 'SIGNATURE' == 0 ) {
plan skip_all => "SIGNATURE file empty";
}
elsif (!eval { require Socket; Socket::inet_aton('pgp.mit.edu') }) {
plan skip_all => "Cannot connect to the keyserver to check module ".
"signature";
}
else {
plan tests => 1;
}
my $ret = Module::Signature::verify();
SKIP: {
skip "Module::Signature cannot verify", 1
if $ret eq Module::Signature::CANNOT_VERIFY();
cmp_ok $ret, '==', Module::Signature::SIGNATURE_OK(), "Valid signature";
}
lib/Acme/DopravnyProstriedok/Vlak.pm
Konečne sme sa dostali k dôvodu prečo sme robili všetku túto parádu :-) , a to vytvoriť modul k všeobecnému blahobytu. Tu má každý voľnu ruku a môže sa do sýtosti zrealizovať. O tom čo je to modul a ako vyzerá z vnútra napíšem v inom návode.
Výcuc ;-)
Rýchly štart:
module-starter --builder=Module::Build --module=Acme::DopravnyProstriedok::Vlak::Rychlik \
--author="Jozef Kutej" --email=jozef@kutej.net
cp MANIFEST.SKIP Acme-DopravnyProstriedok-Vlak-Rychlik/
cp 00-compile distribution.t pod-spell.t signature.t \
Acme-DopravnyProstriedok-Vlak-Rychlik/t/
rm Acme-DopravnyProstriedok-Vlak-Rychlik/t/boilerplate.t
cd Acme-DopravnyProstriedok-Vlak-Rychlik/
vim Build.PL
# pridat
# create_readme => 1,
# sign => 1,
vim lib/Acme/DopravnyProstriedok/Vlak/Rychlik.pm
# nieco zmysluplne nakodit
# zmenit verziu v hlavnom .pm, vyplnit Changes
perl Build.PL; ./Build clean; perl Build.PL && ./Build distcheck && ./Build disttest && ./Build dist
# upload => pause.cpan.org
Slovo na záver. Netreba sa báť pridať niečo na CPAN. Pokiaľ to nekoliduje s iným modulom bude to indexované a pretrvá to tam na veky vekov. Treba rešpektovať niektoré namespace ako DateTime ktoré sa ho snažia mať upratané, ale v takých prípadoch sa niekto ozve, že mu tam robíte bordel. ;-)
Linky: Čo skrýva CPAN
24. Jun 2008
Jozef
en