зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1422302 - Move mozbuild.controller.building.Footer to mozterm r=gps
This makes it a bit easier to share with other parts of the tree, like test and linting. MozReview-Commit-ID: 8Gzk8uOF5zK --HG-- extra : rebase_source : 9354614c78481ca4cbe0327501018a95792e9351
This commit is contained in:
Родитель
0e697ce235
Коммит
80e7a5e3f5
|
@ -31,6 +31,7 @@ except Exception:
|
|||
|
||||
from mach.mixin.logging import LoggingMixin
|
||||
from mozsystemmonitor.resourcemonitor import SystemResourceMonitor
|
||||
from mozterm.widgets import Footer
|
||||
|
||||
import mozpack.path as mozpath
|
||||
|
||||
|
@ -563,60 +564,6 @@ class TerminalLoggingHandler(logging.Handler):
|
|||
self.release()
|
||||
|
||||
|
||||
class Footer(object):
|
||||
"""Handles display of a footer in a terminal.
|
||||
|
||||
This class implements the functionality common to all mach commands
|
||||
that render a footer.
|
||||
"""
|
||||
|
||||
def __init__(self, terminal):
|
||||
# terminal is a blessings.Terminal.
|
||||
self._t = terminal
|
||||
self._fh = sys.stdout
|
||||
|
||||
def clear(self):
|
||||
"""Removes the footer from the current terminal."""
|
||||
self._fh.write(self._t.move_x(0))
|
||||
self._fh.write(self._t.clear_eol())
|
||||
|
||||
def write(self, parts):
|
||||
"""Write some output in the footer, accounting for terminal width.
|
||||
|
||||
parts is a list of 2-tuples of (encoding_function, input).
|
||||
None means no encoding."""
|
||||
|
||||
# We don't want to write more characters than the current width of the
|
||||
# terminal otherwise wrapping may result in weird behavior. We can't
|
||||
# simply truncate the line at terminal width characters because a)
|
||||
# non-viewable escape characters count towards the limit and b) we
|
||||
# don't want to truncate in the middle of an escape sequence because
|
||||
# subsequent output would inherit the escape sequence.
|
||||
max_width = self._t.width
|
||||
written = 0
|
||||
write_pieces = []
|
||||
for part in parts:
|
||||
try:
|
||||
func, part = part
|
||||
encoded = getattr(self._t, func)(part)
|
||||
except ValueError:
|
||||
encoded = part
|
||||
|
||||
len_part = len(part)
|
||||
len_spaces = len(write_pieces)
|
||||
if written + len_part + len_spaces > max_width:
|
||||
write_pieces.append(part[0:max_width - written - len_spaces])
|
||||
written += len_part
|
||||
break
|
||||
|
||||
write_pieces.append(encoded)
|
||||
written += len_part
|
||||
|
||||
with self._t.location():
|
||||
self._t.move(self._t.height-1,0)
|
||||
self._fh.write(' '.join(write_pieces))
|
||||
|
||||
|
||||
class BuildProgressFooter(Footer):
|
||||
"""Handles display of a build progress indicator in a terminal.
|
||||
|
||||
|
@ -651,7 +598,6 @@ class BuildProgressFooter(Footer):
|
|||
self.write(parts)
|
||||
|
||||
|
||||
|
||||
class OutputManager(LoggingMixin):
|
||||
"""Handles writing job output to a terminal or log."""
|
||||
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from .terminal import Terminal
|
||||
|
||||
|
||||
class BaseWidget(object):
|
||||
def __init__(self, terminal=None):
|
||||
self.term = terminal or Terminal()
|
||||
self.stream = self.term.stream
|
||||
|
||||
|
||||
class Footer(BaseWidget):
|
||||
"""Handles display of a footer in a terminal."""
|
||||
|
||||
def clear(self):
|
||||
"""Removes the footer from the current terminal."""
|
||||
self.stream.write(self.term.move_x(0))
|
||||
self.stream.write(self.term.clear_eol())
|
||||
|
||||
def write(self, parts):
|
||||
"""Write some output in the footer, accounting for terminal width.
|
||||
|
||||
parts is a list of 2-tuples of (encoding_function, input).
|
||||
None means no encoding."""
|
||||
|
||||
# We don't want to write more characters than the current width of the
|
||||
# terminal otherwise wrapping may result in weird behavior. We can't
|
||||
# simply truncate the line at terminal width characters because a)
|
||||
# non-viewable escape characters count towards the limit and b) we
|
||||
# don't want to truncate in the middle of an escape sequence because
|
||||
# subsequent output would inherit the escape sequence.
|
||||
max_width = self.term.width
|
||||
written = 0
|
||||
write_pieces = []
|
||||
for part in parts:
|
||||
try:
|
||||
func, part = part
|
||||
encoded = getattr(self.term, func)(part)
|
||||
except ValueError:
|
||||
encoded = part
|
||||
|
||||
len_part = len(part)
|
||||
len_spaces = len(write_pieces)
|
||||
if written + len_part + len_spaces > max_width:
|
||||
write_pieces.append(part[0:max_width - written - len_spaces])
|
||||
written += len_part
|
||||
break
|
||||
|
||||
write_pieces.append(encoded)
|
||||
written += len_part
|
||||
|
||||
with self.term.location():
|
||||
self.term.move(self.term.height-1, 0)
|
||||
self.stream.write(' '.join(write_pieces))
|
|
@ -2,3 +2,4 @@
|
|||
subsuite = mozterm
|
||||
|
||||
[test_terminal.py]
|
||||
[test_widgets.py]
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from io import StringIO
|
||||
|
||||
import mozunit
|
||||
import pytest
|
||||
|
||||
from mozterm import Terminal
|
||||
from mozterm.widgets import Footer
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def terminal(monkeypatch):
|
||||
blessings = pytest.importorskip('blessings')
|
||||
|
||||
kind = 'xterm-256color'
|
||||
try:
|
||||
term = Terminal(stream=StringIO(), force_styling=True, kind=kind)
|
||||
except blessings.curses.error:
|
||||
pytest.skip("terminal '{}' not found".format(kind))
|
||||
|
||||
# For some reason blessings returns None for width/height though a comment
|
||||
# says that shouldn't ever happen.
|
||||
monkeypatch.setattr(term, '_height_and_width', lambda: (100, 100))
|
||||
return term
|
||||
|
||||
|
||||
def test_footer(terminal):
|
||||
footer = Footer(terminal=terminal)
|
||||
footer.write([
|
||||
('dim', 'foo'),
|
||||
('green', 'bar'),
|
||||
])
|
||||
value = terminal.stream.getvalue()
|
||||
expected = "\x1b7\x1b[2mfoo\x1b(B\x1b[m \x1b[32mbar\x1b(B\x1b[m\x1b8"
|
||||
assert value == expected
|
||||
|
||||
footer.clear()
|
||||
value = terminal.stream.getvalue()[len(value):]
|
||||
expected = "\x1b[1G\x1b[K"
|
||||
assert value == expected
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
mozunit.main()
|
Загрузка…
Ссылка в новой задаче