Show close matches for invalid task/target
cover Show close matches for invalid task/target
The following changes (against poky, but apply cleanly with -p2 against bitbake master) are available in the git repository at:
git://git.yoctoproject.org/poky-contrib paule/closematch
http://git.yoctoproject.org/cgit.cgi/poky-contrib/log/?h=paule/closematch
Paul Eggleton (2):
runqueue: report close matches for an invalid task name
taskdata: report close matches with NoProvider errors
bitbake/lib/bb/event.py | 3 ++- bitbake/lib/bb/runqueue.py | 6 +++++- bitbake/lib/bb/taskdata.py | 13 ++++++++++++- bitbake/lib/bb/ui/crumbs/runningbuild.py | 10 ++++++++-- bitbake/lib/bb/ui/knotty.py | 9 +++++++-- 5 files changed, 34 insertions(+), 7 deletions(-)
Signature · 1 line
1.8.1.2
PATCH 1/2 runqueue: report close matches for an invalid task name
Help to pick up mistakes such as "bitbake -c cleanstate xyz" (instead of "bitbake -c cleansstate xyz".)
--- bitbake/lib/bb/runqueue.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
bitbake/lib/bb/runqueue.py +5 -1
@@ -601,7 +601,11 @@ class RunQueueData: continue if target[1] not in taskData.tasks_lookup[fnid]: - bb.msg.fatal("RunQueue", "Task %s does not exist for target %s" % (target[1], target[0])) + import difflib + close_matches = difflib.get_close_matches(target[1], taskData.tasks_lookup[fnid], cutoff=0.7) + if close_matches: + extra = ". Close matches:\n %s" % "\n ".join(close_matches) + bb.msg.fatal("RunQueue", "Task %s does not exist for target %s%s" % (target[1], target[0], extra)) listid = taskData.tasks_lookup[fnid][target[1]]
Signature · 1 line
1.8.1.2
Re: [PATCH 1/2] runqueue: report close matches for an invalid task name
Quoted 13 lines · Paul Eggleton
Help to pick up mistakes such as "bitbake -c cleanstate xyz" (instead of "bitbake -c cleansstate xyz".)
Signed-off-by Paul Eggleton <[email protected]>--- bitbake/lib/bb/runqueue.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)bitbake/lib/bb/runqueue.py +0
-0
bitbake/lib/bb/runqueue.py class RunQueueData: · line 608
Quoted 9 lines
bitbake/lib/bb/runqueue.py +5
-1@@ -601,7 +601,11 @@ class RunQueueData: continue if target[1] not in taskData.tasks_lookup[fnid]: - bb.msg.fatal("RunQueue", "Task %s does not exist for target %s" % (target[1], target[0])) + import difflib + close_matches = difflib.get_close_matches(target[1], taskData.tasks_lookup[fnid], cutoff=0.7) + if close_matches: + extra = ". Close matches:\n %s" % "\n ".join(close_matches) + bb.msg.fatal("RunQueue", "Task %s does not exist for target %s%s" % (target[1], target[0], extra))
Missing else: extra = ""?
Cheers,
Richard
Re: [PATCH 1/2] runqueue: report close matches for an invalid task name
Quoted 18 lines · On Tuesday 13 August 2013 21:18:18 Richard Purdie wrote:
Quoted 17 lines · Paul Eggleton
Help to pick up mistakes such as "bitbake -c cleanstate xyz" (instead of "bitbake -c cleansstate xyz".)
Signed-off-by Paul Eggleton <[email protected]>---
bitbake/lib/bb/runqueue.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)bitbake/lib/bb/runqueue.py +0
-0@@ -601,7 +601,11 @@ class RunQueueData: continue
Quoted 10 lines
Quoted 9 lines
bitbake/lib/bb/runqueue.py +0
-1if target[1] not in taskData.tasks_lookup[fnid]: - bb.msg.fatal("RunQueue", "Task %s does not exist fortarget %s" % (target[1], target[0])) + import difflib
+close_matches= difflib.get_close_matches(target[1],
taskData.tasks_lookup[fnid], cutoff=0.7) + ifclose_matches:
+ extra = ". Close matches:\n %s" % "\n
".join(close_matches) + bb.msg.fatal("RunQueue", "Task %s
does not exist for target %s%s" % (target[1], target[0], extra))Missing else: extra = ""?
Oops. Fixed on the branch.
Thanks,
Paul
Signature · 2 lines
Paul Eggleton Intel Open Source Technology Centre
PATCH 2/2 taskdata: report close matches with NoProvider errors
In reply to Paul EggletonAssuming 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.
--- 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(-)
bitbake/lib/bb/event.py +2 -1
@@ -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
bitbake/lib/bb/taskdata.py +12 -1
@@ -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):
bitbake/lib/bb/ui/crumbs/runningbuild.py +8 -2
@@ -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)
bitbake/lib/bb/ui/knotty.py +7 -2
@@ -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)
Signature · 1 line
1.8.1.2