lib/TWiki/Configure/Load.pm
author Colas Nahaboo <colas@nahaboo.net>
Sat, 26 Jan 2008 15:50:53 +0100
changeset 0 414e01d06fd5
permissions -rw-r--r--
RELEASE 4.2.0 freetown
     1 # Module of TWiki Enterprise Collaboration Platform, http://TWiki.org/
     2 #
     3 # Copyright (C) 1999-2006 TWiki Contributors. All Rights Reserved.
     4 # TWiki Contributors are listed in the AUTHORS file in the root of
     5 # this distribution. NOTE: Please extend that file, not this notice.
     6 #
     7 # Additional copyrights apply to some or all of the code in this
     8 # file as follows:
     9 #
    10 # This program is free software; you can redistribute it and/or
    11 # modify it under the terms of the GNU General Public License
    12 # as published by the Free Software Foundation; either version 2
    13 # of the License, or (at your option) any later version. For
    14 # more details read LICENSE in the root of this distribution.
    15 #
    16 # This program is distributed in the hope that it will be useful,
    17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    19 #
    20 # As per the GPL, removal of this notice is prohibited.
    21 
    22 =pod
    23 
    24 ---+ package TWiki::Configure::Load
    25 
    26 ---++ Purpose
    27 
    28 This module consists of just a single subroutine =readConfig=.  It allows to
    29 safely modify configuration variables _for one single run_ without affecting
    30 normal TWiki operation.
    31 
    32 =cut
    33 
    34 package TWiki::Configure::Load;
    35 
    36 our $TRUE = 1;
    37 
    38 =pod
    39 
    40 ---++ StaticMethod readConfig()
    41 
    42 In normal TWiki operations as a web server this routine is called by the
    43 =BEGIN= block of =TWiki.pm=.  However, when benchmarking/debugging it can be
    44 replaced by custom code which sets the configuration hash.  To prevent us from
    45 overriding the custom code again, we use an "unconfigurable" key
    46 =$cfg{ConfigurationFinished}= as an indicator.
    47 
    48 Note that this method is called by TWiki and configure, and *only* reads
    49 TWiki.spec= to get defaults. Other spec files (those for extensions) are
    50 *not* read.
    51 
    52 The assumption is that =configure= will be run when an extension is installed,
    53 and that will add the config values to LocalSite.cfg, so no defaults are
    54 needed. TWiki.spec is still read because so much of the core code doesn't
    55 provide defaults, and it would be silly to have them in two places anyway.
    56 
    57 =cut
    58 
    59 sub readConfig {
    60     return if $TWiki::cfg{ConfigurationFinished};
    61 
    62     # Read LocalSite.cfg
    63     unless (do 'TWiki.spec') {
    64         die <<GOLLYGOSH;
    65 Content-type: text/plain
    66 
    67 Perl error when reading TWiki.spec: $@
    68 Please inform the site admin.
    69 GOLLYGOSH
    70         exit 1;
    71     }
    72 
    73     # Read LocalSite.cfg
    74     unless (do 'LocalSite.cfg') {
    75         die <<GOLLYGOSH;
    76 Content-type: text/plain
    77 
    78 Perl error when reading LocalSite.cfg: $@
    79 Please inform the site admin.
    80 GOLLYGOSH
    81         exit 1;
    82     }
    83 
    84     # If we got this far without definitions for key variables, then
    85     # we need to default them. otherwise we get peppered with
    86     # 'uninitialised variable' alerts later.
    87 
    88     foreach my $var qw( DataDir DefaultUrlHost PubUrlPath WorkingDir
    89                         PubDir TemplateDir ScriptUrlPath LocalesDir ) {
    90         # We can't do this, because it prevents TWiki being run without
    91         # a LocalSite.cfg, which we don't want
    92         # die "$var must be defined in LocalSite.cfg"
    93         #  unless( defined $TWiki::cfg{$var} );
    94         $TWiki::cfg{$var} = 'NOT SET' unless defined $TWiki::cfg{$var};
    95     }
    96 
    97     # Expand references to $TWiki::cfg vars embedded in the values of
    98     # other $TWiki::cfg vars.
    99     expand(\%TWiki::cfg);
   100 
   101     $TWiki::cfg{ConfigurationFinished} = 1;
   102 }
   103 
   104 sub expand {
   105     my $hash = shift;
   106 
   107     foreach ( values %$hash ) {
   108         next unless $_;
   109         if (ref($_) eq 'HASH') {
   110             expand(\%$_);
   111         } else {
   112             s/(\$TWiki::cfg{[[A-Za-z0-9{}]+})/eval $1||'undef'/ge;
   113         }
   114     }
   115 }
   116 
   117 
   118 =pod
   119 
   120 ---++ StaticMethod expandValue($string) -> $boolean
   121 
   122 Expands references to TWiki configuration items which occur in the
   123 value of other configuration items.  Use expand($hashref) if the item
   124 is not a plain scalar.
   125 
   126 Happens to return true if something has been expanded, though I don't
   127 know whether you would want that.  The replacement is done in-place,
   128 
   129 =cut
   130 
   131 sub expandValue {
   132     $_[0] =~ s/(\$TWiki::cfg{[[A-Za-z0-9{}]+})/eval $1||'undef'/ge;
   133 }
   134 
   135 =pod
   136 
   137 ---++ StaticMethod readDefaults() -> \@errors
   138 
   139 This is only called by =configure= to initialise the TWiki config hash with
   140 default values from the .spec files.
   141 
   142 Normally all configuration values come from LocalSite.cfg. However when
   143 =configure= runs it has to get default values for config vars that have not
   144 yet been saved to =LocalSite.cfg=.
   145 
   146 Returns a reference to a list of the errors it saw.
   147 
   148 SEE ALSO: TWiki::Configure::TWikiCfg::load
   149 
   150 =cut
   151 
   152 sub readDefaults {
   153     my %read = ( );
   154     my @errors;
   155 
   156     eval {
   157         do 'TWiki.spec';
   158         $read{'TWiki.spec'}  =  $INC{'TWiki.spec'};
   159     };
   160     push(@errors, $@) if ($@);
   161     foreach my $dir (@INC) {
   162         _loadDefaultsFrom("$dir/TWiki/Plugins", $root, \%read, \@errors);
   163         _loadDefaultsFrom("$dir/TWiki/Contrib", $root, \%read, \@errors);
   164     }
   165     return \@errors;
   166 }
   167 
   168 sub _loadDefaultsFrom {
   169     my ($dir, $root, $read, $errors) = @_;
   170 
   171     return unless opendir(D, $dir);
   172     foreach my $extension ( grep { !/^\./ } readdir D) {
   173         next if $read->{$extension};
   174         my $file = "$dir/$extension/Config.spec";
   175         next unless -e $file;
   176         eval {
   177             do $file;
   178         };
   179         push(@$errors, $@) if ($@);
   180         $read->{$extension} = $file;
   181     }
   182     closedir(D);
   183 }
   184 
   185 1;