* 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";
        }
 
-       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 ($$;@) { #{{{
@@ -1022,7 +1036,12 @@ sub match_glob ($$;@) { #{{{
        $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 ($$;@) { #{{{
@@ -1040,13 +1059,13 @@ sub match_link ($$;@) { #{{{
        }
 
        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);
-       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);
        }
-       return 0;
+       return IkiWiki::FailReason->new("$page does not link to $link");
 } #}}}
 
 sub match_backlink ($$;@) { #{{{
@@ -1061,7 +1080,7 @@ sub match_created_before ($$;@) { #{{{
                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 0;
+               return IkiWiki::FailReason->new("$page not created after $testpage");
        }
 } #}}}
 
 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 ($$;@) { #{{{
-       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 ($$;@) { #{{{
-       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 ($$;@) { #{{{
@@ -1094,8 +1116,9 @@ sub match_user ($$;@) { #{{{
        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
index 29223ace24ef419bfb23bdd468a061bdebfdac19..58e2b04b954b80eca221f7d62e05027a8ffa0d01 100644 (file)
@@ -62,7 +62,8 @@ sub match_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 ($$;@) { #{{{
@@ -70,8 +71,9 @@ sub match_sourcepage ($$;@) { #{{{
        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 ($$;@) { #{{{
@@ -79,8 +81,9 @@ sub match_destpage ($$;@) { #{{{
        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 ($$;$) { #{{{
@@ -88,8 +91,9 @@ sub match_included ($$;$) { #{{{
        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
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
+  * 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
 
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.
 
+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
@@ -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
-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"
-"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"
@@ -101,8 +101,8 @@ msgid "feed not found"
 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
@@ -118,7 +118,7 @@ msgstr "નવું પાનું %s બનાવે છે"
 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\" વિકલ્પો જરૂરી છે"
 
@@ -396,23 +396,23 @@ msgstr "ખરાબ પહોળાઇ કિંમત"
 msgid "failed to run php"
 msgstr "php ચલાવવામાં નિષ્ફળ"
 
-#: ../IkiWiki/Plugin/table.pm:22
+#: ../IkiWiki/Plugin/table.pm:21
 msgid "cannot find file"
 msgstr "ફાઇલ મળી શકી નહી"
 
-#: ../IkiWiki/Plugin/table.pm:45
+#: ../IkiWiki/Plugin/table.pm:44
 msgid "unknown data format"
 msgstr "અજાણ્યો માહિતી પ્રકાર"
 
-#: ../IkiWiki/Plugin/table.pm:53
+#: ../IkiWiki/Plugin/table.pm:52
 msgid "empty data"
 msgstr "ખાલી માહિતી"
 
-#: ../IkiWiki/Plugin/table.pm:73
+#: ../IkiWiki/Plugin/table.pm:72
 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"
@@ -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.
-#: ../IkiWiki/UserInfo.pm:146
+#: ../IkiWiki/UserInfo.pm:145
 #, 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"
-"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"
index eac2395edd5553c8e33d1fc14a6c1b6847aaf1a0..f0cadcdc76843a63e3de5f615c70e3521b086978 100755 (executable)
@@ -1,7 +1,7 @@
 #!/usr/bin/perl
 use warnings;
 use strict;
-use Test::More tests => 49;
+use Test::More tests => 51;
 
 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");
 
+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");