#!/usr/bin/perl

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

use strict;
use warnings;

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

our $VERSION = '0.012'; # 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.012

=head1 SYNOPSIS

  pinto-admin [global options] COMMAND [command options] [ARGS]

  pinto-admin help COMMAND

  pinto-admin help

=head1 DESCRIPTION

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

You can then point L<cpanm> to your Pinto repository and build and
install your distributions (and 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

First, create a configuration file at F<~/.pinto/config.ini>:

  ; Required. this wil be the path to your repository
  local = /some/directory

  ; Optional, defaults to http://cpan.perl.org
  source = http://some-cpan-mirror

  ; Optional, defaults to your shell user name
  author = MYNAME

Then, run some commands:

  # Create an empty repository
  $> pinto-admin create

  # Add your own distribution to the repository
  $> pinto-admin add Foo-Bar-1.2.tar.gz

  # Fill your repository with all the latest distributions from a remote source
  $> pinto-admin mirror 

  # Then install stuff from your repository
  $> cpanm --mirror-only --mirror file:///some/directory Foo

=head1 CONFIGURATION

The following parameters can be set in your configuration file.  The
default location of this file is F<~/.pinto/config.ini>.  You may
specify an alternative location for this file by setting the
C<PERL_PINTO> environment variable to point to another path.

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 (;).

Almost all configuration parameters can also be specified on the
command line, either as global options or command options.  To display
a list of global options:

  $> pinto-admin -help

To get a list of options for a particular command:

  $> pinto-admin help <command>

=over 4

=item author = NAME

Your identity as a module author.  This could be your PAUSE ID, but it
doesn't have to be.  As long as it is just alphanumeric characters.
This defaults to your shell username (either C<$ENV{USERNAME}> or
C<$ENV{USER}> or C<$ENV{LOGNAME}>).  This parameter is only relevant
to the C<add> and C<remove> commands.

If you have a team of developers and you want them all to be able
to add/remove the same packages to the repository, then everyone
on the team should use the same C<author> parameter.

=item local = DIRECTORY

The path to a directory where your repository will be kept.  This
parameter is required for all commands.  You must be able to read and
write to this directory.  You may use a tilde (~) as shorthand for
your home directory.

=item source = URL

The URL of a repository that you would like 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-admin> 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.

=item nocommit = 0|1

If true, L<pinto-admin> will not commit changes in the repository to your
VCS at the end of each command.  If you're not using a VCS store, then
this parameter has no effect.  The default is 0.

=item noinit = 0|1

If true, L<pinto-admin> assumes tha the working copy of your
repository is up-to-date and will not pull/update the repository from
your VCS at the beginning of each command.  This can save a lot of
time, but use with caution. If you're not using a VCS store, then this
parameter has no effect.  The default is 0.

=item notag = 0|1

If true, L<pinto-admin> will not make a tag in your VCS after committing
changes, even if you've configured a tag name.  If you're not using a
VCS store, then this parameter has no effect.  The default is 0.

=item quiet = 0|1

If true, then only fatal error messages will be displayed.  This
parameter silently overrides any C<verbose> setting.

=item store = CLASS_NAME

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

=item verbose = 0|1|2

Controls how much noise is made.  Default is 0.

=back

=head1 COMMANDS

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

=over 4

=item add Some-Distribution-1.2.tar.gz

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

=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.

=item create

Creates a new, empty repository at the configured location.  You'll
get a warning if a repository already exists at that location.

=item list

Lists the curent packages and distributions that are in the master
index of your repository.  This is basically just the contents of the
F<02packages.details.txt> file.

=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 locally
added.  You cannot remove foreign packages that you pulled in from a
remote source (however you can mask them by adding your own versions).

=item mirror

Fills your repository with the distributions that contain the latest
version of all packages in the remote repository.  See the L<"RULES">
section for more information about how locally added distributions
interact with foreign ones.

=item verify

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

=back

=head1 RULES

There are certain rules that govern how the indexes are managed.
These rules are intended to ensure that clients installing packages from
your repository will always get the B<right ones>.  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 rule is important, so pay attention.  If you C<mirror> a
distribution from a foreign repository that contains both C<Foo> and
C<Bar> packages, and you C<add> your own local distribution that
contains just the C<Foo> package, then both the foreign C<Foo> and
C<Bar> packages will be removed from your index.  This ensures that
anyone installing packages from your repository will always get B<your>
version of C<Foo>.  But they'll never be able to get C<Bar>, because
doing so would overwrite your C<Foo>.

=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 rarely happens
because...

=item Only the original author of a local package can add an
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).

=back

=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__


