#!/usr/bin/perl

# ABSTRACT: administer a Pinto repository
# PODNAME: pinto-admin

use strict;
use warnings;

#-----------------------------------------------------------------------------

our $VERSION = '0.018'; # VERSION

#-----------------------------------------------------------------------------

use App::Pinto::Admin;
exit App::Pinto::Admin->run();

#-----------------------------------------------------------------------------



=pod

=for :stopwords Jeffrey Ryan Thalhammer Imaginative Software Systems

=head1 NAME

pinto-admin - administer a Pinto repository

=head1 VERSION

version 0.018

=head1 SYNOPSIS

  pinto-admin --repos=/path/to/repos [global options] COMMAND [command options] [ARGS]

=head1 DESCRIPTION

C<pinto-admin> is a command line utility for creating and managing a
Pinto repository.  The repository can contain your own distributions
and/or mirror foreign distributions from another repository (such as
L<http://cpan.perl.org>).  You can also put patched versions of
foreign distributions in your repository.

You can then point L<cpanm> to your Pinto repository and install your
distributions (with their dependencies).  B<NOTE:> At this time, only
L<cpanm> will work properly with a Pinto repository.  But support for
L<cpan> and L<cpanp> is coming real soon!

=head1 TYPICAL USAGE

  # Create an empty repository
  pinto-admin --repos=/some/dir create

  # Add your own distribution to the repository
  pinto-admin --repos=/some/dir add /path/to/Foo-Bar-1.2.tar.gz

  # Then install stuff from your repository
  cpanm --mirror-only --mirror file:///some/dir Foo::Bar

=head1 OPTIONS

The following global options are available for all commands.  Say
C<pinto-admin help COMMAND> to display a list of sub-options available
for that C<COMMAND>.

=over 4

=item --repos=/path/to/your/repository

Specifies the path to the root directory of your repository.  This is
mandatory for all commands.

=item --nocolor

Do not colorize diagnostic messages according to severity.

=item --quiet | -q

Report only fatal errors.  This option siletly overrides the
C<--verbose> options.

=item --verbose | -v

Display more diagnostic messages.  This switch can be repeated multiple
times for greater effect.

=back

=head1 COMMANDS

The following commands are available.  To display a list of
sub-options available for any command, you can say:

  pinto-admin help COMMAND.

=over 4

=item add path/to/Some-Distribution-1.2.tar.gz

Adds the given distribution to the Pinto repository.  I call these
"local distributions".  Any packages contained in that distribution
will mask the foreign packages with the same name.  See the
L<"BEHAVIOR"> section for more information about how local
distributions interact with foreign ones.

Note that you can also pipe arguments to this command over STDIN.  In
that case, blank lines and lines that look like comments will be
ignored.

=item clean

Deletes any distribution in the repository that is not currently in
the master index.  This usually happens automatically, unless you've
set the C<nocleanup> parameter.  If you had set C<nocleanup>, beware
that running the C<clean> command will make it impossible to install
older distributions from your repository, and the only way to get them
back is to manually add them again (or rollback, if using VCS).

=item create

Creates a new, empty repository at the configured directory.  The
directory does not need to already exist, and you'll get a warning
if it does.

=item list

Lists packages and distributions that are currently indexed in your
remote repository.  You can see all packages (the default) only
locally added packages, only foreign packages, or only local packages
that conflict with a foreign package.

=item remove Some::Package

Removes the local distribution that contains the given package.  All
other packages that were contained in the same distribution are also
removed.  You can only remove a package that B<YOU> have added.  You
cannot remove packages in foreign distributions that were pulled in
from a remote source (however you can mask them by adding your own
versions).

Note that you can also pipe arguments to this command over STDIN.  In
that case, blank lines and lines that look like comments will be
ignored.

=item mirror

Fills your repository with the distributions that contain the latest
version of all packages in the C<source> repository.  I call these
"foreign" distributions.  See the L<"BEHAVIOR"> section for more
information about how local distributions interact with foreign ones.

=item verify

Reports any distributions that are listed in your index but not
actually present in the repository.  This is usually a sign that
something has gone wrong.

=back

=head1 CONFIGURATION

The F<config> directory in the root of every repository contains a
configuration file named F<pinto.ini>.  This file will be generated
for you (with default values) whenever you create a new repository.
Thereafter, it is up to you to manually adjust the configuration file
as you see fit.

The configuration file is in the typical INI format.  Parameters are
C<NAME = VALUE> pairs.  Global parameters (which are all the ones
described below) are at the top of the file. Blank lines are ignored,
leading and trailing whitespace is discarded.  Comments start with a
semi-colon (;).

=over 4

=item source = URL

The URL of a repository that you would like L<Pinto> to pull foreign
distributions from.  This could be a public CPAN mirror, or another
Pinto repository.  Defaults to L<http://cpan.perl.org>.  This
parameter is only relevant to the C<mirror> command.

=item nocleanup = 0|1

If true, L<Pinto> will not automatically delete distributions that
become out of date (either because you've added your own local version
or you've pulled a newer one from a remote repository).  The default
is 0, which means you won't be able to install older versions of a
distribution from your repository.  But if you set <nocleanup> to 1,
then you can still get older distributions in the usual way:

  $> cpanm A/AU/AUTHOR/Older-Dist-1.2.tar gz

=item noclobber = 0|1

Normally, L<Pinto> favors removing "old" distributions when new ones
are added (see L<"BEHAVIOR">).  But if C<noclobber> is true, L<Pinto>
will not remove (from the index) every package in an existing
distribution whenever you add a distribution that contains one or more
of the packges that were in the existing distribution.  Setting this
to true make Pinto behave more like PAUSE.  TODO: explain this better!

=item store = CLASS_NAME

The name of the class that will handle storage of your Pinto
repository.  The default is L<Pinto::Store>, which simply stores your
repository on the local file system.  Alternatives Stores like
L<Pinto::Store::VCS::Svn> and L<Pinto::Store::VCS::Git> will also
store your repository inside a version control system (VCS).  See the
documentation for each of those modules for additional configuration
settings.

=back

=head1 BEHAVIOR

There are certain rules that govern how a Pinto repository behaves.
These rules are intended to ensure that clients installing
distributions from your repository will always get the B<right ones>,
regardless of what happens on the public CPAN or what order they
install things.  Also, the rules attempt to make Pinto behave somewhat
like PAUSE does.

=over 4

=item A local package always masks a foreign package, and all other
packages that are in the same distribution with the foreign package.

This is important, so pay attention.  If you C<mirror> or C<add> a
distribution that contains both C<Foo> and C<Bar> packages, and you
C<add> another distribution that contains just the C<Foo> package,
then both the C<Foo> and C<Bar> packages from the prior distribution
will be removed from your index.  This ensures that anyone installing
packages from your repository will always get B<your latest> version of
C<Foo>.  But they'll never be able to get C<Bar>, because doing so
would leave them with the older C<Foo>.

However, you can disable this behavior with the C<noclobber>
configuration parameter.

=item You can never add a distribution with the same name twice.

Most distribution-building tools will put some kind of version number
in the name of the distribution, so this is rarely a problem.  The
"name" of a distribution is actually a function of the name of the
file and the name of the author.  So technically, it is possible for
two different authors to both add a distribution called
F<Foo-Bar-1.2.tar.gz>.  But in practice, this almost never happens
because...

=item Only the original author of a local package can add a
distribution that contains the same package.

Ownership is given on a first-come basis, just like PAUSE.  So if
C<SALLY> is the first author to add a distribution to the repository
with package C<Foo::Bar>, then only C<SALLY> can ever add another
distribution with that package again.  Unless that package is
explicitly removed, but...

=item Only the original author of a local package can remove it.

Just like when adding new versions of a local package, only the
original author can remove it.  Yes, you can just change the C<author>
parameter in your configuration, but C<SALLY> probably wouldn't
appreciate you messing with her releases (unless C<SALLY> no longer
works here).

So if you're working as part of a team and everyone is allowed to
make releases of the same packages, then conisder having everyone
use the same C<author> parameter.

=back

=head1 SEE ALSO

L<Pinto::Manual> for broad information about using the Pinto tools.

L<pinto-server> to allow remote access to your Pinto repository.

L<pinto-remote> to interact with a remote Pinto repository.

=head1 AUTHOR

Jeffrey Ryan Thalhammer <jeff@imaginative-software.com>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2011 by Imaginative Software Systems.

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

=cut


__END__


