ah, the joys of test-based development..
think I have smart glob list matching working okmaster
parent
f9ce7a571d
commit
47cec07e44
|
@ -158,10 +158,31 @@ sub add_depends ($$) { #{{{
|
||||||
$depends{$page}=$globlist;
|
$depends{$page}=$globlist;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$depends{$page}.=" ".$globlist;
|
$depends{$page}=globlist_merge($depends{$page}, $globlist);
|
||||||
}
|
}
|
||||||
} # }}}
|
} # }}}
|
||||||
|
|
||||||
|
sub globlist_merge ($$) { #{{{
|
||||||
|
my $a=shift;
|
||||||
|
my $b=shift;
|
||||||
|
|
||||||
|
my $ret="";
|
||||||
|
# Only add negated globs if they are not matched by the other globlist.
|
||||||
|
foreach my $i ((map { [ $a, $_ ] } split(" ", $b)),
|
||||||
|
(map { [ $b, $_ ] } split(" ", $a))) {
|
||||||
|
if ($i->[1]=~/^!(.*)/) {
|
||||||
|
if (! globlist_match($1, $i->[0])) {
|
||||||
|
$ret.=" ".$i->[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$ret.=" ".$i->[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
} #}}}
|
||||||
|
|
||||||
sub genpage ($$$) { #{{{
|
sub genpage ($$$) { #{{{
|
||||||
my $content=shift;
|
my $content=shift;
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
|
|
|
@ -27,8 +27,9 @@ ikiwiki (1.1) UNRELEASED; urgency=low
|
||||||
* Split off an IkiWiki.pm out of ikiwiki and have all the other modules use
|
* Split off an IkiWiki.pm out of ikiwiki and have all the other modules use
|
||||||
it, this will allow for adding a unit test suite.
|
it, this will allow for adding a unit test suite.
|
||||||
* Add a unit test for globlist_match().
|
* Add a unit test for globlist_match().
|
||||||
|
* Smart globlist merging.
|
||||||
|
|
||||||
-- Joey Hess <joeyh@debian.org> Tue, 2 May 2006 03:03:21 -0400
|
-- Joey Hess <joeyh@debian.org> Tue, 2 May 2006 10:56:33 -0400
|
||||||
|
|
||||||
ikiwiki (1.0) unstable; urgency=low
|
ikiwiki (1.0) unstable; urgency=low
|
||||||
|
|
||||||
|
|
|
@ -33,10 +33,3 @@
|
||||||
* if a page containing an rss feed happens to show up in an rss feed,
|
* if a page containing an rss feed happens to show up in an rss feed,
|
||||||
the preprocessor directives won't be expanded (good) but are left in
|
the preprocessor directives won't be expanded (good) but are left in
|
||||||
raw rather than removed (bad).
|
raw rather than removed (bad).
|
||||||
* add\_depends() needs work. If there are two preprocessor directives on a page, and one calls add\_depends("foo"), while the other calls add\_depends("* !foo"), the second one wins, page foo will not be matched by the appended globlist.
|
|
||||||
|
|
||||||
What it needs to do is be smarter about merging depends, so if "foo" is added to "!foo", it should yeild "foo"; adding "!foo" to "foo" should again yeild "foo". That's easy, what's hard is when there are globs involved and potentially partially overlapping included and excluded subsets..
|
|
||||||
|
|
||||||
A basic heuristic might be, when merging two globlists, if either contains negated expressions, remove those expressions. This is not ideal, it does avoid it skipping pages that should be in the merged list though.
|
|
||||||
|
|
||||||
A slightly smarter heuristic: When merging two globlists, find negated expressions, de-negate them, and test them to see if they match anything in the other globlist. If so, remove the negated expression, if not, keep. This would probably be good enough.
|
|
|
@ -1,9 +1,11 @@
|
||||||
#!/usr/bin/perl
|
#!/usr/bin/perl
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use Test::More tests => 11;
|
use Test::More tests => 13;
|
||||||
|
|
||||||
BEGIN { use_ok("IkiWiki"); }
|
BEGIN { use_ok("IkiWiki"); }
|
||||||
|
ok(IkiWiki::globlist_match("foo", "foo bar"), "simple list");
|
||||||
|
ok(IkiWiki::globlist_match("bar", "foo bar"), "simple list 2");
|
||||||
ok(IkiWiki::globlist_match("foo", "*"));
|
ok(IkiWiki::globlist_match("foo", "*"));
|
||||||
ok(IkiWiki::globlist_match("foo", "f?? !foz"));
|
ok(IkiWiki::globlist_match("foo", "f?? !foz"));
|
||||||
ok(! IkiWiki::globlist_match("foo", "f?? !foo"));
|
ok(! IkiWiki::globlist_match("foo", "f?? !foo"));
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
use warnings;
|
||||||
|
use strict;
|
||||||
|
use Test::More tests => 25;
|
||||||
|
|
||||||
|
sub same {
|
||||||
|
my $a=shift;
|
||||||
|
my $b=shift;
|
||||||
|
my $match=shift;
|
||||||
|
|
||||||
|
my $imatch=(IkiWiki::globlist_match($match, $a) ||
|
||||||
|
IkiWiki::globlist_match($match, $b));
|
||||||
|
my $cmatch=IkiWiki::globlist_match($match, IkiWiki::globlist_merge($a, $b));
|
||||||
|
|
||||||
|
return $imatch == $cmatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
BEGIN { use_ok("IkiWiki::Render"); }
|
||||||
|
|
||||||
|
ok(same("foo", "bar", "foo"), "basic match 1");
|
||||||
|
ok(same("foo", "bar", "bar"), "basic match 2");
|
||||||
|
ok(same("foo", "bar", "foobar"), "basic failed match");
|
||||||
|
ok(same("foo", "!bar", "foo"), "basic match with inversion");
|
||||||
|
ok(same("foo", "!bar", "bar"), "basic failed match with inversion");
|
||||||
|
ok(same("!foo", "bar", "foo"), "basic failed match with inversion 2");
|
||||||
|
ok(same("!foo", "bar", "bar"), "basic match with inversion 2");
|
||||||
|
ok(same("!foo", "!bar", "foo"), "double inversion failed match");
|
||||||
|
ok(same("!foo", "!bar", "bar"), "double inversion failed match 2");
|
||||||
|
ok(same("*", "!bar", "foo"), "glob+inversion match");
|
||||||
|
ok(same("*", "!bar", "bar"), "matching glob and matching inversion");
|
||||||
|
ok(same("* !foo", "!bar", "bar"), "matching glob and matching inversion");
|
||||||
|
ok(same("* !foo", "!bar", "foo"), "matching glob with matching inversion and non-matching inversion");
|
||||||
|
ok(same("* !foo", "!foo", "foo"), "matching glob with matching inversion and matching inversion");
|
||||||
|
ok(same("b??", "!b??", "bar"), "matching glob and matching inverted glob");
|
||||||
|
ok(same("f?? !f??", "!bar", "bar"), "matching glob and matching inverted glob");
|
||||||
|
ok(same("b??", "!b?z", "bar"), "matching glob and non-matching inverted glob");
|
||||||
|
ok(same("f?? !f?z", "!bar", "bar"), "matching glob and non-matching inverted glob");
|
||||||
|
ok(same("!foo bar baz", "!bar", "bar"), "matching list and matching inversion");
|
||||||
|
ok(IkiWiki::globlist_match("foo/Discussion",
|
||||||
|
IkiWiki::globlist_merge("* !*/Discussion", "*/Discussion")), "should match");
|
||||||
|
ok(same("* !*/Discussion", "*/Discussion", "foo/Discussion"), "Discussion merge 1");
|
||||||
|
ok(same("*/Discussion", "* !*/Discussion", "foo/Discussion"), "Discussion merge 2");
|
||||||
|
ok(same("*/Discussion !*/bar", "*/bar !*/Discussion", "foo/Discussion"), "bidirectional merge 1");
|
||||||
|
ok(same("*/Discussion !*/bar", "*/bar !*/Discussion", "foo/bar"), "bidirectional merge 2");
|
Loading…
Reference in New Issue