From 25d8fda79555cac1b057b967e03a3e30a9d0a67b Mon Sep 17 00:00:00 2001 From: Will Le Date: Fri, 17 Nov 2017 17:59:06 +0700 Subject: [PATCH] Item14530: Add new config "RootDir" to unify configuartions of file system paths I propose a new config parameter "RootDir" to have all other dirs set relative to this RootDir. Their relativity is only set up at bootstrap config, and the admin can later freely change them to whatever he/she wants. So the default settings should be: XxxDir = $Foswiki::cfg{RootDir}/xxx, and RootDir is auto-detected (at bootstrap) to be the root dir of the website. --- core/lib/Foswiki.spec | 19 +++++++----- core/lib/Foswiki/Configure/Bootstrap.pm | 35 ++++++++++++++++++---- core/lib/Foswiki/Configure/Load.pm | 1 + core/lib/Foswiki/Configure/Wizards/Save.pm | 14 +++++++-- 4 files changed, 54 insertions(+), 15 deletions(-) diff --git a/core/lib/Foswiki.spec b/core/lib/Foswiki.spec index 9e7cc8a143..7efb2e6296 100644 --- a/core/lib/Foswiki.spec +++ b/core/lib/Foswiki.spec @@ -132,36 +132,41 @@ $Foswiki::cfg{PermittedRedirectHostUrls} = ''; # ---++ File System Paths # Configure the file system locations of key Foswiki directories here. These are usually guessed # correctly during bootstrap. Other file locations are configured within their related sections. + +# **PATH LABEL="Root Directory" FEEDBACK="icon='ui-icon-check';label='Validate Permissions'; method='validate_permissions';title='Validate file permissions. WARNING: this may take a long time on a large system'" CHECK="noemptyok perms:r,'*'" ** +# This is the root file system path where all Foswiki directories should be placed. +# $Foswiki::cfg{RootDir} = '/home/httpd/foswiki'; + # **PATH LABEL="Script Directory" FEEDBACK="icon='ui-icon-check';label='Validate Permissions'; method='validate_permissions';title='Validate file permissions.'" CHECK="noemptyok perms:Dx,'(.txt|.cfg)$'" ** # This is the file system path used to access the Foswiki bin directory. -# $Foswiki::cfg{ScriptDir} = '/home/httpd/foswiki/bin'; +# $Foswiki::cfg{ScriptDir} = '$Foswiki::cfg{RootDir}/bin'; # **PATH LABEL="Pub Directory" FEEDBACK="icon='ui-icon-check';label='Validate Permissions'; method='validate_permissions';title='Validate file permissions. WARNING: this may take a long time on a large system'" CHECK="noemptyok perms:r,'*',wDn,'(,v|,pfv)$'" ** # Attachments store (file path, not URL), must match the attachments URL # path =/foswiki/pub= - for example =/usr/local/foswiki/pub= This directory is # normally accessible from the web. -# $Foswiki::cfg{PubDir} = '/home/httpd/foswiki/pub'; +# $Foswiki::cfg{PubDir} = '$Foswiki::cfg{RootDir}/pub'; # **PATH LABEL="Data Directory" FEEDBACK="icon='ui-icon-check';label='Validate Permissions'; method='validate_permissions';title='Validate file permissions. WARNING: this may take a long time on a large system'" CHECK="noemptyok perms:rwDnpd,'(,v|,pfv)$',r" ** # Topic files store (file path, not URL). For example =/usr/local/foswiki/data=. # This directory must not be web accessible. -# $Foswiki::cfg{DataDir} = '/home/httpd/foswiki/data'; +# $Foswiki::cfg{DataDir} = '$Foswiki::cfg{RootDir}/data'; # **PATH LABEL="Tools Directory" FEEDBACK="icon='ui-icon-check';label='Validate Permissions'; method='validate_permissions'" CHECK="noemptyok perms:rD" ** # File path to tools directory. For example =/usr/local/foswiki/tools=. # This directory must not be web accessible. -# $Foswiki::cfg{ToolsDir} = '/home/httpd/foswiki/tools'; +# $Foswiki::cfg{ToolsDir} = '$Foswiki::cfg{RootDir}/tools'; # **PATH LABEL="Template Directory" FEEDBACK="icon='ui-icon-check';label='Validate Permissions'; method='validate_permissions'" CHECK="noemptyok perms:rD" ** # File path to templates directory. For example =/usr/local/foswiki/templates=. # This directory must not be web accessible. -# $Foswiki::cfg{TemplateDir} = '/home/httpd/foswiki/templates'; +# $Foswiki::cfg{TemplateDir} = '$Foswiki::cfg{RootDir}/templates'; # **PATH LABEL="Locales Directory" FEEDBACK="icon='ui-icon-check';label='Validate Permissions'; method='validate_permissions'" CHECK="noemptyok perms:rD" ** # File path to locale directory. # For example =/usr/local/foswiki/locale=. # This directory must not be web accessible. -# $Foswiki::cfg{LocalesDir} = '/home/httpd/foswiki/locale'; +# $Foswiki::cfg{LocalesDir} = '$Foswiki::cfg{RootDir}/locale'; # **PATH LABEL="Working Directory" ONSAVE FEEDBACK="icon='ui-icon-check';label='Validate Permissions'; method='validate_permissions'" CHECK="noemptyok perms:rw,'[\//]README$',r" ** # Directory where Foswiki stores files that are required for the management @@ -185,7 +190,7 @@ $Foswiki::cfg{PermittedRedirectHostUrls} = ''; # * ={WorkingDir}/registration_approvals= - this is used by the # default Foswiki registration process to store registrations that # are pending verification. -# $Foswiki::cfg{WorkingDir} = '/home/httpd/foswiki/working'; +# $Foswiki::cfg{WorkingDir} = '$Foswiki::cfg{RootDir}/working'; # **PATH LABEL="Safe PATH" CHECK='undefok'** # You can override the default PATH setting to control diff --git a/core/lib/Foswiki/Configure/Bootstrap.pm b/core/lib/Foswiki/Configure/Bootstrap.pm index 0c169a2043..ec93d7b680 100644 --- a/core/lib/Foswiki/Configure/Bootstrap.pm +++ b/core/lib/Foswiki/Configure/Bootstrap.pm @@ -101,13 +101,14 @@ sub setBootstrap { # Bootstrap works out the correct values of these keys my @BOOTSTRAP = - qw( {DataDir} {DefaultUrlHost} {ForceDefaultUrlHost} {DetailedOS} {OS} {PubUrlPath} {ToolsDir} {WorkingDir} - {PubDir} {TemplateDir} {ScriptDir} {ScriptUrlPath} {ScriptUrlPaths}{view} - {ScriptSuffix} {LocalesDir} {Store}{Implementation} {NFCNormalizeFilenames} + qw( {DefaultUrlHost} {ForceDefaultUrlHost} {DetailedOS} {OS} {PubUrlPath} + {ScriptUrlPath} {ScriptUrlPaths}{view} + {ScriptSuffix} {Store}{Implementation} {NFCNormalizeFilenames} {Store}{SearchAlgorithm} {Site}{Locale} ); $Foswiki::cfg{isBOOTSTRAPPING} = 1; push( @{ $Foswiki::cfg{BOOTSTRAP} }, @BOOTSTRAP ); + push( @{ $Foswiki::cfg{BOOTSTRAP} }, keys %{ $Foswiki::cfg{BSDIRS} } ); } =begin TML @@ -189,6 +190,11 @@ sub bootstrapConfig { dir => 'bin', required => 1, validate_file => 'setlib.cfg' + }, + RootDir => { + dir => '', + required => 1, + validate_file => 'bin' } ); @@ -196,8 +202,9 @@ sub bootstrapConfig { # confuse soft links my $root = File::Spec->catdir( $bin, File::Spec->updir() ); $root =~ s{\\}{/}g; - my $fatal = ''; - my $warn = ''; + my $fatal = ''; + my $warn = ''; + my %bsdirs = (); while ( my ( $key, $def ) = each %rel_to_root ) { $Foswiki::cfg{$key} = File::Spec->rel2abs( $def->{dir}, $root ); $Foswiki::cfg{$key} = abs_path( $Foswiki::cfg{$key} ); @@ -227,6 +234,17 @@ sub bootstrapConfig { $warn .= "\n * Note: {$key} could not be guessed. Set it manually!"; } + + # Redirect all subdirs to be relative to the RootDir + if ( $key ne 'RootDir' ) { + $bsdirs{"{$key}"} = '$Foswiki::cfg{RootDir}/' . $def->{dir}; + } + else { + $bsdirs{"{$key}"} = $Foswiki::cfg{$key}; + } + + # But we need to keep those unexpanded values out of $Foswiki::cfg + # until after the last expansion via readConfig(). } # Bootstrap the Site Locale and CharSet @@ -249,6 +267,13 @@ EPITAPH # Don't load LocalSite.cfg if it exists (should normally not exist when bootstrapping) Foswiki::Configure::Load::readConfig( 0, 0, 1, 1 ); + # (At the moment of writing this line,) + # the line above is the **last expansion of $Foswiki::cfg** + $Foswiki::cfg{BSDIRS} = \%bsdirs; + print STDERR "AUTOCONFIG BSDIRS: " + . Data::Dumper->Dump( [ $Foswiki::cfg{BSDIRS} ] ) + if (TRAUTO); + # Detect the OS and DetailedOS workOutOS(); print STDERR diff --git a/core/lib/Foswiki/Configure/Load.pm b/core/lib/Foswiki/Configure/Load.pm index c766d93cd3..9d9a9334c2 100644 --- a/core/lib/Foswiki/Configure/Load.pm +++ b/core/lib/Foswiki/Configure/Load.pm @@ -197,6 +197,7 @@ CODE if ( $^O eq 'MSWin32' ) { #force paths to use '/' + $Foswiki::cfg{RootDir} =~ s|\\|/|g; $Foswiki::cfg{PubDir} =~ s|\\|/|g; $Foswiki::cfg{DataDir} =~ s|\\|/|g; $Foswiki::cfg{ToolsDir} =~ s|\\|/|g; diff --git a/core/lib/Foswiki/Configure/Wizards/Save.pm b/core/lib/Foswiki/Configure/Wizards/Save.pm index c85842f4ce..0180792693 100644 --- a/core/lib/Foswiki/Configure/Wizards/Save.pm +++ b/core/lib/Foswiki/Configure/Wizards/Save.pm @@ -211,6 +211,7 @@ sub save { } my %save; + my %set = %{ $this->param('set') }; # Clear out the configuration and re-initialize it either # with or without the .spec expansion. This also clears the @@ -222,8 +223,13 @@ sub save { foreach my $key ( @{ $Foswiki::cfg{BOOTSTRAP} } ) { eval("(\$save$key)=\$Foswiki::cfg$key=~m/^(.*)\$/"); ASSERT( !$@, $@ ) if DEBUG; - delete $Foswiki::cfg{BOOTSTRAP}; } + delete $Foswiki::cfg{BOOTSTRAP}; + print STDERR "BSDIRS set = " + . Data::Dumper->Dump( [ $Foswiki::cfg{BSDIRS} ] ) + if TRACE_SAVE; + %set = ( %set, %{ $Foswiki::cfg{BSDIRS} } ); + delete $Foswiki::cfg{BSDIRS}; %Foswiki::cfg = (); @@ -244,8 +250,10 @@ sub save { # Get changes from 'set' *without* expanding values. this is # a cut-down from Foswiki::Configure::Query::_getSetParams - if ( $this->param('set') ) { - while ( my ( $k, $v ) = each %{ $this->param('set') } ) { + if (%set) { + print STDERR "Save set = " . Data::Dumper->Dump( [ \%set ] ) + if TRACE_SAVE; + while ( my ( $k, $v ) = each %set ) { my $spec = $root->getValueObject($k); eval("\$spec->{old_value} = \$Foswiki::cfg$k") if $spec; if ( $spec && defined $v && !ref($v) ) {