[diffoscope] 01/02: presenters/html: prune all descendants properly (Closes: #875281)

Ximin Luo infinity0 at debian.org
Wed Sep 20 17:15:36 CEST 2017


This is an automated email from the git hooks/post-receive script.

infinity0 pushed a commit to branch master
in repository diffoscope.

commit ccd926faab7eb9a8925437148a441244a5eb664d
Author: Ximin Luo <infinity0 at debian.org>
Date:   Wed Sep 20 17:12:22 2017 +0200

    presenters/html: prune all descendants properly (Closes: #875281)
---
 diffoscope/difference.py           |  7 ++++---
 diffoscope/presenters/html/html.py | 37 +++++++++++++++++++++----------------
 2 files changed, 25 insertions(+), 19 deletions(-)

diff --git a/diffoscope/difference.py b/diffoscope/difference.py
index 30db2f9..8959cdd 100644
--- a/diffoscope/difference.py
+++ b/diffoscope/difference.py
@@ -148,9 +148,10 @@ class Difference(object):
         queue = queue if queue is not None else [(scorer(self, None), self)]
         while queue:
             val, top = heapq.heappop(queue)
-            yield ((top, val) if yield_score else top)
-            for d in top._details:
-                heapq.heappush(queue, (scorer(d, val), d))
+            prune_descendants = yield ((top, val) if yield_score else top)
+            if not prune_descendants:
+                for d in top._details:
+                    heapq.heappush(queue, (scorer(d, val), d))
 
     @staticmethod
     def from_feeder(feeder1, feeder2, path1, path2, source=None, comment=None, **kwargs):
diff --git a/diffoscope/presenters/html/html.py b/diffoscope/presenters/html/html.py
index 4bfb361..175aad1 100644
--- a/diffoscope/presenters/html/html.py
+++ b/diffoscope/presenters/html/html.py
@@ -107,7 +107,7 @@ def escape_anchor(val):
 
 
 def output_diff_path(path):
-    return '/'.join(n.source1 for n in path[1:])
+    return ' / '.join(n.source1 for n in path[1:])
 
 
 def output_anchor(path):
@@ -579,22 +579,20 @@ class HTMLPresenter(Presenter):
         continuations = {}  # functions to print unified diff continuations (html-dir only)
         printers = {}  # nodes to their printers
 
-        def smallest_first(node, parscore):
-            depth = parscore[0] + 1 if parscore else 0
-            parents = parscore[3] if parscore else []
+        def smallest_first(node, parent_score):
+            depth = parent_score[0] + 1 if parent_score else 0
+            parents = parent_score[3] if parent_score else []
             # Difference is not comparable so use memory address in event of a tie
             return depth, node.size_self(), id(node), parents + [node]
 
-        pruned = set()  # children
-        for node, score in root_difference.traverse_heapq(smallest_first, yield_score=True):
-            if node in pruned:
-                continue
-
-            ancestor = ancestors.pop(node, None)
+        def process_node(node, score):
             path = score[3]
             diff_path = output_diff_path(path)
             pagename = md5(diff_path)
             logger.debug('html output for %s', diff_path)
+
+            ancestor = ancestors.pop(node, None)
+            assert ancestor in path or (ancestor is None and node is root_difference)
             node_output, node_continuation = output_node(ctx, node, path, "  ", len(path)-1)
 
             add_to_existing = False
@@ -627,13 +625,10 @@ class HTMLPresenter(Presenter):
                     if not make_new_subpage:  # we hit a limit, either max-report-size or single-page
                         if not outputs:
                             # no more holes, don't traverse any more nodes
-                            break
+                            raise StopIteration
                         else:
-                            # don't traverse this node's children, they won't be output
-                            # however there are holes in other pages, so don't break just yet
-                            for child in node.details:
-                                pruned.add(child)
-                            continue
+                            # True = don't traverse any children either
+                            return True
                 else:
                     # unconditionally write the root node regardless of limits
                     assert node is root_difference
@@ -648,6 +643,7 @@ class HTMLPresenter(Presenter):
                 stored = node
 
             for child in node.details:
+                logger.debug("scheduling future html output for: %s" % output_diff_path(path + [child]))
                 ancestors[child] = stored
 
             conts = continuations.setdefault(stored, [])
@@ -656,6 +652,15 @@ class HTMLPresenter(Presenter):
 
             self.maybe_print(stored, printers, outputs, continuations)
 
+        nodes = root_difference.traverse_heapq(smallest_first, yield_score=True)
+        prune_prev_node_descendants = None
+        while True:
+            try:
+                node, score = nodes.send(prune_prev_node_descendants)
+                prune_prev_node_descendants = process_node(node, score)
+            except StopIteration:
+                break
+
         if outputs:
             import pprint
             pprint.pprint(outputs, indent=4)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/diffoscope.git


More information about the diffoscope mailing list