Item12140: Autochecker port for Offline-Tasks (Or, too many checkers -- and too few)
Priority: Enhancement
Current State: Closed
Released In: 1.1.6
Target Release: patch
Applies To: Engine
Component: Configure
Branches: Release01x01 trunk
This is motivated by configure support for Off-line tasks - though it would have avoided the need for some of last night's checkins.
The core has been in otherwiki for a year as a bugfix/minor patch, so that's how I'm treating it here.
Motivation
The configure architecture makes it mandatory to create a checker (perl module) for every item that needs one. As a result, we end up with a lot of files that are quite boring:
sub check { return shift->checkRE( '{me}')}
is classic.
Plus all the module boilerplate/overhead.
And a lot of things that should have checkers, don't.
Solution
This small patch allows a Type to instantiate a default checker for all items of that type.
If an individual item has a (traditional) checker module, it takes priority. So no change to anything that exists today.
If a Type implements a
makeChecker
method, UI will invoke it to create a checker before assuming there's none to be had.
Note that the
makeChecker
methods don't need to create a unique subroutine for each item. The method can simply return a generic (item-independent) checker object.
With item 12210,
makeChecker
can be avoided in many cases, as the UI will do an expanded search. However, this mechanism provides complete freedom in mapping types to checkers, while the UI's search does not.
Since the other wiki doesn't (currently) do this, packages supplying checkers to both projects might want to use
makeChecker
anyway.
In this example, rather than hardcode a class name for the checker, we map from Types:: to Checkers::. This allows the makeChecker method to
be usefully inherited. It is possible to have more complex mechanisms - but see item 12210 before going down that path.
Example
# Types/FOOO.pm
sub makeChecker {
my $type = shift;
my $class = ref( $type );
$class =~ s/^Foswiki::Configure::Types::/Foswiki::Configure::Checkers::/ or die "Can't makeChecker for $class\n";
eval "require $class;";
die "Unable to makeChecker for ${class}:$@\n" if( $@ );
return $class->new(@_);
}
# Checkers/FooChecker.pm (Typical)
sub check {
my $this = shift;
my $valobj = shift;
my $keys = $valobj->getKeys() or die "No keys for value";
my $value = eval "\$Foswiki::cfg$keys";
return $this->ERROR( "Can't evaluate current value of $keys: $@" ) if( $@ );
my $cfgval = $value;
Foswiki::Configure::Load::expandValue($value);
# Do the work of checking
return $this->showExpandedValue($cfgval) . ($ok? '' : $this->ERROR( "Please correct this error: $e" ));
}
Impact
There is no need to delete existing (boring) item checkers, though that would reduce maintenance efforts and the number of modules that configure has to load.
If REGEX had implemented this, I wouldn't have created 3 new boring modules last night.
In fact, as a Foswiki-only bonus, I've implemented this for REGEX. That way there should never again be a "missing checker" bug for a regex,, and it's a simple (if not quite typical) example for other Types.
Checked in to trunk. Flagged "Needs merge"; I recommend pulling all three files into patch release, though the bare minimum for off-line task support is the patch in UI.pm.
--
TimotheLitt - 11 Oct 2012
Updated example, provided forward reference to Item 12210, which provides additional capabilities for generic checkers.
--
TimotheLitt - 31 Oct 2012