NAME

Book::Chinese::MasterPerlToday::BeACPANAuthor - Be a CPAN Author

DESCRIPTION

本章主要描述如何成为一个 CPAN 贡献者

您有一个非常好的模块,您想与整个 Perl 社区分享。最好的方式是将您的模块上传到 CPAN,本章将描述如何打包,上传您的模块和一些 CPAN 社区约定俗成的惯例。

PAUSE

上传模块到 CPAN 之前,您首先需要到 PAUSE http://pause.perl.org/ 申请一个帐号。通常帐号会在一周之内被批准(因为是志愿者自愿维护和批准整个 PAUSE 网站,所以有点慢)。

上传模块将在您通过帐号批准之后,登录 PAUSE 网站,然后点击左侧的 'Upload a file to CPAN' 来上传您的打包文件。

如何选择一个模块名

为了更好更清晰地组织 CPAN 上的所有包,您需要准确的命名您的模块。

通常请不要给你的模块取最顶层的名字(不带 :: 的包名),和谐的做法是置于某个顶层命名空间下。(当然,如果您觉得您的包将非常有用和流行的话,使用顶层名字也是可以的。)

  • Acme::

    大部分(非全部)的 Acme:: 模块是给人取乐,不成熟或试验的代码,不建议使用在 product 环境的代码。

  • Algorithm::

    算法模块

  • Alien::

    外部程序安装文件

  • Apache::

    Apache mod_perl 相关文件

  • App::

    带有可运行脚本的包

  • Archive::

  • Audio::

  • Authen::

  • B::

    perl5 core 相关模块

  • Bio::

  • Bundle::

    老式模块合集文件,建议使用 Task::

  • Business::

    国家商业相关模块。类如信用卡,在线支付,身份证等相关

  • Cache::

  • Catalyst::, CatalystX::

  • CGI::

  • Class::

  • Crypt::

  • Data::

  • Date::, DateTime::

  • DBIx::

    DBI 扩展模块

  • Devel::

    perl -d 相关模块

  • Digest::

  • Email::, Mail::

    邮件相关

  • ExtUtils::

    模块安装相关工具

  • File::

    文件操作相关

  • Finance::

    银行,股票等

  • Games::

  • Geo::

    地理位置相关

  • Graph::, Graphics::

  • HTML::

  • HTTP::

  • Image::

  • Inline::

  • IO::

  • IPC::

  • JavaScript::, JS::, JSON::

  • Jifty::

  • Language::

  • Lingua::

    自然语言相关模块

  • Log::

  • Math::

  • Module::

    模块操作相关

  • MooseX::

  • Net::

    网络相关(参考 WWW::)

  • Padre::

  • Pod::, POD::

  • POE::

  • Proc::

  • Regex::

  • RT::

  • Search::

  • SQL::

  • Statistics::

  • Task::

    模块合集文件,类似 Bundle::, 推荐。

  • Template::

  • Test::

    测试模块

  • Text::

  • URI::

  • WebServices::

  • Win32::

  • WWW::

如果你还是无法找到准确的地方来放您的模块,建议去 comp.lang.perl.modules 新闻组咨询。

如何打包模块

通常我们不会将一个(或多个) pm 文件直接上传到 PAUSE,默认的规则是打包成 .tar.gz 然后再上传。

h2xs

    > h2xs -AX -n Book::Chinese

h2xs 是最古老的创建新模块的工具。请参阅 h2xs 命令帮助。

不建议使用。

Module::Starter

    > cpan Module::Starter

安装 Module::Starter 完毕之后,perl bin 目录将有一个 module-starter 可执行文件。

    > module-starter --module=Book::Chinese::MasterPerlToday --author="Fayland Lam" --email=fayland@gmail.com

默认使用 ExtUtils::MakeMaker 作为 builder,可以后面再带 '--mb' 使用 Module::Build 或者带 '--mi' 来使用 Module::Install 作为 builder 引擎。

ExtUtils::MakeMaker 是最古老和使用最广的 builder 模块。它需要和 make 配合来打包模块。

    > perl Makefile.PL
    > make
    > make manifest
    > make test
    > make dist
    > make realclean

Module::Build 是用来代替 ExtUtils::MakeMaker 的。它不需要 make,可用 Perl 来完成打包工作。

    > perl Build.PL
    > perl Build
    > perl Build manifest
    > perl Build test
    > perl Build dist
    > perl Build realclean

Module::Install 的打包方法和 ExtUtils::MakeMaker 一样(需要 make 配合)。但不同之处在于:

  • 可扩展,拥有丰富的插件

  • 当 make dist 的时候,所有的 Module::Install 和它的插件文件将被放入 inc 目录随包一起打包成 .tar.gz 文件。

个人建议使用 Module::BuildModule::Install

Dist::Zilla

    > cpan Dist::Zilla

安装 Dist::Zilla 完毕之后,perl bin 目录下将有一个 dzil 的可执行文件。

    > dzil new Book::Chinese::MasterPerlToday

dzil 通过 dist.ini 来控制整个过程。

    > dzil test
    > dzil dist
    > dzil clean

dzil 跟 ExtUtils::MakeMakerModule::BuildModule::InstallModule::Starter 都不同。

  • dzil 是 distribution builder 而不是 installer。这是跟 Module::Install 的最大区别。

  • dzil 的 installer 还是可以选择用 ExtUtils::MakeMaker 或 Module::Build。

  • dzil 的优点在于你只需要专注于你所要开发的代码,而不用关心 MANIFEST,Makefile.PL,Build.PL 版本或者多余的 POD 代码(如 AUTHOR,COPYRIGHT & LICENSE)。

  • dzil 因为基于 Moose 所以它的代码高度可扩展,插件很容易写。

包的组成

一个包通常包括

  • Makefile.PL, Build.PL

    你必须拥有其中之一或者二者都有。建议是永远有 Makefile.PL,使用 Module::Build 可以在 Build.PL 里设置

        create_makefile_pl => 'traditional'
  • lib/Book/Chinese/MasterPerlToday.pm

    主模块。主模块里你最好有 $VERSION

  • t/

    测试目录。建议最起码有一个 00-load.t 来测试主模块的语法是合格的。

  • README, Changes, INSTALL

    所有的文件都是可选的。但是 Changes 和 README 是建议拥有的。

  • MANIFEST, META.yml, MANIFEST.SKIP

    这些文件一般可以通过 make manifest 和 make dist (或 perl Build manifest,perl Build dist) 来生成。

如何编写测试

本段落仅仅描述如何简单地编写测试和验证测试,更多跟详尽的内容,建议参考《Perl Testing 程序高手秘笈》。本书 China-pub,当当和卓越均可购买,由盛春(chunzi)和蒋永清(joe jiang)翻译。

最简单和使用最广泛的测试模块当属 Test::More,建议阅读的有

一个简单的测试文件如下 (eg/BeACPANAuthor/01-basic.t)

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    use Test::More tests => 3;
    
    ok(1, 'true value');
    cmp_ok( 1+1, '==', 2, '1+1=2');
    use_ok('Test::More');
    
    1;

测试所写的 .t 文件跟普通的 Perl 文件一样,你可以使用 perl 01-basic.t 来运行它。比如:

    E:\Fayland\chinese-perl-book\eg\BeACPANAuthor>perl 01-basic.t
    1..3
    ok 1 - true value
    ok 2 - 1+1=2
    ok 3 - use Test::More;

prove 仅仅是在 perl 输出结果的基础上进行总结

    E:\Fayland\chinese-perl-book\eg\BeACPANAuthor>prove 01-basic.t
    01-basic.t .. ok
    All tests successful.
    Files=1, Tests=3,  0 wallclock secs ( 0.08 usr +  0.00 sys =  0.08 CPU)
    Result: PASS

Test::More 遵从 TAP (The Test Anything Protocal) 格式,而 prove 能解析所有遵从 TAP 格式的输出(可以是其他语言写的)。

测试 Tip

  • skip_all

        eval "use Test::Pod 1.14";
        plan skip_all => 'Test::Pod 1.14 required' if $@;
        plan skip_all => 'set TEST_POD to enable this test' unless $ENV{TEST_POD};

    你不能要求你的测试者安装某个模块(如果要求,放到 requires 或 test_requires 里),但你可以选择在没有安装的时候跳过该测试。

FAQ 和建议

  • MANIFEST.SKIP

    MANIFEST.SKIP 不是必须的文件。它的意义在于你 make dist 或者 perl Build dist 的时候忽略目录下的哪些文件。比如你使用版本库,一般需要忽略版本库文件。所以 .SKIP 里含有

        \B\.git\b
        \B\.svn\b
        \B\.cvsignore$

    一般只有在你的 .t 生成某些临时文件,或者你不想将你的一些私有文件包含在 dist 里的时候,将它们加进 MANIFEST.SKIP,可以使用正则。

  • meta resources

    http://search.cpan.org/ 在 dist 的主页上是否显示 Repository (如 http://search.cpan.org/dist/WWW-Contact/ ) 是由 META.yml 来控制。

    而我们一般使用 Makefile.PL 或者 Build.PL 来生成 META.yml。

    • Build.PL (Module::Build)

        meta_merge     => {
          resources => {
            homepage => 'http://sourceforge.net/projects/module-build',
            bugtracker =>
              'http://rt.cpan.org/NoAuth/Bugs.html?Dist=Module-Build',
            MailingList => 'mailto:module-build@perl.org',
            repository  => 'http://svn.perl.org/modules/Module-Build/'
          }
        },

      将类似上面的东西传进 Module::Build->new,参考 http://search.cpan.org/dist/Module-Build/Build.PL

    • Makefile.PL (ExtUtils::MakeMaker)

          META_MERGE      => {
              resources => {
                  license     =>      'http://dev.perl.org/licenses/',
                  homepage    =>      'http://makemaker.org',
                  bugtracker  =>      'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
                  repository  =>      'http://github.com/schwern/extutils-makemaker',
                  MailingList =>      'makemaker@perl.org',
              },
          },

      将类似上面的东西传进 WriteMakefile,参考 http://search.cpan.org/dist/ExtUtils-MakeMaker/Makefile.PL

    • Makefile.PL (Module::Install)

          repository 'http://svn.ali.as/cpan/trunk/Module-Install';
          homepage 'http://homepage/';
          bugtracker 'http://bugtracker/';

      将类似上面的东西直接写进 Makefile.PL。

    • dist.ini (Dist::Zilla)

          [MetaResources]
          repository = http://github.com/rjbs/dist-zilla

    如果你使用一些版本库控制的话,有自动的寻找 repository 的模块。Module::Install 有 Module::Install::Repository, Dist::Zilla 有 Dist::Zilla::Plugin::Repository

  • 不被 PAUSE 索引

    如果你有一些内部私有或没有 POD 的 package 不想被 PAUSE 索引到,可以:

        package     # hidden from PAUSE
            DBD::Switch::dr;
  • dev 版本

        our $VERSION = '0.01_01';

    在版本里使用 _01 _02 等所生成的包不会被 CPAN 索引记录,但会显示成 DEVELOPER RELEASE

    该情况在模块改动大的时候比较有用,先发布一个或多个 dev 版本以供测试。然后去掉 _XX 正式发布。

  • 修复 World-writable files 错误?

    该错误一般发生在 Win32 下。解决方法有三:

    一是用最新版的 Module::Build

    二是使用该脚本来修复 http://perlmonks.org/index.pl?node_id=731935

    三是用非 Win32 系统打包。

  • 头像

    CPAN 使用 Gravatar::URL 调用 http://gravatar.com 上的公用图片。您可以在 http://gravatar.com 上使用你的 CPAN 公开邮件注册并且上传图像。

CPAN 作者

跟踪 Perl 高手的足迹和阅读他们的代码。

根据首字母排序:

大陆(和香港) Perl CPAN 作者,参考 Acme::CPANAuthors::Chinese

首字母排序:

SEE ALSO

Book::Chinese::MasterPerlToday::BeACPANTester

AUTHOR

Fayland Lam, <fayland at gmail.com>

COPYRIGHT & LICENSE

Copyright (c) 2009 Fayland Lam

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.