the kind of perl code that can only be written at 4:30 am
(Get a good message when a PageSpec fails due to a negated success by creating success objects with a reason string, which morph into failure objects when negated.)master
parent
f8a7fb227b
commit
8fa8bd0adb
73
IkiWiki.pm
73
IkiWiki.pm
|
@ -1006,8 +1006,22 @@ sub pagespec_match ($$;@) { #{{{
|
||||||
package IkiWiki::FailReason;
|
package IkiWiki::FailReason;
|
||||||
|
|
||||||
use overload (
|
use overload (
|
||||||
'""' => sub { return ${$_[0]} },
|
'""' => sub { return ${$_[0]} },
|
||||||
'0+' => sub { return 0 },
|
'0+' => sub { return 0 },
|
||||||
|
'!' => sub { bless $_[0], 'IkiWiki::SuccessReason'},
|
||||||
|
fallback => 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
sub new {
|
||||||
|
bless \$_[1], $_[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
package IkiWiki::SuccessReason;
|
||||||
|
|
||||||
|
use overload (
|
||||||
|
'""' => sub { return ${$_[0]} },
|
||||||
|
'0+' => sub { return 1 },
|
||||||
|
'!' => sub { bless $_[0], 'IkiWiki::FailReason'},
|
||||||
fallback => 1,
|
fallback => 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1037,7 +1051,7 @@ sub match_glob ($$;@) { #{{{
|
||||||
$glob=~s/\\\?/./g;
|
$glob=~s/\\\?/./g;
|
||||||
|
|
||||||
if ($page=~/^$glob$/i) {
|
if ($page=~/^$glob$/i) {
|
||||||
return 1
|
return IkiWiki::SuccessReason->new("$glob matches $page");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return IkiWiki::FailReason->new("$glob does not match $page");
|
return IkiWiki::FailReason->new("$glob does not match $page");
|
||||||
|
@ -1063,7 +1077,8 @@ sub match_link ($$;@) { #{{{
|
||||||
my $bestlink = IkiWiki::bestlink($from, $link);
|
my $bestlink = IkiWiki::bestlink($from, $link);
|
||||||
return IkiWiki::FailReason->new("no such link") unless length $bestlink;
|
return IkiWiki::FailReason->new("no such link") unless length $bestlink;
|
||||||
foreach my $p (@$links) {
|
foreach my $p (@$links) {
|
||||||
return 1 if $bestlink eq IkiWiki::bestlink($page, $p);
|
return IkiWiki::SuccessReason->new("$page links to $link")
|
||||||
|
if $bestlink eq IkiWiki::bestlink($page, $p);
|
||||||
}
|
}
|
||||||
return IkiWiki::FailReason->new("$page does not link to $link");
|
return IkiWiki::FailReason->new("$page does not link to $link");
|
||||||
} #}}}
|
} #}}}
|
||||||
|
@ -1077,10 +1092,15 @@ sub match_created_before ($$;@) { #{{{
|
||||||
my $testpage=shift;
|
my $testpage=shift;
|
||||||
|
|
||||||
if (exists $IkiWiki::pagectime{$testpage}) {
|
if (exists $IkiWiki::pagectime{$testpage}) {
|
||||||
return $IkiWiki::pagectime{$page} < $IkiWiki::pagectime{$testpage};
|
if ($IkiWiki::pagectime{$page} < $IkiWiki::pagectime{$testpage}) {
|
||||||
|
IkiWiki::SuccessReason->new("$page created before $testpage");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
IkiWiki::FailReason->new("$page not created before $testpage");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return IkiWiki::FailReason->new("$page not created before $testpage");
|
return IkiWiki::FailReason->new("$testpage has no ctime");
|
||||||
}
|
}
|
||||||
} #}}}
|
} #}}}
|
||||||
|
|
||||||
|
@ -1089,26 +1109,43 @@ sub match_created_after ($$;@) { #{{{
|
||||||
my $testpage=shift;
|
my $testpage=shift;
|
||||||
|
|
||||||
if (exists $IkiWiki::pagectime{$testpage}) {
|
if (exists $IkiWiki::pagectime{$testpage}) {
|
||||||
return $IkiWiki::pagectime{$page} > $IkiWiki::pagectime{$testpage};
|
if ($IkiWiki::pagectime{$page} > $IkiWiki::pagectime{$testpage}) {
|
||||||
|
IkiWiki::SuccessReason->new("$page created after $testpage");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
IkiWiki::FailReason->new("$page not created after $testpage");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return IkiWiki::FailReason->new("$page not created after $testpage");
|
return IkiWiki::FailReason->new("$testpage has no ctime");
|
||||||
}
|
}
|
||||||
} #}}}
|
} #}}}
|
||||||
|
|
||||||
sub match_creation_day ($$;@) { #{{{
|
sub match_creation_day ($$;@) { #{{{
|
||||||
return 1 if ((gmtime($IkiWiki::pagectime{shift()}))[3] == shift);
|
if ((gmtime($IkiWiki::pagectime{shift()}))[3] == shift) {
|
||||||
return IkiWiki::FailReason->new("creation_day did not match");
|
return IkiWiki::SuccessReason->new("creation_day matched");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return IkiWiki::FailReason->new("creation_day did not match");
|
||||||
|
}
|
||||||
} #}}}
|
} #}}}
|
||||||
|
|
||||||
sub match_creation_month ($$;@) { #{{{
|
sub match_creation_month ($$;@) { #{{{
|
||||||
return 1 if ((gmtime($IkiWiki::pagectime{shift()}))[4] + 1 == shift);
|
if ((gmtime($IkiWiki::pagectime{shift()}))[4] + 1 == shift) {
|
||||||
return IkiWiki::FailReason->new("creation_month did not match");
|
return IkiWiki::SuccessReason->new("creation_month matched");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return IkiWiki::FailReason->new("creation_month did not match");
|
||||||
|
}
|
||||||
} #}}}
|
} #}}}
|
||||||
|
|
||||||
sub match_creation_year ($$;@) { #{{{
|
sub match_creation_year ($$;@) { #{{{
|
||||||
return 1 if ((gmtime($IkiWiki::pagectime{shift()}))[5] + 1900 == shift);
|
if ((gmtime($IkiWiki::pagectime{shift()}))[5] + 1900 == shift) {
|
||||||
return IkiWiki::FailReason->new("creation_year did not match");
|
return IkiWiki::SuccessReason->new("creation_year matched");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return IkiWiki::FailReason->new("creation_year did not match");
|
||||||
|
}
|
||||||
} #}}}
|
} #}}}
|
||||||
|
|
||||||
sub match_user ($$;@) { #{{{
|
sub match_user ($$;@) { #{{{
|
||||||
|
@ -1117,8 +1154,12 @@ sub match_user ($$;@) { #{{{
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
return IkiWiki::FailReason->new("cannot match user") unless exists $params{user};
|
return IkiWiki::FailReason->new("cannot match user") unless exists $params{user};
|
||||||
return 1 if $user eq $params{user};
|
if ($user eq $params{user}) {
|
||||||
return IkiWiki::FailReason->new("user is not $user");
|
return IkiWiki::SuccessReason->new("user is $user")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return IkiWiki::FailReason->new("user is not $user");
|
||||||
|
}
|
||||||
} #}}}
|
} #}}}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -62,8 +62,12 @@ sub match_enabled ($$;@) { #{{{
|
||||||
my $plugin=shift;
|
my $plugin=shift;
|
||||||
|
|
||||||
# test if the plugin is enabled
|
# test if the plugin is enabled
|
||||||
return 1 if UNIVERSAL::can("IkiWiki::Plugin::".$plugin, "import");
|
if (UNIVERSAL::can("IkiWiki::Plugin::".$plugin, "import")) {
|
||||||
return IkiWiki::FailReason->new("$plugin is not enabled");
|
return IkiWiki::SuccessReason->new("$plugin is enabled");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return IkiWiki::FailReason->new("$plugin is not enabled");
|
||||||
|
}
|
||||||
} #}}}
|
} #}}}
|
||||||
|
|
||||||
sub match_sourcepage ($$;@) { #{{{
|
sub match_sourcepage ($$;@) { #{{{
|
||||||
|
@ -72,8 +76,12 @@ sub match_sourcepage ($$;@) { #{{{
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
return IkiWiki::FailReason->new("cannot match sourcepage") unless exists $params{sourcepage};
|
return IkiWiki::FailReason->new("cannot match sourcepage") unless exists $params{sourcepage};
|
||||||
return 1 if match_glob($params{sourcepage}, $glob, @_);
|
if (match_glob($params{sourcepage}, $glob, @_)) {
|
||||||
return IkiWiki::FailReason->new("sourcepage does not match $glob");
|
return IkiWiki::SuccessReason->new("sourcepage matches $glob");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return IkiWiki::FailReason->new("sourcepage does not match $glob");
|
||||||
|
}
|
||||||
} #}}}
|
} #}}}
|
||||||
|
|
||||||
sub match_destpage ($$;@) { #{{{
|
sub match_destpage ($$;@) { #{{{
|
||||||
|
@ -82,8 +90,12 @@ sub match_destpage ($$;@) { #{{{
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
return IkiWiki::FailReason->new("cannot match destpage") unless exists $params{destpage};
|
return IkiWiki::FailReason->new("cannot match destpage") unless exists $params{destpage};
|
||||||
return 1 if match_glob($params{destpage}, $glob, @_);
|
if (match_glob($params{destpage}, $glob, @_)) {
|
||||||
return IkiWiki::FailReason->new("destpage does not match $glob");
|
return IkiWiki::SuccessReason->new("destpage matches $glob");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return IkiWiki::FailReason->new("destpage does not match $glob");
|
||||||
|
}
|
||||||
} #}}}
|
} #}}}
|
||||||
|
|
||||||
sub match_included ($$;$) { #{{{
|
sub match_included ($$;$) { #{{{
|
||||||
|
@ -92,8 +104,12 @@ sub match_included ($$;$) { #{{{
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
return IkiWiki::FailReason->new("cannot match included") unless exists $params{sourcepage} && exists $params{destpage};
|
return IkiWiki::FailReason->new("cannot match included") unless exists $params{sourcepage} && exists $params{destpage};
|
||||||
return 1 if $params{sourcepage} ne $params{destpage};
|
if ($params{sourcepage} ne $params{destpage}) {
|
||||||
return IkiWiki::FailReason->new("page $params{sourcepage} is not included");
|
return IkiWiki::SuccessReason->new("page $params{sourcepage} is included");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return IkiWiki::FailReason->new("page $params{sourcepage} is not included");
|
||||||
|
}
|
||||||
} #}}}
|
} #}}}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -16,8 +16,12 @@ sub preprocess (@) { #{{{
|
||||||
|
|
||||||
my $ret=pagespec_match($params{match}, $params{pagespec},
|
my $ret=pagespec_match($params{match}, $params{pagespec},
|
||||||
location => $params{page});
|
location => $params{page});
|
||||||
return $ret if ! $ret;
|
if ($ret) {
|
||||||
return "the pagespec matches";
|
return "match: $ret";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return "no match: $ret";
|
||||||
|
}
|
||||||
} # }}}
|
} # }}}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -30,10 +30,10 @@ ikiwiki (1.51) UNRELEASED; urgency=low
|
||||||
* Plugin interface version increased to 2.00 since I don't anticipate any
|
* Plugin interface version increased to 2.00 since I don't anticipate any
|
||||||
more interface changes before 2.0.
|
more interface changes before 2.0.
|
||||||
* Updated Gujarati translation from Kartik Mistry. Closes: #421198
|
* Updated Gujarati translation from Kartik Mistry. Closes: #421198
|
||||||
* Make pagespec_match on failure return a value that is false, but in a
|
* Make pagespec_match return an object that can be stringified to tell
|
||||||
scalar context, evaluates to a reason why the match failed.
|
the reason why the match failed or succeeded.
|
||||||
* Add testpagespec plugin, which might be useful to see why a pagespec isn't
|
* Add testpagespec plugin, which might be useful to see why a pagespec isn't
|
||||||
matching something.
|
working as desired.
|
||||||
|
|
||||||
-- Joey Hess <joeyh@debian.org> Fri, 27 Apr 2007 03:41:52 -0400
|
-- Joey Hess <joeyh@debian.org> Fri, 27 Apr 2007 03:41:52 -0400
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,21 @@
|
||||||
[[tag type/useful]]
|
[[tag type/useful]]
|
||||||
|
|
||||||
This plugin allows testing a [[PageSpec]] to see if it matches a page, and
|
This plugin allows testing a [[PageSpec]] to see if it matches a page, and
|
||||||
if not, why it fails to match.
|
to see the part that matches, or causes the match to fail.
|
||||||
|
|
||||||
Example use:
|
Example uses:
|
||||||
|
|
||||||
\[[testpagespec pagespec="foopage and barpage" match="foopage"]]
|
\[[testpagespec pagespec="foopage and barpage" match="foopage"]]
|
||||||
|
|
||||||
This will print out something like "barpage does not match foopage",
|
This will print out something like "no match: barpage does not match foopage",
|
||||||
highlighting which part of the [[PageSpec]] is causing the match to fail.
|
highlighting which part of the [[PageSpec]] is causing the match to fail.
|
||||||
|
|
||||||
|
\[[testpagespec pagespec="foopage or !bar*" match="barpage"]]
|
||||||
|
|
||||||
|
This will print out something like "no match: bar* matches barpage", since the part
|
||||||
|
of the [[PageSpec]] that fails is this negated match.
|
||||||
|
|
||||||
|
\[[testpagespec pagespec="foopage or barpage" match="barpage"]]
|
||||||
|
|
||||||
|
This will print out something like "match: barpage matches barpage",
|
||||||
|
indicating the part of the [[PageSpec]] that did match.
|
||||||
|
|
|
@ -328,10 +328,6 @@ The most often used is "location", which specifies the location the
|
||||||
PageSpec should match against. If not passed, relative PageSpecs will match
|
PageSpec should match against. If not passed, relative PageSpecs will match
|
||||||
relative to the top of the wiki.
|
relative to the top of the wiki.
|
||||||
|
|
||||||
If the PageSpec fails to match, it may return a IkiWiki::FailReason object,
|
|
||||||
which evaluates to false in a boolean context, but in a string context,
|
|
||||||
evaulates to the reason the PageSpec failed to match.
|
|
||||||
|
|
||||||
#### `bestlink($$)`
|
#### `bestlink($$)`
|
||||||
|
|
||||||
Given a page and the text of a link on the page, determine which
|
Given a page and the text of a link on the page, determine which
|
||||||
|
@ -452,5 +448,5 @@ IkiWiki::PageSpec package, that is named `match_foo`, where "foo()" is
|
||||||
how it will be accessed in a [[PageSpec]]. The function will be passed
|
how it will be accessed in a [[PageSpec]]. The function will be passed
|
||||||
two parameters: The name of the page being matched, and the thing to match
|
two parameters: The name of the page being matched, and the thing to match
|
||||||
against. It may also be passed additional, named parameters. It should return
|
against. It may also be passed additional, named parameters. It should return
|
||||||
true if the match succeeds, and either false or a IkiWiki::FailReason object
|
a IkiWiki::SuccessReason object if the match succeeds, or an
|
||||||
if the match fails.
|
IkiWiki::FailReason object if the match fails.
|
||||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2007-04-27 03:55-0400\n"
|
"POT-Creation-Date: 2007-04-27 04:24-0400\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/perl
|
#!/usr/bin/perl
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use Test::More tests => 51;
|
use Test::More tests => 52;
|
||||||
|
|
||||||
BEGIN { use_ok("IkiWiki"); }
|
BEGIN { use_ok("IkiWiki"); }
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ ok(pagespec_match("a/b/foo", "./*", location => "a/b"), "relative 2");
|
||||||
ok(pagespec_match("a/foo", "./*", "a/b"), "relative oldstyle call");
|
ok(pagespec_match("a/foo", "./*", "a/b"), "relative oldstyle call");
|
||||||
ok(pagespec_match("foo", "./*", location => "a"), "relative toplevel");
|
ok(pagespec_match("foo", "./*", location => "a"), "relative toplevel");
|
||||||
ok(pagespec_match("foo/bar", "*", location => "baz"), "absolute");
|
ok(pagespec_match("foo/bar", "*", location => "baz"), "absolute");
|
||||||
|
ok(! pagespec_match("foo", "foo and bar"), "foo and bar");
|
||||||
|
|
||||||
# The link and backlink stuff needs this.
|
# The link and backlink stuff needs this.
|
||||||
$config{userdir}="";
|
$config{userdir}="";
|
||||||
|
|
Loading…
Reference in New Issue