]> git.vanrenterghem.biz Git - git.ikiwiki.info.git/blobdiff - IkiWiki.pm
fix some broken influence blocking testing, add more tests
[git.ikiwiki.info.git] / IkiWiki.pm
index 49c76c4d4cb08901b6d102bd6e466ebb9f2f8a8c..ac01ea4180c25224892ba8a5cfa1d807df67c1af 100644 (file)
@@ -1780,19 +1780,17 @@ sub add_depends ($$;$) {
                return 1;
        }
 
-       # Analyse the pagespec, and match it against all pages
-       # to get a list of influences, and add explicit dependencies
-       # for those.
-       #my $sub=pagespec_translate($pagespec);
-       #return if $@;
-       #foreach my $p (keys %pagesources) {
-       #       my $r=$sub->($p, location => $page );
-       #       my %i=$r->influences;
-       #       foreach my $i (keys %i) {
-       #               $depends_simple{$page}{lc $i} |= $i{$i};
-       #       }
-       #}
-       print STDERR "warning: use of add_depends by ".caller()."; influences not tracked\n";
+       # Add explicit dependencies for influences.
+       my $sub=pagespec_translate($pagespec);
+       return if $@;
+       foreach my $p (keys %pagesources) {
+               my $r=$sub->($p, location => $page);
+               my $i=$r->influences;
+               foreach my $k (keys %$i) {
+                       $depends_simple{$page}{lc $k} |= $i->{$k};
+               }
+               last if $r->influences_static;
+       }
 
        $depends{$page}{$pagespec} |= $deptype;
        return 1;
@@ -1986,11 +1984,15 @@ sub pagespec_match_list ($$;@) {
                if $@ || ! defined $sub;
 
        my @candidates;
-       if (exists $params{filter}) {
-               @candidates=grep { ! $params{filter}->($_) } keys %pagesources;
+       if (exists $params{list}) {
+               @candidates=exists $params{filter}
+                       ? grep { ! $params{filter}->($_) } @{$params{list}}
+                       : @{$params{list}};
        }
        else {
-               @candidates=keys %pagesources;
+               @candidates=exists $params{filter}
+                       ? grep { ! $params{filter}->($_) } keys %pagesources
+                       : keys %pagesources;
        }
 
        if (defined $params{sort}) {
@@ -2023,46 +2025,30 @@ sub pagespec_match_list ($$;@) {
        
        # clear params, remainder is passed to pagespec
        my $num=$params{num};
-       delete @params{qw{num deptype reverse sort filter}};
+       delete @params{qw{num deptype reverse sort filter list}};
        
        my @matches;
        my $firstfail;
        my $count=0;
+       my $accum=IkiWiki::SuccessReason->new();
        foreach my $p (@candidates) {
                my $r=$sub->($p, %params, location => $page);
+               error(sprintf(gettext("cannot match pages: %s"), $r))
+                       if $r->isa("IkiWiki::ErrorReason");
+               $accum |= $r;
                if ($r) {
-                       push @matches, [$p, $r];
+                       push @matches, $p;
                        last if defined $num && ++$count == $num;
                }
-               elsif (! defined $firstfail) {
-                       $firstfail=$r;
-               }
-       }
-
-       my @ret;
-       if (@matches) {
-               # Add all influences from successful matches.
-               foreach my $m (@matches) {
-                       push @ret, $m->[0];
-                       my %i=$m->[1]->influences;
-                       foreach my $i (keys %i) {
-                               $depends_simple{$page}{lc $i} |= $i{$i};
-                       }
-               }
        }
-       elsif (defined $firstfail) {
-               # Add influences from one failure. (Which one should not
-               # matter; all should have the same influences.)
-               my %i=$firstfail->influences;
-               foreach my $i (keys %i) {
-                       $depends_simple{$page}{lc $i} |= $i{$i};
-               }
 
-               error(sprintf(gettext("cannot match pages: %s"), $firstfail))
-                       if $firstfail->isa("IkiWiki::ErrorReason");
+       # Add simple dependencies for accumulated influences.
+       my $i=$accum->influences;
+       foreach my $k (keys %$i) {
+               $depends_simple{$page}{lc $k} |= $i->{$k};
        }
 
-       return @ret;
+       return @matches;
 }
 
 sub pagespec_valid ($) {
@@ -2085,7 +2071,7 @@ use overload (
        '""'    => sub { $_[0][0] },
        '0+'    => sub { 0 },
        '!'     => sub { bless $_[0], 'IkiWiki::SuccessReason'},
-       '&'     => sub { $_[0]->merge_influences($_[1]); $_[0] },
+       '&'     => sub { $_[0]->merge_influences($_[1], 1); $_[0] },
        '|'     => sub { $_[1]->merge_influences($_[0]); $_[1] },
        fallback => 1,
 );
@@ -2098,7 +2084,7 @@ use overload (
        '""'    => sub { $_[0][0] },
        '0+'    => sub { 1 },
        '!'     => sub { bless $_[0], 'IkiWiki::FailReason'},
-       '&'     => sub { $_[1]->merge_influences($_[0]); $_[1] },
+       '&'     => sub { $_[1]->merge_influences($_[0], 1); $_[1] },
        '|'     => sub { $_[0]->merge_influences($_[1]); $_[0] },
        fallback => 1,
 );
@@ -2111,19 +2097,33 @@ sub new {
 
 sub influences {
        my $this=shift;
-       if (! @_) {
-               return %{$this->[1]};
-       }
-       else {
-               $this->[1]={@_};
-       }
+       $this->[1]={@_} if @_;
+       my %i=%{$this->[1]};
+       delete $i{""};
+       return \%i;
+}
+
+sub influences_static {
+       return ! $_[0][1]->{""};
 }
 
 sub merge_influences {
        my $this=shift;
        my $other=shift;
-       foreach my $influence (keys %{$other->[1]}) {
-               $this->[1]{$influence} |= $other->[1]{$influence};
+       my $anded=shift;
+
+       if (! $anded || (($this || %{$this->[1]}) &&
+                       ($other || %{$other->[1]}))) {
+               foreach my $influence (keys %{$other->[1]}) {
+                       $this->[1]{$influence} |= $other->[1]{$influence};
+               }
+       }
+       else {
+               # influence blocker
+               print STDERR "merging $this and $other; found influence blocker\n";
+               $this->[1]={};
+               $this->[2]=1;
+               return;
        }
 }
 
@@ -2180,24 +2180,24 @@ sub match_link ($$;@) {
        my $from=exists $params{location} ? $params{location} : '';
 
        my $links = $IkiWiki::links{$page};
-       return IkiWiki::FailReason->new("$page has no links")
+       return IkiWiki::FailReason->new("$page has no links", "" => 1)
                unless $links && @{$links};
        my $bestlink = IkiWiki::bestlink($from, $link);
        foreach my $p (@{$links}) {
                if (length $bestlink) {
-                       return IkiWiki::SuccessReason->new("$page links to $link", $page => $IkiWiki::DEPEND_LINKS)
+                       return IkiWiki::SuccessReason->new("$page links to $link", $page => $IkiWiki::DEPEND_LINKS, "" => 1)
                                if $bestlink eq IkiWiki::bestlink($page, $p);
                }
                else {
-                       return IkiWiki::SuccessReason->new("$page links to page $p matching $link", $page => $IkiWiki::DEPEND_LINKS)
+                       return IkiWiki::SuccessReason->new("$page links to page $p matching $link", $page => $IkiWiki::DEPEND_LINKS, "" => 1)
                                if match_glob($p, $link, %params);
                        my ($p_rel)=$p=~/^\/?(.*)/;
                        $link=~s/^\///;
-                       return IkiWiki::SuccessReason->new("$page links to page $p_rel matching $link", $page => $IkiWiki::DEPEND_LINKS)
+                       return IkiWiki::SuccessReason->new("$page links to page $p_rel matching $link", $page => $IkiWiki::DEPEND_LINKS, "" => 1)
                                if match_glob($p_rel, $link, %params);
                }
        }
-       return IkiWiki::FailReason->new("$page does not link to $link");
+       return IkiWiki::FailReason->new("$page does not link to $link", "" => 1);
 }
 
 sub match_backlink ($$;@) {