From ebf9bc4e0af335b430958b5835f4d9afa143ee33 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 6 Jul 2016 23:47:59 +0200 Subject: [PATCH] Improve version output --- qutebrowser/app.py | 7 +- qutebrowser/utils/version.py | 69 +++++++++++-------- tests/helpers/stubs.py | 11 +++- tests/unit/utils/test_version.py | 109 ++++++++++++++++++++----------- 4 files changed, 124 insertions(+), 72 deletions(-) diff --git a/qutebrowser/app.py b/qutebrowser/app.py index a90532eaf..c0662eaa0 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -64,12 +64,7 @@ qApp = None def run(args): """Initialize everything and run the application.""" if args.version: - print(version.version(short=True)) - print() - print() - print(qutebrowser.__copyright__) - print() - print(version.GPL_BOILERPLATE.strip()) + print(version.version()) sys.exit(usertypes.Exit.ok) if args.temp_basedir: diff --git a/qutebrowser/utils/version.py b/qutebrowser/utils/version.py index f02a3c848..f4660cd9b 100644 --- a/qutebrowser/utils/version.py +++ b/qutebrowser/utils/version.py @@ -110,11 +110,19 @@ def _release_info(): Return: list of (filename, content) tuples. """ + blacklisted = ['ANSI_COLOR=', 'HOME_URL=', 'SUPPORT_URL=', + 'BUG_REPORT_URL='] data = [] for fn in glob.glob("/etc/*-release"): + lines = [] try: with open(fn, 'r', encoding='utf-8') as f: - data.append((fn, f.read())) + for line in f.read().strip().splitlines(): + if not any(line.startswith(bl) for bl in blacklisted): + lines.append(line) + + if lines: + data.append((fn, '\n'.join(lines))) except OSError: log.misc.exception("Error while reading {}.".format(fn)) return data @@ -136,6 +144,7 @@ def _module_versions(): ('yaml', ['__version__']), ('cssutils', ['__version__']), ('typing', []), + ('PyQt5.QtWebEngineWidgets', []), ]) for name, attributes in modules.items(): try: @@ -210,42 +219,50 @@ def _pdfjs_version(): return '{} ({})'.format(pdfjs_version, file_path) -def version(short=False): - """Return a string with various version informations. - - Args: - short: Return a shortened output. - """ +def version(): + """Return a string with various version informations.""" lines = ["qutebrowser v{}".format(qutebrowser.__version__)] gitver = _git_str() if gitver is not None: lines.append("Git commit: {}".format(gitver)) + + if qVersion() != QT_VERSION_STR: + qt_version = 'Qt: {} (compiled {})'.format(qVersion(), QT_VERSION_STR) + else: + qt_version = 'Qt: {}'.format(qVersion()) + lines += [ '', '{}: {}'.format(platform.python_implementation(), platform.python_version()), - 'Qt: {}, runtime: {}'.format(QT_VERSION_STR, qVersion()), + qt_version, 'PyQt: {}'.format(PYQT_VERSION_STR), + '', ] - if not short: - style = QApplication.instance().style() - lines += [ - 'Style: {}'.format(style.metaObject().className()), - 'Desktop: {}'.format(os.environ.get('DESKTOP_SESSION')), - ] + lines += _module_versions() - lines += _module_versions() + lines += [ + 'pdf.js: {}'.format(_pdfjs_version()), + 'Webkit: {}'.format(qWebKitVersion()), + 'Harfbuzz: {}'.format(os.environ.get('QT_HARFBUZZ', 'system')), + 'SSL: {}'.format(QSslSocket.sslLibraryVersionString()), + '', + ] - lines += [ - 'pdf.js: {}'.format(_pdfjs_version()), - 'Webkit: {}'.format(qWebKitVersion()), - 'Harfbuzz: {}'.format(os.environ.get('QT_HARFBUZZ', 'system')), - 'SSL: {}'.format(QSslSocket.sslLibraryVersionString()), - '', - 'Frozen: {}'.format(hasattr(sys, 'frozen')), - 'Platform: {}, {}'.format(platform.platform(), - platform.architecture()[0]), - ] - lines += _os_info() + qapp = QApplication.instance() + if qapp: + style = qapp.style() + lines.append('Style: {}'.format(style.metaObject().className())) + + importpath = os.path.dirname(os.path.abspath(qutebrowser.__file__)) + + lines += [ + 'Platform: {}, {}'.format(platform.platform(), + platform.architecture()[0]), + 'Desktop: {}'.format(os.environ.get('DESKTOP_SESSION')), + 'Frozen: {}'.format(hasattr(sys, 'frozen')), + "Imported from {}".format(importpath), + ] + lines += _os_info() return '\n'.join(lines) diff --git a/tests/helpers/stubs.py b/tests/helpers/stubs.py index d08b35f60..d6c8b69d0 100644 --- a/tests/helpers/stubs.py +++ b/tests/helpers/stubs.py @@ -124,8 +124,15 @@ class FakeQApplication: """Stub to insert as QApplication module.""" - def __init__(self, style=None, all_widgets=None, active_window=None): - self.instance = mock.Mock(return_value=self) + UNSET = object() + + def __init__(self, style=None, all_widgets=None, active_window=None, + instance=UNSET): + + if instance is self.UNSET: + self.instance = mock.Mock(return_value=self) + else: + self.instance = mock.Mock(return_value=instance) self.style = mock.Mock(spec=QCommonStyle) self.style().metaObject().className.return_value = style diff --git a/tests/unit/utils/test_version.py b/tests/unit/utils/test_version.py index 6a1a1522f..920e961ad 100644 --- a/tests/unit/utils/test_version.py +++ b/tests/unit/utils/test_version.py @@ -276,13 +276,24 @@ class ReleaseInfoFake: @pytest.mark.parametrize('files, expected', [ + # no files -> no output ({}, []), - ({'file': ['']}, [('file', '')]), - ({'file': []}, [('file', '')]), + # empty files are stripped + ({'file': ['']}, []), + ({'file': []}, []), + # newlines at EOL are stripped ( {'file1': ['foo\n', 'bar\n'], 'file2': ['baz\n']}, - [('file1', 'foo\nbar\n'), ('file2', 'baz\n')] + [('file1', 'foo\nbar'), ('file2', 'baz')] ), + # blacklisted lines + ( + {'file': ['HOME_URL=example.com\n', 'NAME=FOO']}, + [('file', 'NAME=FOO')] + ), + # only blacklisted lines + ({'file': ['HOME_URL=example.com']}, []), + # broken file (None, []), ]) def test_release_info(files, expected, caplog, monkeypatch): @@ -326,6 +337,7 @@ class ImportFake: 'yaml': True, 'cssutils': True, 'typing': True, + 'PyQt5.QtWebEngineWidgets': True, } self.version_attribute = '__version__' self.version = '1.2.3' @@ -385,7 +397,8 @@ class TestModuleVersions: """Test with all modules present in version 1.2.3.""" expected = ['sip: yes', 'colorama: 1.2.3', 'pypeg2: 1.2.3', 'jinja2: 1.2.3', 'pygments: 1.2.3', 'yaml: 1.2.3', - 'cssutils: 1.2.3', 'typing: yes'] + 'cssutils: 1.2.3', 'typing: yes', + 'PyQt5.QtWebEngineWidgets: yes'] assert version._module_versions() == expected @pytest.mark.parametrize('module, idx, expected', [ @@ -407,12 +420,15 @@ class TestModuleVersions: @pytest.mark.parametrize('value, expected', [ ('VERSION', ['sip: yes', 'colorama: 1.2.3', 'pypeg2: yes', 'jinja2: yes', 'pygments: yes', 'yaml: yes', - 'cssutils: yes', 'typing: yes']), + 'cssutils: yes', 'typing: yes', + 'PyQt5.QtWebEngineWidgets: yes']), ('SIP_VERSION_STR', ['sip: 1.2.3', 'colorama: yes', 'pypeg2: yes', 'jinja2: yes', 'pygments: yes', 'yaml: yes', - 'cssutils: yes', 'typing: yes']), + 'cssutils: yes', 'typing: yes', + 'PyQt5.QtWebEngineWidgets: yes']), (None, ['sip: yes', 'colorama: yes', 'pypeg2: yes', 'jinja2: yes', - 'pygments: yes', 'yaml: yes', 'cssutils: yes', 'typing: yes']), + 'pygments: yes', 'yaml: yes', 'cssutils: yes', 'typing: yes', + 'PyQt5.QtWebEngineWidgets: yes']), ]) def test_version_attribute(self, value, expected, import_fake): """Test with a different version attribute. @@ -598,24 +614,23 @@ class FakeQSslSocket: return self._version -@pytest.mark.parametrize('git_commit, harfbuzz, frozen, short', [ - (True, True, False, False), # normal - (False, True, False, False), # no git commit - (True, False, False, False), # HARFBUZZ unset - (True, True, True, False), # frozen - (True, True, False, True), # short - (False, True, False, True), # short and no git commit +@pytest.mark.parametrize('git_commit, harfbuzz, frozen, style, equal_qt', [ + (True, True, False, True, True), # normal + (False, True, False, True, True), # no git commit + (True, False, False, True, True), # HARFBUZZ unset + (True, True, True, True, True), # frozen + (True, True, True, False, True), # no style + (True, True, False, True, False), # different Qt ]) -def test_version_output(git_commit, harfbuzz, frozen, short, stubs, - monkeypatch): +def test_version_output(git_commit, harfbuzz, frozen, style, equal_qt, + stubs, monkeypatch): """Test version.version().""" patches = { + 'qutebrowser.__file__': '/IMPORTPATH/__init__.py', 'qutebrowser.__version__': 'VERSION', '_git_str': lambda: ('GIT COMMIT' if git_commit else None), 'platform.python_implementation': lambda: 'PYTHON IMPLEMENTATION', 'platform.python_version': lambda: 'PYTHON VERSION', - 'QT_VERSION_STR': 'QT VERSION', - 'qVersion': lambda: 'QT RUNTIME VERSION', 'PYQT_VERSION_STR': 'PYQT VERSION', '_module_versions': lambda: ['MODULE VERSION 1', 'MODULE VERSION 2'], '_pdfjs_version': lambda: 'PDFJS VERSION', @@ -624,9 +639,20 @@ def test_version_output(git_commit, harfbuzz, frozen, short, stubs, 'platform.platform': lambda: 'PLATFORM', 'platform.architecture': lambda: ('ARCHITECTURE', ''), '_os_info': lambda: ['OS INFO 1', 'OS INFO 2'], - 'QApplication': stubs.FakeQApplication(style='STYLE'), } + if equal_qt: + patches['QT_VERSION_STR'] = 'QT VERSION' + patches['qVersion'] = lambda: 'QT VERSION' + else: + patches['QT_VERSION_STR'] = 'QT VERSION' + patches['qVersion'] = lambda: 'QT RUNTIME VERSION' + + if style: + patches['QApplication'] = stubs.FakeQApplication(style='STYLE') + else: + patches['QApplication'] = stubs.FakeQApplication(instance=None) + for attr, val in patches.items(): monkeypatch.setattr('qutebrowser.utils.version.' + attr, val) @@ -646,8 +672,22 @@ def test_version_output(git_commit, harfbuzz, frozen, short, stubs, qutebrowser vVERSION {git_commit} PYTHON IMPLEMENTATION: PYTHON VERSION - Qt: QT VERSION, runtime: QT RUNTIME VERSION + Qt: {qt} PyQt: PYQT VERSION + + MODULE VERSION 1 + MODULE VERSION 2 + pdf.js: PDFJS VERSION + Webkit: WEBKIT VERSION + Harfbuzz: {harfbuzz} + SSL: SSL VERSION + {style} + Platform: PLATFORM, ARCHITECTURE + Desktop: DESKTOP + Frozen: {frozen} + Imported from /IMPORTPATH + OS INFO 1 + OS INFO 2 """.lstrip('\n')) if git_commit: @@ -655,25 +695,18 @@ def test_version_output(git_commit, harfbuzz, frozen, short, stubs, else: substitutions = {'git_commit': ''} - if not short: - template += textwrap.dedent(""" - Style: STYLE - Desktop: DESKTOP - MODULE VERSION 1 - MODULE VERSION 2 - pdf.js: PDFJS VERSION - Webkit: WEBKIT VERSION - Harfbuzz: {harfbuzz} - SSL: SSL VERSION + if style: + substitutions['style'] = '\nStyle: STYLE' + else: + substitutions['style'] = '' - Frozen: {frozen} - Platform: PLATFORM, ARCHITECTURE - OS INFO 1 - OS INFO 2 - """.lstrip('\n')) + if equal_qt: + substitutions['qt'] = 'QT VERSION' + else: + substitutions['qt'] = 'QT RUNTIME VERSION (compiled QT VERSION)' - substitutions['harfbuzz'] = 'HARFBUZZ' if harfbuzz else 'system' - substitutions['frozen'] = str(frozen) + substitutions['harfbuzz'] = 'HARFBUZZ' if harfbuzz else 'system' + substitutions['frozen'] = str(frozen) expected = template.rstrip('\n').format(**substitutions) - assert version.version(short=short) == expected + assert version.version() == expected