* Make pagespec_match on failure return a value that is false, but in a
authorjoey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>
Fri, 27 Apr 2007 07:55:40 +0000 (07:55 +0000)
committerjoey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>
Fri, 27 Apr 2007 07:55:40 +0000 (07:55 +0000)
  scalar context, evaluates to a reason why the match failed.
* Add testpagespec plugin, which might be useful to see why a pagespec isn't
  matching something.

IkiWiki.pm
IkiWiki/Plugin/conditional.pm
IkiWiki/Plugin/testpagespec.pm [new file with mode: 0644]
debian/changelog
doc/plugins/testpagespec.mdwn [new file with mode: 0644]
doc/plugins/write.mdwn
po/gu.po
po/ikiwiki.pot
t/pagespec_match.t

index 7c910a53dfe62b6a88c5c7c85714318739c91663..88d6d442b9c28b5cf2ab420b2b663158b5c5258e 100644 (file)
@@ -998,9 +998,23 @@ sub pagespec_match ($$;@) { #{{{
                unshift @params, "location";
        }
 
                unshift @params, "location";
        }
 
-       return eval pagespec_translate($spec);
+       my $ret=eval pagespec_translate($spec);
+       return IkiWiki::FailReason->new("syntax error") if $@;
+       return $ret;
 } #}}}
 
 } #}}}
 
+package IkiWiki::FailReason;
+
+use overload (
+       '""' => sub { return ${$_[0]} },
+       '0+' => sub { return 0 },
+       fallback => 1,
+);
+
+sub new {
+       bless \$_[1], $_[0];
+}
+
 package IkiWiki::PageSpec;
 
 sub match_glob ($$;@) { #{{{
 package IkiWiki::PageSpec;
 
 sub match_glob ($$;@) { #{{{
@@ -1022,7 +1036,12 @@ sub match_glob ($$;@) { #{{{
        $glob=~s/\\\*/.*/g;
        $glob=~s/\\\?/./g;
 
        $glob=~s/\\\*/.*/g;
        $glob=~s/\\\?/./g;
 
-       return $page=~/^$glob$/i;
+       if ($page=~/^$glob$/i) {
+               return 1
+       }
+       else {
+               return IkiWiki::FailReason->new("$glob does not match $page");
+       }
 } #}}}
 
 sub match_link ($$;@) { #{{{
 } #}}}
 
 sub match_link ($$;@) { #{{{
@@ -1040,13 +1059,13 @@ sub match_link ($$;@) { #{{{
        }
 
        my $links = $IkiWiki::links{$page} or return undef;
        }
 
        my $links = $IkiWiki::links{$page} or return undef;
-       return 0 unless @$links;
+       return IkiWiki::FailReason->new("$page has no links") unless @$links;
        my $bestlink = IkiWiki::bestlink($from, $link);
        my $bestlink = IkiWiki::bestlink($from, $link);
-       return 0 unless length $bestlink;
+       return IkiWiki::FailReason->new("no such link") unless length $bestlink;
        foreach my $p (@$links) {
                return 1 if $bestlink eq IkiWiki::bestlink($page, $p);
        }
        foreach my $p (@$links) {
                return 1 if $bestlink eq IkiWiki::bestlink($page, $p);
        }
-       return 0;
+       return IkiWiki::FailReason->new("$page does not link to $link");
 } #}}}
 
 sub match_backlink ($$;@) { #{{{
 } #}}}
 
 sub match_backlink ($$;@) { #{{{
@@ -1061,7 +1080,7 @@ sub match_created_before ($$;@) { #{{{
                return $IkiWiki::pagectime{$page} < $IkiWiki::pagectime{$testpage};
        }
        else {
                return $IkiWiki::pagectime{$page} < $IkiWiki::pagectime{$testpage};
        }
        else {
-               return 0;
+               return IkiWiki::FailReason->new("$page not created before $testpage");
        }
 } #}}}
 
        }
 } #}}}
 
@@ -1073,20 +1092,23 @@ sub match_created_after ($$;@) { #{{{
                return $IkiWiki::pagectime{$page} > $IkiWiki::pagectime{$testpage};
        }
        else {
                return $IkiWiki::pagectime{$page} > $IkiWiki::pagectime{$testpage};
        }
        else {
-               return 0;
+               return IkiWiki::FailReason->new("$page not created after $testpage");
        }
 } #}}}
 
 sub match_creation_day ($$;@) { #{{{
        }
 } #}}}
 
 sub match_creation_day ($$;@) { #{{{
-       return ((gmtime($IkiWiki::pagectime{shift()}))[3] == shift);
+       return 1 if ((gmtime($IkiWiki::pagectime{shift()}))[3] == shift);
+       return IkiWiki::FailReason->new("creation_day did not match");
 } #}}}
 
 sub match_creation_month ($$;@) { #{{{
 } #}}}
 
 sub match_creation_month ($$;@) { #{{{
-       return ((gmtime($IkiWiki::pagectime{shift()}))[4] + 1 == shift);
+       return 1 if ((gmtime($IkiWiki::pagectime{shift()}))[4] + 1 == shift);
+       return IkiWiki::FailReason->new("creation_month did not match");
 } #}}}
 
 sub match_creation_year ($$;@) { #{{{
 } #}}}
 
 sub match_creation_year ($$;@) { #{{{
-       return ((gmtime($IkiWiki::pagectime{shift()}))[5] + 1900 == shift);
+       return 1 if ((gmtime($IkiWiki::pagectime{shift()}))[5] + 1900 == shift);
+       return IkiWiki::FailReason->new("creation_year did not match");
 } #}}}
 
 sub match_user ($$;@) { #{{{
 } #}}}
 
 sub match_user ($$;@) { #{{{
@@ -1094,8 +1116,9 @@ sub match_user ($$;@) { #{{{
        my $user=shift;
        my %params=@_;
 
        my $user=shift;
        my %params=@_;
 
-       return unless exists $params{user};
-       return $user eq $params{user};
+       return IkiWiki::FailReason->new("cannot match user") unless exists $params{user};
+       return 1 if $user eq $params{user};
+       return IkiWiki::FailReason->new("user is not $user");
 } #}}}
 
 1
 } #}}}
 
 1
index 29223ace24ef419bfb23bdd468a061bdebfdac19..58e2b04b954b80eca221f7d62e05027a8ffa0d01 100644 (file)
@@ -62,7 +62,8 @@ sub match_enabled ($$;@) { #{{{
        my $plugin=shift;
        
        # test if the plugin is enabled
        my $plugin=shift;
        
        # test if the plugin is enabled
-       return UNIVERSAL::can("IkiWiki::Plugin::".$plugin, "import");
+       return 1 if UNIVERSAL::can("IkiWiki::Plugin::".$plugin, "import");
+       return IkiWiki::FailReason->new("$plugin is not enabled");
 } #}}}
 
 sub match_sourcepage ($$;@) { #{{{
 } #}}}
 
 sub match_sourcepage ($$;@) { #{{{
@@ -70,8 +71,9 @@ sub match_sourcepage ($$;@) { #{{{
        my $glob=shift;
        my %params=@_;
 
        my $glob=shift;
        my %params=@_;
 
-       return unless exists $params{sourcepage};
-       return match_glob($params{sourcepage}, $glob, @_);
+       return IkiWiki::FailReason->new("cannot match sourcepage") unless exists $params{sourcepage};
+       return 1 if match_glob($params{sourcepage}, $glob, @_);
+       return IkiWiki::FailReason->new("sourcepage does not match $glob");
 } #}}}
 
 sub match_destpage ($$;@) { #{{{
 } #}}}
 
 sub match_destpage ($$;@) { #{{{
@@ -79,8 +81,9 @@ sub match_destpage ($$;@) { #{{{
        my $glob=shift;
        my %params=@_;
        
        my $glob=shift;
        my %params=@_;
        
-       return unless exists $params{destpage};
-       return match_glob($params{destpage}, $glob, @_);
+       return IkiWiki::FailReason->new("cannot match destpage") unless exists $params{destpage};
+       return 1 if match_glob($params{destpage}, $glob, @_);
+       return IkiWiki::FailReason->new("destpage does not match $glob");
 } #}}}
 
 sub match_included ($$;$) { #{{{
 } #}}}
 
 sub match_included ($$;$) { #{{{
@@ -88,8 +91,9 @@ sub match_included ($$;$) { #{{{
        shift;
        my %params=@_;
 
        shift;
        my %params=@_;
 
-       return unless exists $params{sourcepage} && exists $params{destpage};
-       return $params{sourcepage} ne $params{destpage};
+       return IkiWiki::FailReason->new("cannot match included") unless exists $params{sourcepage} && exists $params{destpage};
+       return 1 if $params{sourcepage} ne $params{destpage};
+       return IkiWiki::FailReason->new("page $params{sourcepage} is not included");
 } #}}}
 
 1
 } #}}}
 
 1
diff --git a/IkiWiki/Plugin/testpagespec.pm b/IkiWiki/Plugin/testpagespec.pm
new file mode 100644 (file)
index 0000000..56dc03c
--- /dev/null
@@ -0,0 +1,23 @@
+#!/usr/bin/perl
+package IkiWiki::Plugin::testpagespec;
+
+use warnings;
+use strict;
+use IkiWiki 2.00;
+
+sub import { #{{{
+       hook(type => "preprocess", id => "testpagespec", call => \&preprocess);
+} # }}}
+
+sub preprocess (@) { #{{{
+       my %params=@_;
+       
+       add_depends($params{page}, $params{pagespec});
+       
+       my $ret=pagespec_match($params{match}, $params{pagespec}, 
+                       location => $params{page});
+       return $ret if ! $ret;
+       return "the pagespec matches";
+} # }}}
+
+1
index 7f6157e898156b02af49ba4deb2308c52c76c332..ee3792892c70f272a9724db740c6f0e09ba20af5 100644 (file)
@@ -30,8 +30,12 @@ ikiwiki (1.51) UNRELEASED; urgency=low
   * Plugin interface version increased to 2.00 since I don't anticipate any
     more interface changes before 2.0.
   * Updated Gujarati translation from Kartik Mistry. Closes: #421198
   * Plugin interface version increased to 2.00 since I don't anticipate any
     more interface changes before 2.0.
   * Updated Gujarati translation from Kartik Mistry. Closes: #421198
+  * Make pagespec_match on failure return a value that is false, but in a
+    scalar context, evaluates to a reason why the match failed.
+  * Add testpagespec plugin, which might be useful to see why a pagespec isn't
+    matching something.
 
 
- -- Joey Hess <joeyh@debian.org>  Fri, 27 Apr 2007 01:30:34 -0400
+ -- Joey Hess <joeyh@debian.org>  Fri, 27 Apr 2007 03:41:52 -0400
 
 ikiwiki (1.50) unstable; urgency=low
 
 
 ikiwiki (1.50) unstable; urgency=low
 
diff --git a/doc/plugins/testpagespec.mdwn b/doc/plugins/testpagespec.mdwn
new file mode 100644 (file)
index 0000000..28e5ba7
--- /dev/null
@@ -0,0 +1,12 @@
+[[template id=plugin name=testpagespec author="[[Joey]]"]]
+[[tag type/useful]]
+
+This plugin allows testing a [[PageSpec]] to see if it matches a page, and
+if not, why it fails to match.
+
+Example use:
+
+       \[[testpagespec pagespec="foopage and barpage" match="foopage"]]
+
+This will print out something like "barpage does not match foopage",
+highlighting which part of the [[PageSpec]] is causing the match to fail.
index d9f25641d9d1ae82e888543902e5d61d91293a96..ef9d412e5081070eb65aba70f316ce95414068e1 100644 (file)
@@ -328,6 +328,10 @@ The most often used is "location", which specifies the location the
 PageSpec should match against. If not passed, relative PageSpecs will match
 relative to the top of the wiki.
 
 PageSpec should match against. If not passed, relative PageSpecs will match
 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($$)`
 
 Given a page and the text of a link on the page, determine which
 #### `bestlink($$)`
 
 Given a page and the text of a link on the page, determine which
@@ -448,4 +452,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
 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
 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
 against. It may also be passed additional, named parameters. It should return
-true if the page matches.
+true if the match succeeds, and either false or a IkiWiki::FailReason object
+if the match fails.
index 5fa46b68703b0c33ea14cda0a690ff1a64648a2e..9a26e9bd6da1c07349611ef0790659f968e6da87 100644 (file)
--- a/po/gu.po
+++ b/po/gu.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ikiwiki-gu\n"
 "Report-Msgid-Bugs-To: \n"
 msgstr ""
 "Project-Id-Version: ikiwiki-gu\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-04-23 14:43-0400\n"
+"POT-Creation-Date: 2007-04-27 03:55-0400\n"
 "PO-Revision-Date: 2007-01-11 16:05+0530\n"
 "Last-Translator: Kartik Mistry <kartik.mistry@gmail.com>\n"
 "Language-Team: Gujarati <team@utkarsh.org>\n"
 "PO-Revision-Date: 2007-01-11 16:05+0530\n"
 "Last-Translator: Kartik Mistry <kartik.mistry@gmail.com>\n"
 "Language-Team: Gujarati <team@utkarsh.org>\n"
@@ -101,8 +101,8 @@ msgid "feed not found"
 msgstr "ફીડ મળ્યું નહી"
 
 #: ../IkiWiki/Plugin/aggregate.pm:278
 msgstr "ફીડ મળ્યું નહી"
 
 #: ../IkiWiki/Plugin/aggregate.pm:278
-#, perl-format
-msgid "invalid UTF-8 stripped from feed"
+#, fuzzy, perl-format
+msgid "(invalid UTF-8 stripped from feed)"
 msgstr "ફીડમાંથી અયોગ્ય રીતે UTF-8 નીકાળેલ છે"
 
 #: ../IkiWiki/Plugin/aggregate.pm:283
 msgstr "ફીડમાંથી અયોગ્ય રીતે UTF-8 નીકાળેલ છે"
 
 #: ../IkiWiki/Plugin/aggregate.pm:283
@@ -118,7 +118,7 @@ msgstr "નવું પાનું %s બનાવે છે"
 msgid "There are no broken links!"
 msgstr "અહીં કોઇ તૂટેલ કડી નથી!"
 
 msgid "There are no broken links!"
 msgstr "અહીં કોઇ તૂટેલ કડી નથી!"
 
-#: ../IkiWiki/Plugin/conditional.pm:20
+#: ../IkiWiki/Plugin/conditional.pm:17
 msgid "\"test\" and \"then\" parameters are required"
 msgstr "\"test\" અને \"then\" વિકલ્પો જરૂરી છે"
 
 msgid "\"test\" and \"then\" parameters are required"
 msgstr "\"test\" અને \"then\" વિકલ્પો જરૂરી છે"
 
@@ -396,23 +396,23 @@ msgstr "ખરાબ પહોળાઇ કિંમત"
 msgid "failed to run php"
 msgstr "php ચલાવવામાં નિષ્ફળ"
 
 msgid "failed to run php"
 msgstr "php ચલાવવામાં નિષ્ફળ"
 
-#: ../IkiWiki/Plugin/table.pm:22
+#: ../IkiWiki/Plugin/table.pm:21
 msgid "cannot find file"
 msgstr "ફાઇલ મળી શકી નહી"
 
 msgid "cannot find file"
 msgstr "ફાઇલ મળી શકી નહી"
 
-#: ../IkiWiki/Plugin/table.pm:45
+#: ../IkiWiki/Plugin/table.pm:44
 msgid "unknown data format"
 msgstr "અજાણ્યો માહિતી પ્રકાર"
 
 msgid "unknown data format"
 msgstr "અજાણ્યો માહિતી પ્રકાર"
 
-#: ../IkiWiki/Plugin/table.pm:53
+#: ../IkiWiki/Plugin/table.pm:52
 msgid "empty data"
 msgstr "ખાલી માહિતી"
 
 msgid "empty data"
 msgstr "ખાલી માહિતી"
 
-#: ../IkiWiki/Plugin/table.pm:73
+#: ../IkiWiki/Plugin/table.pm:72
 msgid "Direct data download"
 msgstr "સીધી માહિતી ડાઉનલોડ"
 
 msgid "Direct data download"
 msgstr "સીધી માહિતી ડાઉનલોડ"
 
-#: ../IkiWiki/Plugin/table.pm:106
+#: ../IkiWiki/Plugin/table.pm:105
 #, perl-format
 msgid "parse fail at line %d: %s"
 msgstr "ઉકેલવાનું લીટી %d પર નિષ્ફળ: %s"
 #, perl-format
 msgid "parse fail at line %d: %s"
 msgstr "ઉકેલવાનું લીટી %d પર નિષ્ફળ: %s"
@@ -512,7 +512,7 @@ msgstr "સંપૂર્ણ"
 #. translators: A list of one or more pages that were changed,
 #. translators: And the name of the user making the change.
 #. translators: This is used as the subject of a commit email.
 #. translators: A list of one or more pages that were changed,
 #. translators: And the name of the user making the change.
 #. translators: This is used as the subject of a commit email.
-#: ../IkiWiki/UserInfo.pm:146
+#: ../IkiWiki/UserInfo.pm:145
 #, perl-format
 msgid "update of %s's %s by %s"
 msgstr "%s નો સુધારો %s નાં %s વડે"
 #, perl-format
 msgid "update of %s's %s by %s"
 msgstr "%s નો સુધારો %s નાં %s વડે"
index 64af1d2a93cf4d4ce2ae9e3cfcf36d0862b26d5a..aaac2ef04c961e452479039559db926dfc52f893 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-04-26 22:52-0400\n"
+"POT-Creation-Date: 2007-04-27 03:55-0400\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
index eac2395edd5553c8e33d1fc14a6c1b6847aaf1a0..f0cadcdc76843a63e3de5f615c70e3521b086978 100755 (executable)
@@ -1,7 +1,7 @@
 #!/usr/bin/perl
 use warnings;
 use strict;
 #!/usr/bin/perl
 use warnings;
 use strict;
-use Test::More tests => 49;
+use Test::More tests => 51;
 
 BEGIN { use_ok("IkiWiki"); }
 
 
 BEGIN { use_ok("IkiWiki"); }
 
@@ -67,6 +67,10 @@ ok(! pagespec_match("foo", "no_such_function(foo)"), "foo");
 ok(pagespec_match("foo", "foo and user(bar)", user => "bar"), "user");
 ok(! pagespec_match("foo", "foo and user(bar)", user => "baz"), "user fail");
 
 ok(pagespec_match("foo", "foo and user(bar)", user => "bar"), "user");
 ok(! pagespec_match("foo", "foo and user(bar)", user => "baz"), "user fail");
 
+my $ret=pagespec_match("foo", "(invalid");
+ok(! $ret, "syntax error");
+ok($ret eq "syntax error", "error message");
+
 # old style globlists
 ok(pagespec_match("foo", "foo bar"), "simple list");
 ok(pagespec_match("bar", "foo bar"), "simple list 2");
 # old style globlists
 ok(pagespec_match("foo", "foo bar"), "simple list");
 ok(pagespec_match("bar", "foo bar"), "simple list 2");