[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#639319: [britney] Improved auto-hinter



Package: release.debian.org
Severity: wishlist
User: release.debian.org@packages.debian.org
Usertags: britney
Tags: patch

Hi,

After a certain amount of head-desking when various things didn't work,
I'm finally happy enough with my improved auto-hinter functionality for
britney that I thought it should be in the BTS for others to pull
apart^W^Wcomment on.

Essentially, starting from each "leaf" package in terms of excuses it
recursively builds a list of the forward and reverse dependencies of
each package encountered, assuming they are valid candidates.

A list of such package lists is built up and processed to remove any
lists which are subsets of another list, before trying each hint in
turn.

By way of a test, for a britney run seeded with the output of this
morning's live run the code found seven potential hints, of which two
were successful.

Regards,

Adam
--- britney.py.orig	2011-08-25 21:27:55.000000000 +0000
+++ britney.py	2011-08-25 21:28:01.000000000 +0000
@@ -2848,20 +2848,54 @@
             return hint
 
         # loop on them
-        cache = []
+        candidates = []
         for e in excuses:
             excuse = excuses[e]
-            if e in self.sources['testing'] and self.sources['testing'][e][VERSION] == excuse.ver[1] or \
-               len(excuse.deps) == 0:
-                continue
-            hint = find_related(e, {})
-            if isinstance(hint, dict) and len(hint) and hint not in cache:
-                self.do_hint("easy", "autohinter", hint.items())
-                cache.append(hint)
-            hint = find_related(e, {}, True)
-            if isinstance(hint, dict) and e in hint and hint not in cache:
-                self.do_hint("easy", "autohinter", hint.items())
-                cache.append(hint)
+            if e in self.sources['testing'] and self.sources['testing'][e][VERSION] == excuse.ver[1]:
+               continue
+            if len(excuse.deps) > 0:
+                hint = find_related(e, {}, True)
+                if isinstance(hint, dict) and e in hint and hint not in candidates:
+                    candidates.append(hint.items())
+            else:
+                items = [ (e, excuse.ver[1]) ]
+                for item, ver in items:
+                    # sources which depend on item or are depended on by item
+                    items.extend( [ (x, excuses[x].ver[1]) for x in excuses if \
+                       (item in excuses[x].deps or x in excuses[item].deps) \
+                       and (x, excuses[x].ver[1]) not in items ] )
+                    for arch in self.options.architectures:
+                        # binNMUs which depend on item
+                        items.extend( [ ("%s/%s" % (x, arch), excuses[x].ver[1]) for x in excuses if \
+                          (item in excuses[x].deps and arch in excuses[x].deps[item]) and \
+                          not (x in self.sources['unstable'] and \
+                               self.same_source(excuses[x].ver[1], self.sources['unstable'][x][VERSION]) \
+                              ) and \
+                          ("%s/%s" % (x,arch), excuses[x].ver[1]) not in items and \
+                          (x, excuses[x].ver[1]) not in items ] )
+                        # binNMUs which item depends on
+                        items.extend( [ ("%s/%s" % (x, arch), excuses[x].ver[1]) for x in excuses if \
+                          (x in excuses[item].deps and arch in excuses[item].deps[x]) and \
+                          not (x in self.sources['unstable'] and \
+                               self.same_source(excuses[x].ver[1], self.sources['unstable'][x][VERSION]) \
+                              ) and \
+                          ("%s/%s" % (x,arch), excuses[x].ver[1]) not in items and \
+                          (x, excuses[x].ver[1]) not in items ] )
+                if len(items) > 1:
+                    candidates.append(items)
+
+        to_skip = []
+        for i in range(len(candidates)):
+            for j in range(i + 1, len(candidates)):
+                if i in to_skip or j in to_skip:
+                    continue
+                if frozenset(candidates[i]) >= frozenset(candidates[j]):
+                    to_skip.append(j)
+                elif frozenset(candidates[i]) <= frozenset(candidates[j]):
+                    to_skip.append(i)
+        for i in range(len(candidates)):
+            if i not in to_skip:
+                self.do_hint("easy", "autohinter", candidates[i])
 
     def old_libraries(self):
         """Detect old libraries left in testing for smooth transitions

Reply to: