mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1422302 - Create python/mozterm for sharing terminal blessings across modules r=gps
This is a new module that will provide a place to store some common abstractions around the 'blessings' module. The main entrypoint is: from mozterm import Terminal term = Terminal() If blessings is available, this will return a blessings.Terminal() object. If it isn't available, or something went wrong on import, this will return a NullTerminal() object, which is a drop-in replacement that does no formatting. MozReview-Commit-ID: 6c63svm4tM5 --HG-- extra : rebase_source : 9ab221774d92a418d9b098d79bb2c88f75d937f8
This commit is contained in:
parent
914342129b
commit
0e697ce235
@ -2,6 +2,7 @@ mozilla.pth:python/mach
|
||||
mozilla.pth:python/mozboot
|
||||
mozilla.pth:python/mozbuild
|
||||
mozilla.pth:python/mozlint
|
||||
mozilla.pth:python/mozterm
|
||||
mozilla.pth:python/mozversioncontrol
|
||||
mozilla.pth:third_party/python/blessings
|
||||
mozilla.pth:third_party/python/compare-locales
|
||||
|
@ -40,6 +40,7 @@ PYTHON_UNITTEST_MANIFESTS += [
|
||||
'mach/mach/test/python.ini',
|
||||
'mozbuild/dumbmake/test/python.ini',
|
||||
'mozlint/test/python.ini',
|
||||
'mozterm/test/python.ini',
|
||||
'mozversioncontrol/test/python.ini',
|
||||
]
|
||||
|
||||
|
@ -4,30 +4,10 @@
|
||||
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from mozterm import Terminal
|
||||
|
||||
from ..result import ResultContainer
|
||||
|
||||
try:
|
||||
import blessings
|
||||
except ImportError:
|
||||
blessings = None
|
||||
|
||||
|
||||
class NullTerminal(object):
|
||||
"""Replacement for `blessings.Terminal()` that does no formatting."""
|
||||
class NullCallableString(unicode):
|
||||
"""A dummy callable Unicode stolen from blessings"""
|
||||
def __new__(cls):
|
||||
new = unicode.__new__(cls, u'')
|
||||
return new
|
||||
|
||||
def __call__(self, *args):
|
||||
if len(args) != 1 or isinstance(args[0], int):
|
||||
return u''
|
||||
return args[0]
|
||||
|
||||
def __getattr__(self, attr):
|
||||
return self.NullCallableString()
|
||||
|
||||
|
||||
class StylishFormatter(object):
|
||||
"""Formatter based on the eslint default."""
|
||||
@ -45,11 +25,8 @@ class StylishFormatter(object):
|
||||
fmt = " {c1}{lineno}{column} {c2}{level}{normal} {message} {c1}{rule}({linter}){normal}"
|
||||
fmt_summary = "{t.bold}{c}\u2716 {problem} ({error}, {warning}{failure}){t.normal}"
|
||||
|
||||
def __init__(self, disable_colors=None):
|
||||
if disable_colors or not blessings:
|
||||
self.term = NullTerminal()
|
||||
else:
|
||||
self.term = blessings.Terminal()
|
||||
def __init__(self, disable_colors=False):
|
||||
self.term = Terminal(disable_styling=disable_colors)
|
||||
self.num_colors = self.term.number_of_colors
|
||||
|
||||
def color(self, color):
|
||||
|
6
python/mozterm/mozterm/__init__.py
Normal file
6
python/mozterm/mozterm/__init__.py
Normal file
@ -0,0 +1,6 @@
|
||||
# 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, NullTerminal # noqa
|
49
python/mozterm/mozterm/terminal.py
Normal file
49
python/mozterm/mozterm/terminal.py
Normal file
@ -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
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
class NullTerminal(object):
|
||||
"""Replacement for `blessings.Terminal()` that does no formatting."""
|
||||
number_of_colors = 0
|
||||
width = 0
|
||||
height = 0
|
||||
|
||||
def __init__(self, stream=None, **kwargs):
|
||||
self.stream = stream or sys.__stdout__
|
||||
try:
|
||||
self.is_a_tty = os.isatty(self.stream.fileno())
|
||||
except:
|
||||
self.is_a_tty = False
|
||||
|
||||
class NullCallableString(unicode):
|
||||
"""A dummy callable Unicode stolen from blessings"""
|
||||
def __new__(cls):
|
||||
new = unicode.__new__(cls, '')
|
||||
return new
|
||||
|
||||
def __call__(self, *args):
|
||||
if len(args) != 1 or isinstance(args[0], int):
|
||||
return ''
|
||||
return args[0]
|
||||
|
||||
def __getattr__(self, attr):
|
||||
return self.NullCallableString()
|
||||
|
||||
|
||||
def Terminal(raises=False, disable_styling=False, **kwargs):
|
||||
if disable_styling:
|
||||
return NullTerminal(**kwargs)
|
||||
|
||||
try:
|
||||
import blessings
|
||||
except Exception:
|
||||
if raises:
|
||||
raise
|
||||
return NullTerminal(**kwargs)
|
||||
return blessings.Terminal(**kwargs)
|
4
python/mozterm/test/python.ini
Normal file
4
python/mozterm/test/python.ini
Normal file
@ -0,0 +1,4 @@
|
||||
[DEFAULT]
|
||||
subsuite = mozterm
|
||||
|
||||
[test_terminal.py]
|
51
python/mozterm/test/test_terminal.py
Normal file
51
python/mozterm/test/test_terminal.py
Normal file
@ -0,0 +1,51 @@
|
||||
# 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
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import mozunit
|
||||
import pytest
|
||||
|
||||
from mozterm import Terminal, NullTerminal
|
||||
|
||||
|
||||
def test_terminal():
|
||||
blessings = pytest.importorskip('blessings')
|
||||
term = Terminal()
|
||||
assert isinstance(term, blessings.Terminal)
|
||||
|
||||
term = Terminal(disable_styling=True)
|
||||
assert isinstance(term, NullTerminal)
|
||||
|
||||
del sys.modules['blessings']
|
||||
orig = sys.path[:]
|
||||
for path in orig:
|
||||
if 'blessings' in path:
|
||||
sys.path.remove(path)
|
||||
|
||||
term = Terminal()
|
||||
assert isinstance(term, NullTerminal)
|
||||
|
||||
with pytest.raises(ImportError):
|
||||
term = Terminal(raises=True)
|
||||
|
||||
sys.path = orig
|
||||
|
||||
|
||||
def test_null_terminal():
|
||||
term = NullTerminal()
|
||||
assert term.red("foo") == "foo"
|
||||
assert term.red == ""
|
||||
assert term.color(1) == ""
|
||||
assert term.number_of_colors == 0
|
||||
assert term.width == 0
|
||||
assert term.height == 0
|
||||
assert term.is_a_tty == os.isatty(sys.stdout.fileno())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
mozunit.main()
|
@ -128,6 +128,22 @@ mozlint:
|
||||
files-changed:
|
||||
- 'python/mozlint/**'
|
||||
|
||||
mozterm:
|
||||
description: python/mozterm unit tests
|
||||
platform: linux64/opt
|
||||
treeherder:
|
||||
symbol: py(term)
|
||||
worker:
|
||||
by-platform:
|
||||
linux64.*:
|
||||
docker-image: {in-tree: "lint"}
|
||||
max-run-time: 3600
|
||||
run:
|
||||
mach: python-test --subsuite mozterm
|
||||
when:
|
||||
files-changed:
|
||||
- 'python/mozterm/**'
|
||||
|
||||
mozversioncontrol:
|
||||
description: python/mozversioncontrol unit tests
|
||||
platform: linux64/opt
|
||||
|
@ -12,6 +12,7 @@ flake8:
|
||||
- python/mach_commands.py
|
||||
- python/mozboot
|
||||
- python/mozlint
|
||||
- python/mozterm
|
||||
- python/mozversioncontrol
|
||||
- security/manager
|
||||
- taskcluster
|
||||
|
@ -11,18 +11,15 @@ import sys
|
||||
from distutils.spawn import find_executable
|
||||
|
||||
from mozboot.util import get_state_dir
|
||||
from mozterm import Terminal
|
||||
|
||||
from .. import preset as pset
|
||||
from ..cli import BaseTryParser
|
||||
from ..tasks import generate_tasks
|
||||
from ..vcs import VCSHelper
|
||||
|
||||
try:
|
||||
import blessings
|
||||
terminal = blessings.Terminal()
|
||||
except ImportError:
|
||||
from mozlint.formatters.stylish import NullTerminal
|
||||
terminal = NullTerminal()
|
||||
terminal = Terminal()
|
||||
|
||||
|
||||
FZF_NOT_FOUND = """
|
||||
Could not find the `fzf` binary.
|
||||
|
Loading…
Reference in New Issue
Block a user