#!/usr/bin/perl -w use strict; use FindBin; use lib "$FindBin::RealBin/../lib"; use Getopt::Long; use YAML; use Plack::Runner; use File::Pid; use File::Spec::Functions qw{catfile rel2abs}; use Cwd; GetOptions( 'file=s' => \my $CONFIG_FILE, 'verbose|v' => \my $VERBOSE, 'D=s' => \my %DEFINES, ); my %default_config = ( server_root => cwd, port => 5000, access_log => 'access', error_log => 'error', pid_file => 'pid', ); my %run = ( init => sub { $CONFIG_FILE ||= 'server.yml'; my $config = { %default_config, %DEFINES, }; print Dump($config) if $VERBOSE; YAML::DumpFile($CONFIG_FILE, $config); print "Wrote config to $CONFIG_FILE\n" if $VERBOSE; }, run => \&run_server, start => \&start_server, stop => sub { signal_server('QUIT') }, restart => sub { signal_server('HUP') }, ); my $command = shift or die "Usage: $0 <" . join('|', keys %run) . ">\n"; exists $run{$command} or die "Unrecognized command $command\n"; $run{$command}->(); sub get_config { $CONFIG_FILE ||= 'server.yml'; my $config_from_file = -e $CONFIG_FILE ? YAML::LoadFile($CONFIG_FILE) : {}; my $config = { %default_config, %{ $config_from_file }, %DEFINES, }; # make config paths absolute before handing off to the app for my $file_key (qw{dbname htdigest access_log error_log pid_file}) { if ($config->{$file_key}) { $config->{$file_key} = rel2abs($config->{$file_key}, $config->{server_root}); } } warn Dump($config) if $VERBOSE; return $config; } sub run_server { my $config = get_config(); require BookmarksApp; my $app = BookmarksApp->new({ config => $config })->to_app; my $runner = Plack::Runner->new(server => 'Starman'); $runner->parse_options( '--listen', ':' . $config->{port}, ); $runner->run($app); } sub start_server { my $config = get_config(); require BookmarksApp; my $app = BookmarksApp->new({ config => $config })->to_app; my $runner = Plack::Runner->new(server => 'Starman'); $runner->parse_options( '--daemonize', '--listen', ':' . $config->{port}, '--pid', $config->{pid_file}, '--error-log', $config->{error_log}, '--access-log', $config->{access_log}, ); $runner->run($app); } sub signal_server { my $config = get_config(); my $signal = shift; my $pid_path = $config->{pid_file}; unless (-e $pid_path) { warn "$pid_path does not exist\n"; return; } my $pid_file = File::Pid->new({ file => $pid_path, }); if (my $pid = $pid_file->running) { kill $signal, $pid; } }