From: Richard Purdie <richard.purdie@linuxfoundation.org>
To: bitbake-devel <bitbake-devel@lists.openembedded.org>
Subject: [PATCH] knotty: Fold knotty2 into knotty and make it the default
Date: Wed, 15 Aug 2012 17:50:22 +0100 [thread overview]
Message-ID: <1345049422.14667.11.camel@ted> (raw)
There is no good reason knotty2 shouldn't be the default now. If you need
the old behaviour, just pipe the output through cat as non-interactive
terminals get the old output.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
---
diff --git a/bitbake/lib/bb/ui/knotty.py b/bitbake/lib/bb/ui/knotty.py
index 34b5969..304ba29 100644
--- a/bitbake/lib/bb/ui/knotty.py
+++ b/bitbake/lib/bb/ui/knotty.py
@@ -27,6 +27,9 @@ import logging
import progressbar
import signal
import bb.msg
+import fcntl
+import struct
+import copy
from bb.ui import uihelper
logger = logging.getLogger("BitBake")
@@ -84,39 +87,124 @@ def pluralise(singular, plural, qty):
else:
return plural % qty
+
+class InteractConsoleLogFilter(logging.Filter):
+ def __init__(self, tf, format):
+ self.tf = tf
+ self.format = format
+
+ def filter(self, record):
+ if record.levelno == self.format.NOTE and (record.msg.startswith("Running") or record.msg.startswith("package ")):
+ return False
+ self.tf.clearFooter()
+ return True
+
class TerminalFilter(object):
+ columns = 80
+
+ def sigwinch_handle(self, signum, frame):
+ self.columns = self.getTerminalColumns()
+ if self._sigwinch_default:
+ self._sigwinch_default(signum, frame)
+
+ def getTerminalColumns(self):
+ def ioctl_GWINSZ(fd):
+ try:
+ cr = struct.unpack('hh', fcntl.ioctl(fd, self.termios.TIOCGWINSZ, '1234'))
+ except:
+ return None
+ return cr
+ cr = ioctl_GWINSZ(sys.stdout.fileno())
+ if not cr:
+ try:
+ fd = os.open(os.ctermid(), os.O_RDONLY)
+ cr = ioctl_GWINSZ(fd)
+ os.close(fd)
+ except:
+ pass
+ if not cr:
+ try:
+ cr = (env['LINES'], env['COLUMNS'])
+ except:
+ cr = (25, 80)
+ return cr[1]
+
def __init__(self, main, helper, console, format):
self.main = main
self.helper = helper
+ self.cuu = None
+ self.stdinbackup = None
+ self.interactive = sys.stdout.isatty()
+ self.footer_present = False
+ self.lastpids = []
+
+ if not self.interactive:
+ return
+
+ import curses
+ import termios
+ self.curses = curses
+ self.termios = termios
+ try:
+ fd = sys.stdin.fileno()
+ self.stdinbackup = termios.tcgetattr(fd)
+ new = copy.deepcopy(self.stdinbackup)
+ new[3] = new[3] & ~termios.ECHO
+ termios.tcsetattr(fd, termios.TCSADRAIN, new)
+ curses.setupterm()
+ self.ed = curses.tigetstr("ed")
+ if self.ed:
+ self.cuu = curses.tigetstr("cuu")
+ try:
+ self._sigwinch_default = signal.getsignal(signal.SIGWINCH)
+ signal.signal(signal.SIGWINCH, self.sigwinch_handle)
+ except:
+ pass
+ self.columns = self.getTerminalColumns()
+ except:
+ self.cuu = None
+ console.addFilter(InteractConsoleLogFilter(self, format))
def clearFooter(self):
- return
+ if self.footer_present:
+ lines = self.footer_present
+ sys.stdout.write(self.curses.tparm(self.cuu, lines))
+ sys.stdout.write(self.curses.tparm(self.ed))
+ self.footer_present = False
def updateFooter(self):
- if not main.shutdown or not self.helper.needUpdate:
+ if not self.cuu:
return
-
activetasks = self.helper.running_tasks
+ failedtasks = self.helper.failed_tasks
runningpids = self.helper.running_pids
-
- if len(runningpids) == 0:
+ if self.footer_present and (self.lastpids == runningpids):
+ return
+ if self.footer_present:
+ self.clearFooter()
+ if not activetasks:
return
-
- self.helper.getTasks()
-
tasks = []
for t in runningpids:
tasks.append("%s (pid %s)" % (activetasks[t]["title"], t))
- if main.shutdown:
- print("Waiting for %s running tasks to finish:" % len(activetasks))
+ if self.main.shutdown:
+ content = "Waiting for %s running tasks to finish:" % len(activetasks)
else:
- print("Currently %s running tasks (%s of %s):" % (len(activetasks), self.helper.tasknumber_current, self.helper.tasknumber_total))
+ content = "Currently %s running tasks (%s of %s):" % (len(activetasks), self.helper.tasknumber_current, self.helper.tasknumber_total)
+ print content
+ lines = 1 + int(len(content) / (self.columns + 1))
for tasknum, task in enumerate(tasks):
- print("%s: %s" % (tasknum, task))
+ content = "%s: %s" % (tasknum, task)
+ print content
+ lines = lines + 1 + int(len(content) / (self.columns + 1))
+ self.footer_present = lines
+ self.lastpids = runningpids[:]
def finish(self):
- return
+ if self.stdinbackup:
+ fd = sys.stdin.fileno()
+ self.termios.tcsetattr(fd, self.termios.TCSADRAIN, self.stdinbackup)
def main(server, eventHandler, tf = TerminalFilter):
diff --git a/bitbake/lib/bb/ui/knotty2.py b/bitbake/lib/bb/ui/knotty2.py
deleted file mode 100644
index 57ad67f..0000000
--- a/bitbake/lib/bb/ui/knotty2.py
+++ b/dev/null
@@ -1,149 +0,0 @@
-#
-# BitBake (No)TTY UI Implementation (v2)
-#
-# Handling output to TTYs or files (no TTY)
-#
-# Copyright (C) 2012 Richard Purdie
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-from bb.ui import knotty
-import logging
-import sys
-import os
-import fcntl
-import struct
-import copy
-logger = logging.getLogger("BitBake")
-
-class InteractConsoleLogFilter(logging.Filter):
- def __init__(self, tf, format):
- self.tf = tf
- self.format = format
-
- def filter(self, record):
- if record.levelno == self.format.NOTE and (record.msg.startswith("Running") or record.msg.startswith("package ")):
- return False
- self.tf.clearFooter()
- return True
-
-class TerminalFilter2(object):
- columns = 80
-
- def sigwinch_handle(self, signum, frame):
- self.columns = self.getTerminalColumns()
- if self._sigwinch_default:
- self._sigwinch_default(signum, frame)
-
- def getTerminalColumns(self):
- def ioctl_GWINSZ(fd):
- try:
- cr = struct.unpack('hh', fcntl.ioctl(fd, self.termios.TIOCGWINSZ, '1234'))
- except:
- return None
- return cr
- cr = ioctl_GWINSZ(sys.stdout.fileno())
- if not cr:
- try:
- fd = os.open(os.ctermid(), os.O_RDONLY)
- cr = ioctl_GWINSZ(fd)
- os.close(fd)
- except:
- pass
- if not cr:
- try:
- cr = (env['LINES'], env['COLUMNS'])
- except:
- cr = (25, 80)
- return cr[1]
-
- def __init__(self, main, helper, console, format):
- self.main = main
- self.helper = helper
- self.cuu = None
- self.stdinbackup = None
- self.interactive = sys.stdout.isatty()
- self.footer_present = False
- self.lastpids = []
-
- if not self.interactive:
- return
-
- import curses
- import termios
- self.curses = curses
- self.termios = termios
- try:
- fd = sys.stdin.fileno()
- self.stdinbackup = termios.tcgetattr(fd)
- new = copy.deepcopy(self.stdinbackup)
- new[3] = new[3] & ~termios.ECHO
- termios.tcsetattr(fd, termios.TCSADRAIN, new)
- curses.setupterm()
- self.ed = curses.tigetstr("ed")
- if self.ed:
- self.cuu = curses.tigetstr("cuu")
- try:
- self._sigwinch_default = signal.getsignal(signal.SIGWINCH)
- signal.signal(signal.SIGWINCH, self.sigwinch_handle)
- except:
- pass
- self.columns = self.getTerminalColumns()
- except:
- self.cuu = None
- console.addFilter(InteractConsoleLogFilter(self, format))
-
- def clearFooter(self):
- if self.footer_present:
- lines = self.footer_present
- sys.stdout.write(self.curses.tparm(self.cuu, lines))
- sys.stdout.write(self.curses.tparm(self.ed))
- self.footer_present = False
-
- def updateFooter(self):
- if not self.cuu:
- return
- activetasks = self.helper.running_tasks
- failedtasks = self.helper.failed_tasks
- runningpids = self.helper.running_pids
- if self.footer_present and (self.lastpids == runningpids):
- return
- if self.footer_present:
- self.clearFooter()
- if not activetasks:
- return
- tasks = []
- for t in runningpids:
- tasks.append("%s (pid %s)" % (activetasks[t]["title"], t))
-
- if self.main.shutdown:
- content = "Waiting for %s running tasks to finish:" % len(activetasks)
- else:
- content = "Currently %s running tasks (%s of %s):" % (len(activetasks), self.helper.tasknumber_current, self.helper.tasknumber_total)
- print content
- lines = 1 + int(len(content) / (self.columns + 1))
- for tasknum, task in enumerate(tasks):
- content = "%s: %s" % (tasknum, task)
- print content
- lines = lines + 1 + int(len(content) / (self.columns + 1))
- self.footer_present = lines
- self.lastpids = runningpids[:]
-
- def finish(self):
- if self.stdinbackup:
- fd = sys.stdin.fileno()
- self.termios.tcsetattr(fd, self.termios.TCSADRAIN, self.stdinbackup)
-
-def main(server, eventHandler):
- return bb.ui.knotty.main(server, eventHandler, TerminalFilter2)
next reply other threads:[~2012-08-15 17:02 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-15 16:50 Richard Purdie [this message]
2012-08-15 16:56 ` [PATCH] knotty: Fold knotty2 into knotty and make it the default Jason Wessel
2012-08-15 17:03 ` Richard Purdie
2012-08-15 19:20 ` Chris Larson
2012-08-15 21:52 ` Richard Purdie
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=1345049422.14667.11.camel@ted \
--to=richard.purdie@linuxfoundation.org \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.