=pod

=head1 NAME

CPANPLUS::Dist::Arch - CPANPLUS backend for building Archlinux pacman packages

=head1 VERSION

Version 0.16

=head1 SYNOPSIS

  (First, setup cpan to use us automatically:)
  $ setupdistarch
  This script will now setup CPANPLUS to automatically package all
  modules into pacman packages when installing.
  Are you sure you want to do this? [y/N] y
  Set CPANPLUS to package all modules through CPANPLUS::Dist::Arch

  (Install the module as a pacman package:)
  $ cpanp -i Perl::Module::Here

  (Add --verbose for more output:)
  $ cpanp -i Acme::Bleach --verbose

  (Use cpan2dist to make a package, but don't install it:)
  $ cpan2dist --verbose Acme::Bleach

  (Use our included cpan2aur to make a source package in current dir:)
  $ cpan2aur CPANPLUS::Dist::Arch

  (Oh no!  If something doesn't autopackage, create an AUR package dir
   under our current dir.  This package dir contains a PKGBUILD we can
   edit and then run makepkg on:)
  $ cpan2aur -d CPANPLUS::Dist::Arch
  Finding module CPANPLUS::Dist::Arch... done
  Created perl-cpanplus-dist-arch/PKGBUILD
  $ cd perl-cpanplus-dist-arch
  $ emacs PKGBUILD
  $ makepkg
  (Get the idea? Now upload, etc)

=head1 SETUP

Setting up L<CPANPLUS> to use this module automatically is as easy as
the example above.  See L<setupdistarch>(1) for more information about
setupdistarch.  If you are having trouble running C<setupdistarch> or
C<cpanp>, your C<PATH> may not be set properly, add C</usr/bin/perlbin/core>
and C</use/bin/perlbin/vendor> to your C<.profile> file in your home
directory.

  # Example ~/.profile
  export PATH=/usr/bin:/bin:/usr/bin/perlbin/core:/usr/bin/perlbin/vendor

=head1 WHERE IS THE PACKAGE

By default, packages are stored under the user's home directory in the
.cpanplus directory.  Two seperate directories are created for
building packages and for storing the resulting package file.

=over

=item Build Directory

C<~/.cpanplus/5.10.0/pacman/build>

=item Package Directory

C<~/.cpanplus/5.10.0/pacman/pkg>

=back

Where C<5.10.0> represents the version of perl you used to build the
package and ~/.cpanplus represents the base directory chosen
in your CPANPLUS config.

=head1 CUSTOMIZATION

=head2 PKGDEST

You can change the destination by setting C<PKGDEST> in your
C</etc/makepkg.conf> file.  You can also set the C<PKGDEST> environment
variable to a directory where you want to store all built packages.

=head2 PACKAGER

The C<PACKAGER> in C</etc/makepkg.conf> is inserted into the PKGBUILD
comment header.  If there is no PACKAGER set, then 'Anonymous' is used
instead.  You may also use the C<PACKAGER> environment variable.

=head1 COMMAND LINE OPTIONS

There are many command line options to L<cpan2dist> and L<cpanp>.  A
small number of these options are recognized by CPANPLUS::Dist::Arch.

=over

=item B<--verbose>

This classic option allows for more verbose messages.  Otherwise you
get next to no output.  Useful for debugging and neurosis.

=item B<--skiptest>

This will I<comment out> the tests in PKGBUILD files that are generated.
I actually think testing is a good idea and would not recommend this
unless you know what you are doing.

  WARNING: This affects all pre-requisite module/packages that are
           built and installed; not just the module you specify.

=back

=head1 DIST OPTIONS

cpan2dist allows you specify CPANPLUS::Dist::Arch specific options on
the command line.  I'm not sure how or if cpanp does the same.  Look
at the source code of the L<cpan2aur> script to see how they also work
programmatically.

=over

=item B<pkgtype>

This specifies whether to make a source package or a binary package.
The default is to make a binary package.

=item B<destdir>

Specifies where to store the resulting package.  The default is to
store under the C<~/.cpanp/pacman/pkg> directory, or the directory
specified by C<PKGDEST> in the C</etc/makepkg.conf> config file.

=back

=head1 EXPORT TAGS

=over 4

=item B<:all>

This will import the functions C<dist_pkgname> and C<dist_pkgver> into
your package.

=back

=head1 EXPORTED FUNCTIONS

=head2 dist_pkgname

  Usage   : my $pkgname = dist_pkgname( 'Acme-Drunk' );
  Purpose : Converts a module's distribution name to an
            Archlinux style perl package name.
  Params  : $dist_name - The name of the distribution (ex: Acme-Drunk)
  Returns : The Archlinux perl package name (ex: perl-acme-drunk).
            following the Archlinux packaging standards.

=head2 dist_pkgver

  Usage   : my $pkgver = dist_pkgver( '1.20.1_2A' );
  Purpose : Convert a module's CPAN distribution version into our more
            restrictive pacman package version number.
  Params  : The version of the CPAN distribution file.
  Returns : The Archlinux package version following the Archlinux
            packaging standards.

=head1 PUBLIC METHODS

When using the CPANPLUS module in a perl script to create packages,
these public methods are available.  See the cpanpkgbuild.pl script
included in the examples directory for an example.

=head2 set_destdir

  Usage   : $dist->set_destdir('~/pkg/perl');
  Purpose : Sets the directory to store the resulting package.
  Returns : The directory that was set.

=head2 get_destdir

  Usage   : my $dest = $dist->get_destdir;
  Returns : The directory where the package is going to end up.

=head2 get_pkgpath

  Usage   : my $fqp = $dist->get_pkgpath;
  Returns : The fully qualified path of the built package
            or undef if no package was built yet.

=head2 get_cpandistdir

  Usage   : my $distdir = $dist->get_cpandistdir;
  Returns : The main directory name that will be inside the distribution
            tarball.  This directory contains the entire distribution.
  Example : If the distribution file of Acme-Bleach is in the tarball
            Acme-Bleach-1.12.tar.gz or Acme-Bleach-1.12.tar.bz2
            then $dist->get_cpandistdir will return 'Acme-Bleach-1.12'.
  Notes   : Does not actually check if the directory exists in the tarball.
            So far it always has...

=head2 get_pkgvars

  Usage   : my %pkgvars = $dist->get_pkgvars;
  Returns : A hash containing all the PKGBUILD variables.
            Keys are the bash variable names in the PKGBUILD.
            Dependencies are converted to their pacman names.
 
            The keys are: pkgname, pkgver, pkgdesc, depends, url, source
            md5sums (despite this name only one is given), depshash
 
            One new key is 'depshash' whose value is a hashref.
            The hashref keys are packages and their values are
            required versions, or 0 if there is no required version.

=head2 get_pkgvars_ref

  Usage    : my $pkgvars_ref = $dist->get_pkgvars_ref;
  Returns  : The same as get_pkgvars except as a hashref.

=head2 get_pkgbuild

  Usage    : my $pkgbuildtext = $dist->get_pkgbuild;
  Params   : $skiptest - (optional, default is 0)
                         Whether to skip testing and comment out the test.
  Returns  : A scalar containing the full text of the PKGBUILD that would
             be generated in the perl pacman package.

=head2 create_pkgbuild

  Usage   : $self->create_pkgbuild( '/tmp', 1 );
  Purpose : Creates a PKGBUILD file in the specified directory.
  Params  : $destdir - The directory to put the new PKGBUILD in.
            $skiptest - (optional, default is 0)
                        Whether to skip testing and comment out the test.
  Precond : You must first call prepare or have CPANPLUS do it automatically.
  Throws  : unknown installer type: '...'
            failed to write PKGBUILD: ...
            Invalid arguments to create_pkgbuild
            Invalid directoy passed to create_pkgbuild: ...
  Returns : Nothing.

=head1 LIMITATIONS

There are some limitations in the way CPANPLUS and pacman works
together that I am not sure can be fixed automatically.  Instead you
might need a human to intervene.  I called these limitations because
they aren't exactly bugs.  More specific bugs with exact error messages
are in the L</BUGS> section.

=over 4

=item B<Cannot detect non-perl dependencies>

As of version 0.9, CPANPLUS will I<try> to find non-perl dependencies.
This only works with ExtUtils::MakeMaker distributions.

This means if you plan on distributing a perl module package (ie
uploading to AUR) you should edit the PKGBUILD by hand to include
the libraries needed by the XS module.

The included L<cpan2aur> script helps creating customized AUR
packages.

=item B<A module is installed, but pacman says it isn't>

CPAN[PLUS] considers a module installed if it can be C<use>d.  That
is, if it is in C<@INC> somewhere on your system.

I<Pacman> considers a module installed if it has been packaged and
installed with I<pacman>.

So if you installed some modules in the past without packaging them
first, they don't exist as far as I<pacman> is concerned.  Usually, you
can just reinstall them using this module because CPANPLUS::Dist::Arch
installs modules under the C<vendor_perl/> directories, such as
C</usr/share/perl5/vendor_perl/...>, and CPAN installs under the
C<site_perl/> directories, such as C</usr/share/perl5/site_perl/...>.

Installing with this module will appease I<pacman>, but you may want
to manually delete the previously installed modules to prevent
version mismatch problems.

=item B<Pre-requisites are always installed>

CPANPLUS by default installs the pre-requisite modules before the
module you requested.  This module does the same only it creates an
Arch package and installs it with I<pacman> instead.

You should be able to run I<pacman> under sudo for this to work properly.
Or you could run cpan2dist as root, but I wouldn't recommend it.

=item B<All module packages are installed explicitly>

This has to do with how I<pacman> categorizes automatically installed
dependencies implicitly installed package.  Explicitly installed
packages are packages installed by the user, by request.

So, logically, all pre-requisite perl modules should be installed
implicitly but right now everything is installed explicitly.

If this is a big problem, tell me and I will try to make some hackish
solution.  I can't think of an elegant way to do this.

=item B<Readline is broken and I can't use cpanplus!>

I had this problem recently.  A system upgrade had updated my readline
package but the L<Term::ReadLine::Gnu> module was not updated.  Or
perhaps I had the termcap-compat package, which breaks
L<Term::ReadLine::Gnu>.

I forget, in any case Term::ReadLine::Gnu was broken.  To be able to
update the perl-term-readline-gnu package, I had to force the
Term::ReadLine module to not try to load Term::ReadLine::Gnu with the
PERL_RL environment variable:

  PERL_RL=0 cpanp -i Term::ReadLine::Gnu

=back

=head1 BUGS

Please email me or report any bugs or feature requests to
C<bug-cpanplus-dist-arch at rt.cpan.org>, or through the web interface
at
L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=CPANPLUS-Dist-Arch>.
I will be notified, and then you'll automatically be notified of
progress on your bug as I make changes.

=head2 Known Bugs

=over 4

=item B<Dist creation of '...' skipped, build time exceeded: 300 seconds>

If compiling a module takes a long time, this message will pop up.
Interestingly, though, the module keeps compiling in the background...?

This is something CPANPLUS does automatically.  If you had been trying
to install the module, the install step will be aborted.  The package
will still be created in the usual directory, so you can install it
manually.

I haven't been able to track this down yet... I think it has only happened
with cpan2dist so far.  It happened when building L<PDL>, by the way.

=back

=head1 TODO

=over 4

=item * Extract license information from META.yml, maybe use a YAML module.

=back

=head1 SUPPORT

Email me at C<< jrcd83 at gmail >> or message me as I<juster> on the
Archlinux BBS at L<http://bbs.archlinux.org>.

To check why the build process failed, read the build logs CPANPLUS
keeps in C<~/.cpanplus/install_logs/>.  The problem may be specific to
the module you're building and not this module.

=head1 ACKNOWLEDGEMENTS

This module was inspired by the perl-cpanplus-pacman package and
CPANPLUS::Dist::Pacman by Firmicus which is available at
L<http://aur.archlinux.org/packages.php?ID=5954>.

This mostly started from CPANPLUS::Dist::RPM which is on Google Code
at L<http://code.google.com/p/cpanplus-dist-rpm/>.  This was a very
helpful starting point to try to understand the internals of CPANPLUS.

=head1 SEE ALSO

=over

=item * AUR Package: perl-cpanplus-dist

L<http://aur.archlinux.org/packages.php?ID=24971>

=item * Git Repository

L<http://github.com/juster/perl-cpanplus-dist-arch>

=item * Archlinux Perl Package Guidelines

L<http://wiki.archlinux.org/index.php/Perl_Package_Guidelines>

=item * pacman

L<http://wiki.archlinux.org/index.php/Pacman>

=item * makepkg

L<http://wiki.archlinux.org/index.php/Makepkg>

=item * CPANPLUS

L<http://search.cpan.org/dist/CPANPLUS/>

=back

=head1 AUTHOR

Justin Davis, C<< <jrcd83 gmail> >>, juster on L<http://bbs.archlinux.org>

=head1 COPYRIGHT & LICENSE

Copyright 2010 Justin Davis, all rights reserved.

This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.

=cut