[bitbake-devel] [RFC PATCH] ui/knotty: Add a footer to the build output for interactive terminals

Richard Purdie richard.purdie at linuxfoundation.org
Sat Nov 26 13:47:10 UTC 2011


On terminals which support it, add summary information to the end of the
build output about the number of tasks currently running and how many tasks
we've run so far.

This provides a summary at a glace of what the current state of the build is
and what the build is currently doing which is lacking in the current UI.

Also disable echo of characters on stdin since this corrupts the disable,
particularly Crtl+C.

The "waiting for X tasks" code can be merged into this code too since
that is only useful on interactive terminals and this improves the
readability of that output too.

Signed-off-by: Richard Purdie <richard.purdie at linuxfoundation.org>
---

This is something I've been experimenting with. I'd appreciate feedback
on whether people feel this is an improvement over the current terminal
output. Currently the existing output continues to scroll above the
footer. We could cut down on the number of log messages going there
though so warnings and errors would become more visible. Full logs would
remain in the BB_CONSOLELOG file on disk for reference.

diff --git a/bitbake/lib/bb/ui/knotty.py b/bitbake/lib/bb/ui/knotty.py
index 7c645ad..0f50ce4 100644
--- a/bitbake/lib/bb/ui/knotty.py
+++ b/bitbake/lib/bb/ui/knotty.py
@@ -31,6 +31,25 @@ from bb.ui import uihelper
 logger = logging.getLogger("BitBake")
 interactive = sys.stdout.isatty()
 
+cuu = None
+stdinbackup = None
+if interactive:
+    import curses
+    import termios
+    import copy
+    try:
+        fd = sys.stdin.fileno()
+        stdinbackup = termios.tcgetattr(fd)
+        new = copy.deepcopy(stdinbackup)
+        new[3] = new[3] & ~termios.ECHO
+        termios.tcsetattr(fd, termios.TCSADRAIN, new)
+        curses.setupterm()
+        ed = curses.tigetstr("ed")
+        if ed:
+            cuu = curses.tigetstr("cuu")
+    except:
+        cuu = None
+
 class BBProgress(progressbar.ProgressBar):
     def __init__(self, msg, maxval):
         self.msg = msg
@@ -99,21 +124,49 @@ def main(server, eventHandler):
     cacheprogress = None
     shutdown = 0
     return_value = 0
+    main.footer_present = False
+    main.footer_update = True
+
+    def updateFooter():
+        if not main.footer_update:
+            return
+        if main.footer_present:
+            clearFooter()
+        if not cuu:
+            return
+        activetasks = helper.running_tasks
+        failedtasks = helper.failed_tasks
+        if not activetasks:
+            return
+        lines = 1
+        if shutdown:
+            print("Waiting for %s running tasks to finish:" % len(activetasks))
+        else:
+            print("Currently %s running tasks (%s of %s):" % (len(activetasks), helper.tasknumber_current, helper.tasknumber_total))
+        for tasknum, task in enumerate(activetasks):
+            print("%s: %s (pid %s)" % (tasknum, activetasks[task]["title"], task))
+            lines = lines + 1
+        main.footer_present = lines
+
+    def clearFooter():
+        if main.footer_present:
+            lines = main.footer_present
+            sys.stdout.write(curses.tparm(cuu, lines))
+            sys.stdout.write(curses.tparm(ed))
+        main.footer_present = False
+        main.footer_update = True
+
     while True:
         try:
+            updateFooter()
             event = eventHandler.waitEvent(0.25)
             if event is None:
                 continue
+            clearFooter()
             helper.eventHandler(event)
             if isinstance(event, bb.runqueue.runQueueExitWait):
                 if not shutdown:
                     shutdown = 1
-            if shutdown and helper.needUpdate:
-                activetasks, failedtasks = helper.getTasks()
-                if activetasks:
-                    print("Waiting for %s active tasks to finish:" % len(activetasks))
-                    for tasknum, task in enumerate(activetasks):
-                        print("%s: %s (pid %s)" % (tasknum, activetasks[task]["title"], task))
 
             if isinstance(event, logging.LogRecord):
                 if event.levelno >= format.ERROR:
@@ -246,10 +299,12 @@ def main(server, eventHandler):
             logger.error("Unknown event: %s", event)
 
         except EnvironmentError as ioerror:
+            clearFooter()
             # ignore interrupted io
             if ioerror.args[0] == 4:
                 pass
         except KeyboardInterrupt:
+            clearFooter()
             if shutdown == 2:
                 print("\nThird Keyboard Interrupt, exit.\n")
                 break
@@ -261,4 +316,6 @@ def main(server, eventHandler):
                 server.runCommand(["stateShutdown"])
             shutdown = shutdown + 1
             pass
+    if stdinbackup:
+        termios.tcsetattr(fd, termios.TCSADRAIN, stdinbackup)
     return return_value






More information about the bitbake-devel mailing list