Openembedded Bitbake Development
 help / color / mirror / Atom feed
From: Paul Eggleton <paul.eggleton@linux.intel.com>
To: bitbake-devel@lists.openembedded.org
Subject: [PATCH 2/2] taskdata: report close matches with NoProvider errors
Date: Tue, 13 Aug 2013 15:18:39 +0100	[thread overview]
Message-ID: <34fc374892f84f804bef65fa25614fad2da64c36.1376403450.git.paul.eggleton@linux.intel.com> (raw)
In-Reply-To: <cover.1376403450.git.paul.eggleton@linux.intel.com>
In-Reply-To: <cover.1376403450.git.paul.eggleton@linux.intel.com>

Assuming there is no known reason why an item is not provided, show
close matches on the assumption that it might have been a typo or
other mistake.

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
---
 bitbake/lib/bb/event.py                  |  3 ++-
 bitbake/lib/bb/taskdata.py               | 13 ++++++++++++-
 bitbake/lib/bb/ui/crumbs/runningbuild.py | 10 ++++++++--
 bitbake/lib/bb/ui/knotty.py              |  9 +++++++--
 4 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/bitbake/lib/bb/event.py b/bitbake/lib/bb/event.py
index 9c134ee..ba25d38 100644
--- a/bitbake/lib/bb/event.py
+++ b/bitbake/lib/bb/event.py
@@ -341,12 +341,13 @@ class DiskFull(Event):
 class NoProvider(Event):
     """No Provider for an Event"""
 
-    def __init__(self, item, runtime=False, dependees=None, reasons=[]):
+    def __init__(self, item, runtime=False, dependees=None, reasons=[], close_matches=[]):
         Event.__init__(self)
         self._item = item
         self._runtime = runtime
         self._dependees = dependees
         self._reasons = reasons
+        self._close_matches = close_matches
 
     def getItem(self):
         return self._item
diff --git a/bitbake/lib/bb/taskdata.py b/bitbake/lib/bb/taskdata.py
index c08186a..58fe199 100644
--- a/bitbake/lib/bb/taskdata.py
+++ b/bitbake/lib/bb/taskdata.py
@@ -390,6 +390,17 @@ class TaskData:
                     reasons.append("%s PROVIDES %s but was skipped: %s" % (skipitem.pn, item, skipitem.skipreason))
         return reasons
 
+    def get_close_matches(self, item, provider_list):
+        import difflib
+        if self.skiplist:
+            skipped = []
+            for fn in self.skiplist:
+                skipped.append(self.skiplist[fn].pn)
+            full_list = provider_list + skipped
+        else:
+            full_list = provider_list
+        return difflib.get_close_matches(item, full_list, cutoff=0.7)
+
     def add_provider(self, cfgData, dataCache, item):
         try:
             self.add_provider_internal(cfgData, dataCache, item)
@@ -411,7 +422,7 @@ class TaskData:
             return
 
         if not item in dataCache.providers:
-            bb.event.fire(bb.event.NoProvider(item, dependees=self.get_dependees_str(item), reasons=self.get_reasons(item)), cfgData)
+            bb.event.fire(bb.event.NoProvider(item, dependees=self.get_dependees_str(item), reasons=self.get_reasons(item), close_matches=self.get_close_matches(item, dataCache.providers.keys())), cfgData)
             raise bb.providers.NoProvider(item)
 
         if self.have_build_target(item):
diff --git a/bitbake/lib/bb/ui/crumbs/runningbuild.py b/bitbake/lib/bb/ui/crumbs/runningbuild.py
index 78fa141..abd3300 100644
--- a/bitbake/lib/bb/ui/crumbs/runningbuild.py
+++ b/bitbake/lib/bb/ui/crumbs/runningbuild.py
@@ -375,10 +375,16 @@ class RunningBuild (gobject.GObject):
                 r = "R"
             else:
                 r = ""
+
+            extra = ''
+            if not event._reasons:
+                if event._close_matches:
+                    extra = ". Close matches:\n  %s" % '\n  '.join(event._close_matches)
+
             if event._dependees:
-                msg = "Nothing %sPROVIDES '%s' (but %s %sDEPENDS on or otherwise requires it)\n" % (r, event._item, ", ".join(event._dependees), r)
+                msg = "Nothing %sPROVIDES '%s' (but %s %sDEPENDS on or otherwise requires it)%s\n" % (r, event._item, ", ".join(event._dependees), r, extra)
             else:
-                msg = "Nothing %sPROVIDES '%s'\n" % (r, event._item)
+                msg = "Nothing %sPROVIDES '%s'%s\n" % (r, event._item, extra)
             if event._reasons:
                 for reason in event._reasons:
                     msg += ("%s\n" % reason)
diff --git a/bitbake/lib/bb/ui/knotty.py b/bitbake/lib/bb/ui/knotty.py
index 2c8293d..09ad99e 100644
--- a/bitbake/lib/bb/ui/knotty.py
+++ b/bitbake/lib/bb/ui/knotty.py
@@ -416,10 +416,15 @@ def main(server, eventHandler, params, tf = TerminalFilter):
                 else:
                     r = ""
 
+                extra = ''
+                if not event._reasons:
+                    if event._close_matches:
+                        extra = ". Close matches:\n  %s" % '\n  '.join(event._close_matches)
+
                 if event._dependees:
-                    logger.error("Nothing %sPROVIDES '%s' (but %s %sDEPENDS on or otherwise requires it)", r, event._item, ", ".join(event._dependees), r)
+                    logger.error("Nothing %sPROVIDES '%s' (but %s %sDEPENDS on or otherwise requires it)%s", r, event._item, ", ".join(event._dependees), r, extra)
                 else:
-                    logger.error("Nothing %sPROVIDES '%s'", r, event._item)
+                    logger.error("Nothing %sPROVIDES '%s'%s", r, event._item, extra)
                 if event._reasons:
                     for reason in event._reasons:
                         logger.error("%s", reason)
-- 
1.8.1.2



      parent reply	other threads:[~2013-08-13 14:18 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-08-13 14:18 [PATCH 0/2] Show close matches for invalid task/target Paul Eggleton
2013-08-13 14:18 ` [PATCH 1/2] runqueue: report close matches for an invalid task name Paul Eggleton
2013-08-13 20:18   ` Richard Purdie
2013-08-13 20:46     ` Paul Eggleton
2013-08-13 14:18 ` Paul Eggleton [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=34fc374892f84f804bef65fa25614fad2da64c36.1376403450.git.paul.eggleton@linux.intel.com \
    --to=paul.eggleton@linux.intel.com \
    --cc=bitbake-devel@lists.openembedded.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox