Merge branch 'master' of ssh://git.ikiwiki.info/srv/git/ikiwiki.info
[ikiwiki] / IkiWiki / Setup.pm
1 #!/usr/bin/perl
2 # Ikiwiki setup files are perl files that 'use IkiWiki::Setup::foo',
3 # passing it some sort of configuration data.
4
5 package IkiWiki::Setup;
6
7 use warnings;
8 use strict;
9 use IkiWiki;
10 use open qw{:utf8 :std};
11 use File::Spec;
12
13 sub load ($) {
14         my $setup=IkiWiki::possibly_foolish_untaint(shift);
15         $config{setupfile}=File::Spec->rel2abs($setup);
16
17         #translators: The first parameter is a filename, and the second
18         #translators: is a (probably not translated) error message.
19         open (IN, $setup) || error(sprintf(gettext("cannot read %s: %s"), $setup, $!));
20         my $code;
21         {
22                 local $/=undef;
23                 $code=<IN>;
24         }
25         ($code)=$code=~/(.*)/s;
26         close IN;
27
28         eval $code;
29         error("$setup: ".$@) if $@;
30 }
31
32 sub merge ($) {
33         # Merge setup into existing config and untaint.
34         my %setup=%{shift()};
35
36         if (exists $setup{add_plugins} && exists $config{add_plugins}) {
37                 push @{$setup{add_plugins}}, @{$config{add_plugins}};
38         }
39         if (exists $setup{exclude}) {
40                 push @{$config{wiki_file_prune_regexps}}, $setup{exclude};
41         }
42         foreach my $c (keys %setup) {
43                 if (defined $setup{$c}) {
44                         if (! ref $setup{$c} || ref $setup{$c} eq 'Regexp') {
45                                 $config{$c}=IkiWiki::possibly_foolish_untaint($setup{$c});
46                         }
47                         elsif (ref $setup{$c} eq 'ARRAY') {
48                                 if ($c eq 'wrappers') {
49                                         # backwards compatability code
50                                         $config{$c}=$setup{$c};
51                                 }
52                                 else {
53                                         $config{$c}=[map { IkiWiki::possibly_foolish_untaint($_) } @{$setup{$c}}]
54                                 }
55                         }
56                         elsif (ref $setup{$c} eq 'HASH') {
57                                 foreach my $key (keys %{$setup{$c}}) {
58                                         $config{$c}{$key}=IkiWiki::possibly_foolish_untaint($setup{$c}{$key});
59                                 }
60                         }
61                 }
62                 else {
63                         $config{$c}=undef;
64                 }
65         }
66         
67         if (length $config{cgi_wrapper}) {
68                 push @{$config{wrappers}}, {
69                         cgi => 1,
70                         wrapper => $config{cgi_wrapper},
71                         wrappermode => (defined $config{cgi_wrappermode} ? $config{cgi_wrappermode} : "06755"),
72                 };
73         }
74 }
75
76 sub getsetup () {
77         # Gets all available setup data from all plugins. Returns an
78         # ordered list of [plugin, setup] pairs.
79         my @ret;
80
81         # disable logging to syslog while dumping, broken plugins may
82         # whine when loaded
83         my $syslog=$config{syslog};
84         $config{syslog}=undef;
85
86         # Load all plugins, so that all setup options are available.
87         my @plugins=grep { $_ ne $config{rcs} } sort(IkiWiki::listplugins());
88         unshift @plugins, $config{rcs} if $config{rcs}; # rcs plugin 1st
89         foreach my $plugin (@plugins) {
90                 eval { IkiWiki::loadplugin($plugin) };
91                 if (exists $IkiWiki::hooks{checkconfig}{$plugin}{call}) {
92                         my @s=eval { $IkiWiki::hooks{checkconfig}{$plugin}{call}->() };
93                 }
94         }
95
96         foreach my $plugin (@plugins) {
97                 if (exists $IkiWiki::hooks{getsetup}{$plugin}{call}) {
98                         # use an array rather than a hash, to preserve order
99                         my @s=eval { $IkiWiki::hooks{getsetup}{$plugin}{call}->() };
100                         next unless @s;
101                         push @ret, [ $plugin, \@s ],
102                 }
103         }
104         
105         $config{syslog}=$syslog;
106
107         return @ret;
108 }
109
110 sub dump ($) {
111         my $file=IkiWiki::possibly_foolish_untaint(shift);
112         
113         require IkiWiki::Setup::Standard;
114         my @dump=IkiWiki::Setup::Standard::gendump("Setup file for ikiwiki.");
115
116         open (OUT, ">", $file) || die "$file: $!";
117         print OUT "$_\n" foreach @dump;
118         close OUT;
119 }
120
121 1