#!/usr/bin/env perl

# ABSTRACT: provide a web interface to a Pinto repository
# PODNAME: pinto-server

use strict;
use warnings;

use Pod::Usage;
use List::MoreUtils qw(none);
use Getopt::Long qw(:config pass_through);  # keeps unrecognized options in
use Plack::Runner;
use Pinto::Server;

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

our $VERSION = '0.035'; # VERSION

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

my @opt_spec = qw(root|r=s auth=s%);
GetOptions(\my %opts, @opt_spec) or pod2usage();

$opts{root} ||= $ENV{PINTO_REPOSITORY_ROOT};
pod2usage(-message => 'Must specify a repository root') if not $opts{root};

# HACK: To avoid defaulting to the Plack default port, we must wedge
# in our own --port argument, unless the user has specified their own.
push @ARGV, ('--port' => Pinto::Server->default_port())
  if none { /^ --? p(?: ort)?/x } @ARGV;

my $runner = Plack::Runner->new();
$runner->parse_options(@ARGV);

my $server = Pinto::Server->new(%opts);
my $app    = $server->to_app();

$runner->run($app);


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



=pod

=for :stopwords Jeffrey Ryan Thalhammer Imaginative Software Systems

=head1 NAME

pinto-server - provide a web interface to a Pinto repository

=head1 VERSION

version 0.035

=head1 SYNOPSIS

  pinto-server --root=/path/to/repository [--daemon] [--port=N]

=head1 DESCRIPTION

Before running C<pinto-server> you must first create a Pinto
repository.  See L<pinto-admin> for instructions on that.

C<pinto-server> provides a web API to a L<Pinto> repository.  Remote
clients (like L<pinto-remote>) can use this API to add distributions,
remove packages, and list the contents of the Pinto repository.  In
addition, C<pinto-server> serves up the contents of your repository, so
you can use it as the source of distributions for L<cpan> or L<cpanm>.

=head1 ARGUMENTS

=over 4

=item --root=PATH

The path to the root directory of the Pinto repository you wish to
serve.

=back

=head1 OPTIONS

=over 4

=item --auth

Indicates the an option describing the authentication scheme to use
(default is no authentication).  Each time this is used, a key=value pair must
follow; one of them must be 'backend', which should correspond to a class in
the L<Authen::Simple> namespace, e.g. backend=Kerberos would indicate that
Kerberos authentication will be used, with the L<Authen::Simple::Kerberos>
backend.

Options that follow will be passed as-is to the authentication backend.

For example, this would be a valid configuration for Kerberos:

  --auth backend=Kerberos --auth realm=REALM.COMPANY.COM

and this is how the authentication backend will be constructed:

  my $auth = Authen::Simple::Kerberos->new(
    realm => 'REALM.COMPANY.COM'
  );

=item other options

All other options supported by L<plackup> are supported too, such as
C<--server>, C<--port>, C<--daemonize>, etc.  These will be passed to
L<Plack::Runner>.

=back

=head1 DEPLOYMENT

C<pinto-server> is PSGI compatible, running under L<Plack::Runner> by
default.  It will use whatever backend you specify on the command line
or have configured in your environment.

If you wish to add your own middleware and/or customize the backend in
other ways, you can use L<Pinto::Server> in a custom .psgi script like
this:

    # my-pinto-server.psgi

    my %opts   = (...);
    my $server = Pinto::Server->new(%opts);
    my $app    = $server->to_app();

    # wrap $app with middlewares here and/or
    # insert code customized for your backend
    # which operates on the $app

Then you may directly launch F<my-pinto-server.psgi> using L<plackup>.

=head1 CAVEATS

If you are running C<pinto-server> and have configured L<Pinto> to use
a VCS-based store, such as L<Pinto::Store::VCS::Svn> or
L<Pinto::Store::VCS::Git>, then you must not mess with the VCS
directly (at least not the part of the VCS that holds the Pinto
repository).  This is because C<pinto-server> only initializes the
working copy of the repository at startup.  Thereafter, it assumes
that it is the only actor affecting the Pinto repository within the
VCS.  If you start modifying Pinto's area of the VCS directly, then
the working copy for C<pinto-server> will become out of date and
conflicts will happen.

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


