3d431d7516cfe2e6ef823be4e865a132814d52ca
[scpubgit/App-SCS.git] / lib / App / SCS.pm
1 package App::SCS;
2
3 use Module::Runtime qw(use_module);
4 use IO::All;
5 use Moo;
6
7 with 'App::SCS::Role::WithConfig';
8
9 has plugins => (is => 'ro', default => sub { [] });
10
11 has root_dir => (is => 'lazy');
12
13 sub _build_root_dir {
14   my ($self) = @_;
15   # Need to pass '.' rather than undef in the default case - otherwise
16   # IO::All 0.47+ resolves to / (previously undef or '' was '.')
17   io->dir(io->dir($self->config->{root_dir}||'.')->absolute);
18 }
19
20 has share_dir => (is => 'lazy');
21
22 sub _build_share_dir {
23   my ($self) = @_;
24   io->dir($self->config->{share_dir}||$self->root_dir->catdir('share'));
25 }
26
27 has page_plugin_config => (is => 'lazy');
28
29 sub _build_page_plugin_config {
30   my ($self) = @_;
31   return {
32     plugin_map => {
33       do {
34         my %map = map $_->page_plugins, reverse @{$self->plugins};
35         ref($_) or $_ = { class => $_, config => sub {} } for values %map;
36         %map;
37       }
38     },
39     defaults => [
40       map $_->default_page_plugins, @{$self->plugins}
41     ],
42   };
43 }
44
45 has pages => (is => 'lazy');
46
47 sub _build_pages {
48   my ($self) = @_;
49   return use_module('App::SCS::PageSet')->new(
50     base_dir => $self->share_dir->catdir('pages'),
51     plugin_config => $self->page_plugin_config,
52   );
53 }
54
55 has web => (is => 'lazy');
56
57 sub _build_web {
58   my ($self) = @_;
59   return use_module('App::SCS::Web')->new(
60     app => $self
61   );
62 }
63
64 sub BUILD {
65   my ($self) = @_;
66   $self->load_plugin(Core => {});
67   my @plist = @{$self->config->{plugins}||[]};
68   while (my ($name, $conf) = splice @plist, 0, 2) {
69     $self->load_plugin($name, $conf);
70   }
71 }
72
73 sub load_plugin {
74   my ($self, $name, $config) = @_;
75   my $class = ($name =~ s/^\+// ? $name : "App::SCS::Plugin::${name}");
76   push(
77     @{$self->plugins},
78     use_module($class)->new(
79       app => $self,
80       config => $config
81     )
82   );
83   return;
84 }
85
86 sub run_if_script {
87   my $self = shift;
88   if (caller(1)) {
89     my $code;
90     return sub {
91       $code ||= $self->web->to_psgi_app;
92       &$code
93     };
94   } else {
95     return $self->run;
96   }
97 }
98
99 sub run {
100   my $self = shift;
101   my $env = {
102     argv => \@ARGV,
103     stdin => \*STDIN,
104     stdout => \*STDOUT,
105     stderr => \*STDERR,
106   };
107   foreach my $p (@{$self->plugins}) {
108     return if $p->run_cli($env);
109   }
110   $self->web->run;
111 }
112
113 1;