#!/usr/bin/env perl

# ABSTRACT: the pinto web server
# PODNAME: pintod

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.042'; # 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;

# TODO: Consider sending the server access log into the log directory
# for the repository by default, so everything is in one place.

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 pintod

=head1 NAME

pintod - the pinto web server

=head1 VERSION

version 0.042

=head1 SYNOPSIS

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

=head1 DESCRIPTION

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

C<pintod> provides a web API to a L<Pinto> repository.  Clients (like
L<pinto>) can use this API to manage and inspect the repository.  In
addition, C<pintod> serves up the distributions within repository, so
you can use it as the backend 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<pintod> 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-pintod.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-pintod.psgi> using L<plackup>.

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


