summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/progress.py
diff options
context:
space:
mode:
authorPaul Eggleton <paul.eggleton@linux.intel.com>2016-06-23 22:59:05 +1200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-07-08 09:57:26 +0100
commitac5e720575dd3c8f86514a7a646de82c8cc28e17 (patch)
tree9c0cec5d764f1b9fb8f33d5f094d87a8fbc89ab5 /bitbake/lib/bb/progress.py
parent1cf6e14a6c5ddb4daec1c1e0cce113eea8570545 (diff)
downloadpoky-ac5e720575dd3c8f86514a7a646de82c8cc28e17.tar.gz
bitbake: lib: implement basic task progress support
For long-running tasks where we have some output from the task that gives us some idea of the progress of the task (such as a percentage complete), provide the means to scrape the output for that progress information and show it to the user in the default knotty terminal output in the form of a progress bar. This is implemented using a new TaskProgress event as well as some code we can insert to do output scanning/filtering. Any task can fire TaskProgress events; however, if you have a shell task whose output you wish to scan for progress information, you just need to set the "progress" varflag on the task. This can be set to: * "percent" to just look for a number followed by a % sign * "percent:<regex>" to specify your own regex matching a percentage value (must have a single group which matches the percentage number) * "outof:<regex>" to look for the specified regex matching x out of y items completed (must have two groups - first group needs to be x, second y). We can potentially extend this in future but this should be a good start. Part of the implementation for [YOCTO #5383]. (Bitbake rev: 0d275fc5b6531957a6189069b04074065bb718a0) Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/bb/progress.py')
-rw-r--r--bitbake/lib/bb/progress.py86
1 files changed, 86 insertions, 0 deletions
diff --git a/bitbake/lib/bb/progress.py b/bitbake/lib/bb/progress.py
new file mode 100644
index 0000000000..bab8e9465d
--- /dev/null
+++ b/bitbake/lib/bb/progress.py
@@ -0,0 +1,86 @@
1"""
2BitBake progress handling code
3"""
4
5# Copyright (C) 2016 Intel Corporation
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20import sys
21import re
22import time
23import bb.event
24import bb.build
25
26class ProgressHandler(object):
27 """
28 Base class that can pretend to be a file object well enough to be
29 used to build objects to intercept console output and determine the
30 progress of some operation.
31 """
32 def __init__(self, d, outfile=None):
33 self._progress = 0
34 self._data = d
35 self._lastevent = 0
36 if outfile:
37 self._outfile = outfile
38 else:
39 self._outfile = sys.stdout
40
41 def _fire_progress(self, taskprogress, rate=None):
42 """Internal function to fire the progress event"""
43 bb.event.fire(bb.build.TaskProgress(taskprogress, rate), self._data)
44
45 def write(self, string):
46 self._outfile.write(string)
47
48 def flush(self):
49 self._outfile.flush()
50
51 def update(self, progress, rate=None):
52 ts = time.time()
53 if progress > 100:
54 progress = 100
55 if progress != self._progress or self._lastevent + 1 < ts:
56 self._fire_progress(progress, rate)
57 self._lastevent = ts
58 self._progress = progress
59
60class BasicProgressHandler(ProgressHandler):
61 def __init__(self, d, regex=r'(\d+)%', outfile=None):
62 super(BasicProgressHandler, self).__init__(d, outfile)
63 self._regex = re.compile(regex)
64 # Send an initial progress event so the bar gets shown
65 self._fire_progress(0)
66
67 def write(self, string):
68 percs = self._regex.findall(string)
69 if percs:
70 progress = int(percs[-1])
71 self.update(progress)
72 super(BasicProgressHandler, self).write(string)
73
74class OutOfProgressHandler(ProgressHandler):
75 def __init__(self, d, regex, outfile=None):
76 super(OutOfProgressHandler, self).__init__(d, outfile)
77 self._regex = re.compile(regex)
78 # Send an initial progress event so the bar gets shown
79 self._fire_progress(0)
80
81 def write(self, string):
82 nums = self._regex.findall(string)
83 if nums:
84 progress = (float(nums[-1][0]) / float(nums[-1][1])) * 100
85 self.update(progress)
86 super(OutOfProgressHandler, self).write(string)