Skip to content

Commit

Permalink
Item12952: phew! decoupled the .spec model building from the UI. That…
Browse files Browse the repository at this point in the history
… was hugely harder than it needed to be. Next step is to break down the checkers into UI and non-UI parts, so that core checker capability exists but doesn't assume any specific UI implementation.

git-svn-id: http://svn.foswiki.org/trunk@17840 0b4bb1d4-4e5a-0410-9cc4-b2b747904278
  • Loading branch information
CrawfordCurrie authored and CrawfordCurrie committed Aug 1, 2014
1 parent 9e4c133 commit e5ffcbc
Show file tree
Hide file tree
Showing 289 changed files with 5,781 additions and 3,462 deletions.
331 changes: 331 additions & 0 deletions ConfigureContrib/bin/configure
Original file line number Diff line number Diff line change
@@ -0,0 +1,331 @@
#! /usr/bin/perl -wT
# -d:NYTProf
# See bottom of file for license and copyright information

=begin TML
Configuration script for Foswiki. Once you have a basic webserver
configuration that lets you access this script, the rest of the
configuration process is done from here.
This script is the dispatcher for several request types, and the container
for session management functions used by all request types.
Detailed TML documentation is available following the __END__ marker.
=cut

use strict;
use warnings;

our $VERSION = '3.0_001';
$ENV{FOSWIKI_ASSERTS} = 1;

sub log;

END {

package Foswiki;
our $configureFork;

if ( exists $INC{'Foswiki.pm'} && !$Foswiki::configureFork ) {
my $message =
"Foswiki ERROR: Some module loaded Foswiki.pm into configure. This is not permitted, and will cause unpredictable results, including corruption of the Foswiki configuration. This is probably caused by a pluggable module, such as a checker, pluggable, or Foswiki Engine code that was inappropriately used (use, require) in configure. This must be tracked-down and removed.\n";
print STDERR $message;
die $message;
}
}

# This is absolutely essential for error reporting. We load it using
# an eval so we can report the problem.
eval "use CGI::Carp qw(fatalsToBrowser)";
if ($@) {
print <<"REPORT";
Content-type: text/plain
Could not load CGI::Carp. Please install this module before continuing.
It can be downloaded from http://www.cpan.org
The error seen was:
$@
REPORT
exit 1;
}

###########################################################
# VERY basic stuff required for configure to work. Any errors
# during this phase will throw a die, which will be picked up
# using CGI::Carp fatalsToBrowser

# Warnings are fatal confession is good for the soul.
#$SIG{'__WARN__'} = sub { die @_ };
#$SIG{'__WARN__'} = sub { Carp::confess( @_) };

eval 'require 5.00503';
die $@ if $@;

# We warn against running Foswiki on an older Perl version than 5.8.8
# but we will not let configure die in this situation. The user
# may have updated many libraries and tweaked Foswiki so let us give
# him a chance.
my $perlversion = $];
if ( $perlversion < 5.008008 ) {
print STDERR <<HERE;
Your perl version is older than 5.8.8.
Foswiki has been successfully tested on Perl 5.8.8 and 5.10.X.
Running Foswiki with an older Perl version requires upgrading of modules and
tweaking of the Foswiki code.
HERE
}

# Get web server's user
our $WebServer_uid = '';

eval { $WebServer_uid = getlogin() || getpwuid($>) || ''; };

my $localLibFailure;

sub _loadBasicModule {
my (@modules) = @_;

foreach my $module (@modules) {
eval "use $module";
if ($@) {
my $reason = "Failed to load the perl module $module. The module ";

# See if we can find the .pm on @INC
my $foundAt = "could not be found. ";
my $modpath = $module;
if ( $modpath =~ /^([\w:]+)/ ) {
$modpath =~ s#::#/#g;
$modpath .= '.pm';
foreach my $path (@INC) {
if ( -e "$path/$modpath" ) {
$foundAt = "was found at $path/$modpath";
if ( !-r "$path/$modpath" ) {
$foundAt .=
", but I don't have permission to read it.";
}
last;
}
}
}
$reason .= $foundAt;

$reason .= <<HERE;
Please ensure that:
1 $module is installed,
2 that the module is available on the \@INC path,
3 that the webserver user ($WebServer_uid) has permission to read the $modpath file.
HERE

$reason .= <<HERE;
The detailed error seen was:
$@
HERE
if ($localLibFailure) {
$reason .= <<HERE;
NOTE that I was unable to load LocalLib.cfg because of the following error:
$localLibFailure
HERE
}
die $reason;
}
}
}

::_loadBasicModule( 'FindBin', 'File::Spec', 'Config', );

# Capture DIE for stack *when debugging*
#$SIG{__DIE__} = sub { Carp::confess( $_[0] || '' ) };
#$SIG{__DIE__} = sub { return if( $^S ); Carp::confess( $_[0] || '' ) };

###########################################################
# Establish the path to the Foswiki library

# Set the working dir to the bin dir
no warnings;
$FindBin::Bin =~ /^(.*)$/;
use warnings;
chdir($1) or die "chdir $1 failed";

my @root = File::Spec->splitdir($1);
my $setlib = File::Spec->catfile( @root, 'setlib.cfg' );
pop(@root);

# Try to load the LocalLib.cfg optional overload
eval "require '$setlib';";
if ($@) {

# No joy. Remember the failure so we can report it later.
$localLibFailure = $@;

# Stick the root/lib on the path; there's a high probability we'll be
# able to find the bits of Foswiki::Configure that way. We will report
# the setlib error later.
unshift( @INC, File::Spec->catfile( @root, 'lib' ) );
}

::_loadBasicModule( 'CGI qw(:any)', 'Foswiki::Configure::CGI', );

$| = 1; # no buffering on STDOUT

# At this point, we have our @INC set by setlib.cfg. We switch to Dispatch
# so that we can use Foswiki::Configure to access global symbols with 'our'
# aliases.

::_loadBasicModule(qw/Foswiki::Configure::Dispatch/);

# This should never return
die "Configure:Dispatch returned to configure boostrap!\n";

1;
__END__
=begin TML
The script works from the top down, by checking features of the
environment before moving on. The sequence is:
1. Check the version of perl
2. Check we have the modules to run this script
3. Check the environment
4. Check we have the modules to load the rest of configure
... and so on. At any stage, the script reports any errors in the
best way it can given the environment established so far.
When the basic checks are complete, the script moves into the
real configuration steps; setting configuration variables.
This phase of the configure environment follows a Model-View-
Controller pattern.
---++ Controller
This script is the controller; it handles communication with the
browser (and thus the user). Communication is very simple; this script
is re-invoked with different 'action' parameters to determine what it does.
---++ Model
The Model consists of a simple node tree, where each node represents a
structural element in the *presentation* of the configuration (this may
not be consistent with the structure of $Foswiki:cfg, so beware). Each
leaf node has an associated Type (in the Types subdirectory) that has
collected model and view behaviours for the basic types.
Class hierarchy
* Foswiki::Configure::Item
* Foswiki::Configure::Value - a leaf value
* Foswiki::Configure::Section - a running node
* Foswiki::Configure::Root - a root section
* Foswiki::Configure::Pluggable - a plug-in subsection
* Foswiki::Configure::Pluggables::FINDEXTENSIONS - etc
* Foswiki::Configure::Checkers::Introduction - should be a Pluggable
* Foswiki::Configure::Checkers::Welcome - should be a Pluggable
* Foswiki::Configure::Checkers::MSWin32 - should be a Pluggable
The Model is independent of the language used to represent the
configuration. There is one parser/generator provided, FoswikiCfg, but it
would be trivial to add others.
---++ View
The View is a DOM document, generated as HTML by a set of UI classes,
all subclasses of Foswiki::Configure::UI. The UI classes visit the
model in order to generate the HTML.
---+++ UIs
Each class in the model (Root, Section, Value, Item) has a corresponding UI
decorator object, which renders HTML for the model. There are also a
number of bespoke UIs, some of which assist =configure= in the generation
of full screens (Introduction, Welcome, AUTH, UPDATE, EXTEND, EXTENSIONS,
UPDATE) and others which relate to the Pluggables (FINDEXTENSIONS, LANGUAGES,
PLUGINS). The special UI CGISetup is a specialised Section focused on groping
the CGI configuration. Several of the bespoke UIs (CGISetup, Introduction,
Welcome) have corresponding Checkers, which act as placeholders in the
model for these sections.
Class hierarchy
* Foswiki::Configure::UI
* Foswiki::Configure::Checker
* Foswiki::Configure::Checkers::* - see below
* Foswiki::Configure::UIs::* - components used in building screens
* Foswiki::Configure::UIs::Item
* Foswiki::Configure::UIs::Section
* Foswiki::Configure::UIs::Root
* Foswiki::Configure::UIs::Introduction
* Foswiki::Configure::UIs::Welcome
* Foswiki::Configure::UIs::MSWin32
* Foswiki::Configure::UIs::* - other UIs for Pluggables and screens
* Foswiki::Configure::UIs::Value
---+++ Checkers
Checkers give checking and guessing support for configuration values. Checkers
are all subclasses of Foswiki::Configure::Checker, and inhabit a class
hierarchy under it that mirrors the organisation of configuration keys in
Foswiki.spec. Checkers include read-only checking UI used for checking
environment sanity (BasicSanity)
Note that when configure is run for the first time (before LocalSite.cfg
has been created) then only the first section of Foswiki.spec is loaded,
and thus checkers only for that subset will be created and run. This means
that on some platforms, initial configuration is a two-phase process, as
the initial path checks are performed on the first run, and only on the
second run, when LocalSite.cfg exists, are the other checkers built and
invoked. This needs improving on.
---+++ Types
Types provide some UI support in the form of type-specific prompters.
This is really an abuse of the Model, but it saves creating
decorator classes for all the Model types.
HTML is generated for the model using Visitor pattern. Each node in the tree
is visited in depth-first order.
Class hierarchy
* Foswiki::Configure::Type - base
* Foswiki::Configure::Types::NUMBER - numerical type (perl float values)
* Foswiki::Configure::Types::OCTAL - octal (permissions)
* Foswiki::Configure::Types::BOOLEAN - boolean type
* Foswiki::Configure::Types::LANGUAGE
* Foswiki::Configure::Types::PERL - perl structure
* Foswiki::Configure::Types::SELECT - select from a list of values
* Foswiki::Configure::Types::SELECTCLASS - select a class from a path
* Foswiki::Configure::Types::STRING - string type
* Foswiki::Configure::Types::REGEX - regular expression
* Foswiki::Configure::Types::COMMAND - shell command
* Foswiki::Configure::Types::PASSWORD - hidden password
* Foswiki::Configure::Types::PATH - file path (/)
* Foswiki::Configure::Types::URL - absolute url path (/)
* Foswiki::Configure::Types::URLPATH - relative url path (/)
* Foswiki::Configure::Types::UNKNOWN - unknown type
TODO:
The type classes are the obvious place to attach client-side javascript
validators, thus releasing the server-side checkers to consider the "deeper"
issues.
=cut
__END__
Foswiki - The Free and Open Source Wiki, http://foswiki.org/
Copyright (C) 2008-2010 Foswiki Contributors. Foswiki Contributors
are listed in the AUTHORS file in the root of this distribution.
NOTE: Please extend that file, not this notice.
Additional copyrights apply to some or all of the code in this
file as follows:
Copyright (C) 2000-2007 TWiki Contributors. All Rights Reserved.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. For
more details read LICENSE in the root of this distribution.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
As per the GPL, removal of this notice is prohibited.
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ our %EXPORT_TAGS = (
config =>
[qw/$badLSC $insane $sanityStatement $unsavedChangesNotice $defaultCfg/],
feedback => [qw/$pendingChanges $changesDiscarded/],
keys => [qw/$configItemRegex/],
keys => [qw/$Foswiki::Configure::Load::ITEMREGEX/],
session => [
qw/SESSIONEXP COOKIEEXP SAVEEXP RESOURCEEXP COOKIENAME RESOURCECACHETIME SESSION_DSN RT80346/,
qw/establishSession/,
Expand Down Expand Up @@ -141,8 +141,6 @@ our ( $pendingChanges, $changesDiscarded, );

# keys - manipulating configuration keys

our ( $configItemRegex, );

# session - session management (not the $sesion variable - see auth)
# See constants above

Expand Down
File renamed without changes.
Loading

0 comments on commit e5ffcbc

Please sign in to comment.