add type info to influence information

master
Joey Hess 2009-10-07 21:48:03 -04:00
parent 83b9bf54ec
commit 5f9860e65c
6 changed files with 60 additions and 49 deletions

View File

@ -1795,8 +1795,10 @@ sub add_depends ($$;@) {
return if $@; return if $@;
foreach my $p (keys %pagesources) { foreach my $p (keys %pagesources) {
my $r=$sub->($p, location => $page ); my $r=$sub->($p, location => $page );
map { $depends_simple{$page}{lc $_} |= $DEPEND_CONTENT } $r->influences my %i=$r->influences;
if $r; foreach my $i (keys %i) {
$depends_simple{$page}{lc $i} |= $i{$i};
}
} }
$depends{$page}{$pagespec} |= $deptype; $depends{$page}{$pagespec} |= $deptype;
@ -1998,8 +2000,8 @@ use overload (
'""' => sub { $_[0][0] }, '""' => sub { $_[0][0] },
'0+' => sub { 0 }, '0+' => sub { 0 },
'!' => sub { bless $_[0], 'IkiWiki::SuccessReason'}, '!' => sub { bless $_[0], 'IkiWiki::SuccessReason'},
'&' => sub { $_[0][1]={%{$_[0][1]}, %{$_[1][1]}}; $_[0] }, '&' => sub { $_[0]->merge_influences($_[1]); $_[0] },
'|' => sub { $_[1][1]={%{$_[0][1]}, %{$_[1][1]}}; $_[1] }, '|' => sub { $_[1]->merge_influences($_[0]); $_[1] },
fallback => 1, fallback => 1,
); );
@ -2011,19 +2013,27 @@ use overload (
'""' => sub { $_[0][0] }, '""' => sub { $_[0][0] },
'0+' => sub { 1 }, '0+' => sub { 1 },
'!' => sub { bless $_[0], 'IkiWiki::FailReason'}, '!' => sub { bless $_[0], 'IkiWiki::FailReason'},
'&' => sub { $_[1][1]={%{$_[0][1]}, %{$_[1][1]}}; $_[1] }, '&' => sub { $_[1]->merge_influences($_[0]); $_[1] },
'|' => sub { $_[0][1]={%{$_[0][1]}, %{$_[1][1]}}; $_[0] }, '|' => sub { $_[0]->merge_influences($_[1]); $_[0] },
fallback => 1, fallback => 1,
); );
sub new { sub new {
my $class = shift; my $class = shift;
my $value = shift; my $value = shift;
return bless [$value, {map { $_ => 1 } @_}], $class; return bless [$value, {@_}], $class;
} }
sub influences { sub influences {
return keys %{$_[0][1]}; return %{$_[0][1]};
}
sub merge_influences {
my $this=shift;
my $other=shift;
foreach my $influence (keys %{$other->[1]}) {
$this->[1]{$influence} |= $other->[1]{$influence};
}
} }
package IkiWiki::ErrorReason; package IkiWiki::ErrorReason;
@ -2079,23 +2089,24 @@ sub match_link ($$;@) {
my $from=exists $params{location} ? $params{location} : ''; my $from=exists $params{location} ? $params{location} : '';
my $links = $IkiWiki::links{$page}; my $links = $IkiWiki::links{$page};
return IkiWiki::FailReason->new("$page has no links", $page) unless $links && @{$links}; return IkiWiki::FailReason->new("$page has no links", $page => $IkiWiki::DEPEND_LINKS)
unless $links && @{$links};
my $bestlink = IkiWiki::bestlink($from, $link); my $bestlink = IkiWiki::bestlink($from, $link);
foreach my $p (@{$links}) { foreach my $p (@{$links}) {
if (length $bestlink) { if (length $bestlink) {
return IkiWiki::SuccessReason->new("$page links to $link", $page) return IkiWiki::SuccessReason->new("$page links to $link", $page => $IkiWiki::DEPEND_LINKS)
if $bestlink eq IkiWiki::bestlink($page, $p); if $bestlink eq IkiWiki::bestlink($page, $p);
} }
else { else {
return IkiWiki::SuccessReason->new("$page links to page $p matching $link", $page) return IkiWiki::SuccessReason->new("$page links to page $p matching $link", $page => $IkiWiki::DEPEND_LINKS)
if match_glob($p, $link, %params); if match_glob($p, $link, %params);
my ($p_rel)=$p=~/^\/?(.*)/; my ($p_rel)=$p=~/^\/?(.*)/;
$link=~s/^\///; $link=~s/^\///;
return IkiWiki::SuccessReason->new("$page links to page $p_rel matching $link", $page) return IkiWiki::SuccessReason->new("$page links to page $p_rel matching $link", $page => $IkiWiki::DEPEND_LINKS)
if match_glob($p_rel, $link, %params); if match_glob($p_rel, $link, %params);
} }
} }
return IkiWiki::FailReason->new("$page does not link to $link", $page); return IkiWiki::FailReason->new("$page does not link to $link", $page => $IkiWiki::DEPEND_LINKS);
} }
sub match_backlink ($$;@) { sub match_backlink ($$;@) {
@ -2111,14 +2122,14 @@ sub match_created_before ($$;@) {
if (exists $IkiWiki::pagectime{$testpage}) { if (exists $IkiWiki::pagectime{$testpage}) {
if ($IkiWiki::pagectime{$page} < $IkiWiki::pagectime{$testpage}) { if ($IkiWiki::pagectime{$page} < $IkiWiki::pagectime{$testpage}) {
return IkiWiki::SuccessReason->new("$page created before $testpage", $testpage); return IkiWiki::SuccessReason->new("$page created before $testpage", $testpage => $IkiWiki::DEPEND_PRESENCE);
} }
else { else {
return IkiWiki::FailReason->new("$page not created before $testpage", $testpage); return IkiWiki::FailReason->new("$page not created before $testpage", $testpage => $IkiWiki::DEPEND_PRESENCE);
} }
} }
else { else {
return IkiWiki::ErrorReason->new("$testpage does not exist", $testpage); return IkiWiki::ErrorReason->new("$testpage does not exist", $testpage => $IkiWiki::DEPEND_PRESENCE);
} }
} }
@ -2131,14 +2142,14 @@ sub match_created_after ($$;@) {
if (exists $IkiWiki::pagectime{$testpage}) { if (exists $IkiWiki::pagectime{$testpage}) {
if ($IkiWiki::pagectime{$page} > $IkiWiki::pagectime{$testpage}) { if ($IkiWiki::pagectime{$page} > $IkiWiki::pagectime{$testpage}) {
return IkiWiki::SuccessReason->new("$page created after $testpage", $testpage); return IkiWiki::SuccessReason->new("$page created after $testpage", $testpage => $IkiWiki::DEPEND_PRESENCE);
} }
else { else {
return IkiWiki::FailReason->new("$page not created after $testpage", $testpage); return IkiWiki::FailReason->new("$page not created after $testpage", $testpage => $IkiWiki::DEPEND_PRESENCE);
} }
} }
else { else {
return IkiWiki::ErrorReason->new("$testpage does not exist", $testpage); return IkiWiki::ErrorReason->new("$testpage does not exist", $testpage => $IkiWiki::DEPEND_PRESENCE);
} }
} }

View File

@ -291,14 +291,14 @@ sub match {
if (defined $val) { if (defined $val) {
if ($val=~/^$re$/i) { if ($val=~/^$re$/i) {
return IkiWiki::SuccessReason->new("$re matches $field of $page", $page); return IkiWiki::SuccessReason->new("$re matches $field of $page", $page => $IkiWiki::DEPEND_CONTENT);
} }
else { else {
return IkiWiki::FailReason->new("$re does not match $field of $page", $page); return IkiWiki::FailReason->new("$re does not match $field of $page", $page => $IkiWiki::DEPEND_CONTENT);
} }
} }
else { else {
return IkiWiki::FailReason->new("$page does not have a $field", $page); return IkiWiki::FailReason->new("$page does not have a $field", $page => $IkiWiki::DEPEND_CONTENT);
} }
} }

View File

@ -982,9 +982,9 @@ an IkiWiki::FailReason object if the match fails. If the match cannot be
attempted at all, for any page, it can instead return an attempted at all, for any page, it can instead return an
IkiWiki::ErrorReason object explaining why. IkiWiki::ErrorReason object explaining why.
When constructing these objects, you should also include a list of any When constructing these objects, you should also include information about
pages whose contents or other metadata influenced the result of the match. of any pages whose contents or other metadata influenced the result of the
For example, "backlink(foo)" is influenced by the contents of page foo; match. For example, "backlink(foo)" is influenced by the contents of page foo;
"link(foo)" and "title(bar)" are influenced by the contents of any "link(foo)" and "title(bar)" are influenced by the contents of any
page they match; "created_before(foo)" is influenced by the metadata of page they match; "created_before(foo)" is influenced by the metadata of
foo; while "glob(*)" is not influenced by the contents of any page. foo; while "glob(*)" is not influenced by the contents of any page.

View File

@ -16,5 +16,5 @@ use IkiWiki::Setup::Standard {
userdir => "users", userdir => "users",
usedirs => 0, usedirs => 0,
prefix_directives => 1, prefix_directives => 1,
add_plugins => [qw{goodstuff version haiku polygen fortune}], add_plugins => [qw{linkmap goodstuff version haiku polygen fortune}],
} }

View File

@ -57,17 +57,17 @@ ok($IkiWiki::depends{foo0}{"*"} & ($IkiWiki::DEPEND_CONTENT | $IkiWiki::DEPEND_L
ok(! ($IkiWiki::depends{foo0}{"*"} & $IkiWiki::DEPEND_PRESENCE)); ok(! ($IkiWiki::depends{foo0}{"*"} & $IkiWiki::DEPEND_PRESENCE));
# Adding a pagespec that requires page metadata should add the influence # Adding a pagespec that requires page metadata should add the influence
# as an explicit content dependency. # as an explicit dependency. In the case of a link, a links dependency.
$links{foo0}=$links{foo9}=[qw{bar baz}]; $links{foo0}=$links{foo9}=[qw{bar baz}];
foreach my $spec ("* and ! link(bar)", "* or link(bar)") { foreach my $spec ("* and ! link(bar)", "* or link(bar)") {
ok(add_depends("foo3", $spec, presence => 1)); ok(add_depends("foo3", $spec, presence => 1));
ok($IkiWiki::depends{foo3}{$spec} & $IkiWiki::DEPEND_PRESENCE); ok($IkiWiki::depends{foo3}{$spec} & $IkiWiki::DEPEND_PRESENCE);
ok(! ($IkiWiki::depends{foo3}{$spec} & ($IkiWiki::DEPEND_CONTENT | $IkiWiki::DEPEND_LINKS))); ok(! ($IkiWiki::depends{foo3}{$spec} & ($IkiWiki::DEPEND_CONTENT | $IkiWiki::DEPEND_LINKS)));
ok($IkiWiki::depends_simple{foo3}{foo3} == $IkiWiki::DEPEND_CONTENT); ok($IkiWiki::depends_simple{foo3}{foo3} == $IkiWiki::DEPEND_LINKS);
ok(add_depends("foo4", $spec, links => 1)); ok(add_depends("foo4", $spec, links => 1));
ok($IkiWiki::depends{foo4}{$spec} & $IkiWiki::DEPEND_LINKS); ok($IkiWiki::depends{foo4}{$spec} & $IkiWiki::DEPEND_LINKS);
ok(! ($IkiWiki::depends{foo4}{$spec} & ($IkiWiki::DEPEND_CONTENT | $IkiWiki::DEPEND_PRESENCE))); ok(! ($IkiWiki::depends{foo4}{$spec} & ($IkiWiki::DEPEND_CONTENT | $IkiWiki::DEPEND_PRESENCE)));
ok($IkiWiki::depends_simple{foo4}{foo4} == $IkiWiki::DEPEND_CONTENT); ok($IkiWiki::depends_simple{foo4}{foo4} == $IkiWiki::DEPEND_LINKS);
} }
# a pagespec with backlinks() will add as an influence the page with the links # a pagespec with backlinks() will add as an influence the page with the links
@ -76,20 +76,20 @@ foreach my $spec ("bugs or (backlink(foo0) and !*.png)", "backlink(foo)") {
ok(add_depends("foo5", $spec, presence => 1)); ok(add_depends("foo5", $spec, presence => 1));
ok($IkiWiki::depends{foo5}{$spec} & $IkiWiki::DEPEND_PRESENCE); ok($IkiWiki::depends{foo5}{$spec} & $IkiWiki::DEPEND_PRESENCE);
ok(! ($IkiWiki::depends{foo5}{$spec} & ($IkiWiki::DEPEND_CONTENT | $IkiWiki::DEPEND_LINKS))); ok(! ($IkiWiki::depends{foo5}{$spec} & ($IkiWiki::DEPEND_CONTENT | $IkiWiki::DEPEND_LINKS)));
ok($IkiWiki::depends_simple{foo5}{foo0} == $IkiWiki::DEPEND_CONTENT); ok($IkiWiki::depends_simple{foo5}{foo0} == $IkiWiki::DEPEND_LINKS);
ok(add_depends("foo6", $spec, links => 1)); ok(add_depends("foo6", $spec, links => 1));
ok($IkiWiki::depends{foo6}{$spec} & $IkiWiki::DEPEND_LINKS); ok($IkiWiki::depends{foo6}{$spec} & $IkiWiki::DEPEND_LINKS);
ok(! ($IkiWiki::depends{foo6}{$spec} & ($IkiWiki::DEPEND_PRESENCE | $IkiWiki::DEPEND_CONTENT))); ok(! ($IkiWiki::depends{foo6}{$spec} & ($IkiWiki::DEPEND_PRESENCE | $IkiWiki::DEPEND_CONTENT)));
ok($IkiWiki::depends_simple{foo5}{foo0} == $IkiWiki::DEPEND_CONTENT); ok($IkiWiki::depends_simple{foo5}{foo0} == $IkiWiki::DEPEND_LINKS);
ok(add_depends("foo7", $spec, presence => 1, links => 1)); ok(add_depends("foo7", $spec, presence => 1, links => 1));
ok($IkiWiki::depends{foo7}{$spec} & $IkiWiki::DEPEND_PRESENCE); ok($IkiWiki::depends{foo7}{$spec} & $IkiWiki::DEPEND_PRESENCE);
ok($IkiWiki::depends{foo7}{$spec} & $IkiWiki::DEPEND_LINKS); ok($IkiWiki::depends{foo7}{$spec} & $IkiWiki::DEPEND_LINKS);
ok(! ($IkiWiki::depends{foo7}{$spec} & $IkiWiki::DEPEND_CONTENT)); ok(! ($IkiWiki::depends{foo7}{$spec} & $IkiWiki::DEPEND_CONTENT));
ok($IkiWiki::depends_simple{foo7}{foo0} == $IkiWiki::DEPEND_CONTENT); ok($IkiWiki::depends_simple{foo7}{foo0} == $IkiWiki::DEPEND_LINKS);
ok(add_depends("foo8", $spec)); ok(add_depends("foo8", $spec));
ok($IkiWiki::depends{foo8}{$spec} & $IkiWiki::DEPEND_CONTENT); ok($IkiWiki::depends{foo8}{$spec} & $IkiWiki::DEPEND_CONTENT);
ok(! ($IkiWiki::depends{foo8}{$spec} & ($IkiWiki::DEPEND_PRESENCE | $IkiWiki::DEPEND_LINKS))); ok(! ($IkiWiki::depends{foo8}{$spec} & ($IkiWiki::DEPEND_PRESENCE | $IkiWiki::DEPEND_LINKS)));
ok($IkiWiki::depends_simple{foo8}{foo0} == $IkiWiki::DEPEND_CONTENT); ok($IkiWiki::depends_simple{foo8}{foo0} == $IkiWiki::DEPEND_LINKS);
} }
# content is the default if unknown types are entered # content is the default if unknown types are entered

View File

@ -93,19 +93,19 @@ $ret=pagespec_match("foo", "bar or foo");
ok($ret, "simple match"); ok($ret, "simple match");
is($ret, "foo matches foo", "stringified return"); is($ret, "foo matches foo", "stringified return");
$ret=pagespec_match("foo", "link(bar)"); my %i=pagespec_match("foo", "link(bar)")->influences;
is(join(",", $ret->influences), 'foo', "link is influenced by the page with the link"); is(join(",", keys %i), 'foo', "link is influenced by the page with the link");
$ret=pagespec_match("bar", "backlink(foo)"); %i=pagespec_match("bar", "backlink(foo)")->influences;
is(join(",", $ret->influences), 'foo', "backlink is influenced by the page with the link"); is(join(",", keys %i), 'foo', "backlink is influenced by the page with the link");
$ret=pagespec_match("bar", "backlink(foo)"); %i=pagespec_match("bar", "backlink(foo)")->influences;
is(join(",", $ret->influences), 'foo', "backlink is influenced by the page with the link"); is(join(",", keys %i), 'foo', "backlink is influenced by the page with the link");
$ret=pagespec_match("bar", "created_before(foo)"); %i=pagespec_match("bar", "created_before(foo)")->influences;
is(join(",", $ret->influences), 'foo', "created_before is influenced by the comparison page"); is(join(",", keys %i), 'foo', "created_before is influenced by the comparison page");
$ret=pagespec_match("bar", "created_after(foo)"); %i=pagespec_match("bar", "created_after(foo)")->influences;
is(join(",", $ret->influences), 'foo', "created_after is influenced by the comparison page"); is(join(",", keys %i), 'foo', "created_after is influenced by the comparison page");
$ret=pagespec_match("bar", "link(quux) and created_after(foo)"); %i=pagespec_match("bar", "link(quux) and created_after(foo)")->influences;
is(join(",", sort $ret->influences), 'foo,quux', "influences add up over AND"); is(join(",", sort keys %i), 'bar,foo', "influences add up over AND");
$ret=pagespec_match("bar", "link(quux) and created_after(foo)"); %i=pagespec_match("bar", "link(quux) and created_after(foo)")->influences;
is(join(",", sort $ret->influences), 'foo,quux', "influences add up over OR"); is(join(",", sort keys %i), 'bar,foo', "influences add up over OR");
$ret=pagespec_match("bar", "!link(quux) and !created_after(foo)"); %i=pagespec_match("bar", "!link(quux) and !created_after(foo)")->influences;
is(join(",", sort $ret->influences), 'foo,quux', "influences unaffected by negation"); is(join(",", sort keys %i), 'bar,foo', "influences unaffected by negation");