Openembedded Bitbake Development
 help / color / mirror / Atom feed
From: Rob Woolley <rob.woolley@windriver.com>
To: <bitbake-devel@lists.openembedded.org>
Subject: [PATCH 3/3] knotty: Add automatic paging for bitbake -s and -e
Date: Fri, 27 Feb 2015 09:32:24 -0500	[thread overview]
Message-ID: <1425047544-4820-4-git-send-email-rob.woolley@windriver.com> (raw)
In-Reply-To: <1425047544-4820-1-git-send-email-rob.woolley@windriver.com>

The bitbake show environment and show versions commands provide a
large volume of output to the user.  The knotty user interface changes
the output it provides based on whether it detects a TTY.

By checking for the presense of a TTY, we can automatically pipe
the output to a child process that pages the output for the user.
The logic for the automatic paging is based on pager.c found in git.

Some users may have a preferred pager already set in the PAGER
environment variable.  If it is set, found in PATH, and executable
then we use the user's preferred pager.  If it is set to "cat", then
paging is disabled.  If no pager is set, then we set it to "less" as
the default.

The LESS and LV environment variables are also set with sane defaults
in the event that either of these pagers are used.

We cleanly close the pipe before the summary message is displayed.  This 
is done intentionally so that the user does not miss any of the summary 
information if they close the pipe early.

Tested with both bitbake -s and -e with and without an explicit pipe
to a pager.  This includes testing broken pipe conditions caused by 
quitting the pager before the full output has been sent through the pipe.

Pagers tested include: less, more, cat, more, lv, and vim less.sh

Signed-off-by: Rob Woolley <rob.woolley@windriver.com>
---
 lib/bb/ui/knotty.py | 47 +++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 45 insertions(+), 2 deletions(-)

Index: b/lib/bb/ui/knotty.py
===================================================================
--- a/lib/bb/ui/knotty.py
+++ b/lib/bb/ui/knotty.py
@@ -32,6 +32,7 @@ import fcntl
 import struct
 import copy
 import atexit
+import subprocess
 from bb.ui import uihelper
 
 featureSet = [bb.cooker.CookerFeatures.SEND_SANITYEVENTS]
@@ -138,7 +139,7 @@ class TerminalFilter(object):
         self.helper = helper
         self.cuu = None
         self.stdinbackup = None
-        self.interactive = sys.stdout.isatty()
+        self.interactive = console.stream.isatty()
         self.footer_present = False
         self.lastpids = []
 
@@ -256,8 +257,42 @@ def main(server, eventHandler, params, t
 
     helper = uihelper.BBUIHelper()
 
-    console = logging.StreamHandler(sys.stdout)
-    errconsole = logging.StreamHandler(sys.stderr)
+    pager_bin = None
+    pager_process = None
+
+    if (os.getenv("PAGER")):
+        pager_bin = os.getenv("PAGER")
+    else:
+        pager_bin = "less"
+
+    if pager_bin == "cat":
+        pager_bin = None
+
+    if pager_bin and (not os.path.isfile(pager_bin) or not os.access(pager_bin, os.X_OK)):
+        found_pager = False
+        for path in os.environ["PATH"].split(os.pathsep):
+             pager_path = os.path.join(path,pager_bin)
+             if os.path.isfile(pager_path) and os.access(pager_path, os.X_OK):
+                 found_pager = True
+                 break
+
+        if not found_pager:
+            pager_bin = None
+
+    if (os.getenv("LESS") == None):
+        os.environ['LESS'] = 'FRX'
+
+    if (os.getenv("LV") == None):
+        os.environ['LV'] = '-c'
+
+    if interactive and pager_bin and (params.options.show_versions or params.options.show_environment):
+        pager_process = subprocess.Popen(pager_bin, stdin=subprocess.PIPE)
+        console = logging.StreamHandler(pager_process.stdin)
+        errconsole = logging.StreamHandler(pager_process.stdin)
+    else:
+        console = logging.StreamHandler(sys.stdout)
+        errconsole = logging.StreamHandler(sys.stderr)
+
     format_str = "%(levelname)s: %(message)s"
     format = bb.msg.BBLogFormatter(format_str)
     bb.msg.addDefaultlogFilter(console, bb.msg.BBLogFilterStdOut)
@@ -536,6 +571,11 @@ def main(server, eventHandler, params, t
             if not params.observe_only:
                 _, error = server.runCommand(["stateForceShutdown"])
             main.shutdown = 2
+
+    if pager_process:
+        pager_process.stdin.close()
+        pager_process.wait()
+
     try:
          summary = ""
          if taskfailures:


  parent reply	other threads:[~2015-02-27 14:32 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-27 14:32 [PATCH 0/3] knotty: Add automatic pager support Rob Woolley
2015-02-27 14:32 ` [PATCH 1/3] knotty: Catch exceptions on broken pipes Rob Woolley
2015-02-27 14:32 ` [PATCH 2/3] knotty: Do not log show_versions output Rob Woolley
2015-02-27 14:32 ` Rob Woolley [this message]
2015-03-12 15:25 ` [PATCH 0/3] knotty: Add automatic pager support Rob Woolley
2015-03-12 16:30   ` Richard Purdie
2015-03-13 19:41     ` Woolley, Rob
2015-03-13 21:12       ` Bernhard Reutner-Fischer
2015-03-13 21:37         ` Bernhard Reutner-Fischer
2015-03-17 15:05           ` Woolley, Rob

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=1425047544-4820-4-git-send-email-rob.woolley@windriver.com \
    --to=rob.woolley@windriver.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