From 7ce442c77186aa256ed8d098cf1cd435e251c963 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Tue, 27 Sep 2016 12:01:04 +0200 Subject: [PATCH 01/13] standarddir path names in qute://version fixes #1947 --- qutebrowser/utils/version.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/qutebrowser/utils/version.py b/qutebrowser/utils/version.py index 7e0416929..f24d0d46d 100644 --- a/qutebrowser/utils/version.py +++ b/qutebrowser/utils/version.py @@ -38,7 +38,7 @@ except ImportError: # pragma: no cover qWebKitVersion = None import qutebrowser -from qutebrowser.utils import log, utils +from qutebrowser.utils import log, utils, standarddir from qutebrowser.browser import pdfjs @@ -152,6 +152,22 @@ def _module_versions(): return lines +def _path_info(): + """Get info about important path names. + + Return: + A dictionary of descriptive to actual path names. + """ + return { + 'config': standarddir.config(), + 'data': standarddir.data(), + 'system_data': standarddir.system_data(), + 'cache': standarddir.cache(), + 'download': standarddir.download(), + 'runtime': standarddir.runtime(), + } + + def _os_info(): """Get operating system info. @@ -255,4 +271,12 @@ def version(): "Imported from {}".format(importpath), ] lines += _os_info() + + lines += [ + '', + 'Paths', + ] + for name, path in _path_info().items(): + lines += [ '{}: {}'.format(name, path) ] + return '\n'.join(lines) From 10a19774598e3e9c8fec3eb8242d438b640175f0 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Tue, 27 Sep 2016 12:48:19 +0200 Subject: [PATCH 02/13] adjust version unit test to accomodate for new output from path info refs #1947 --- tests/unit/utils/test_version.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/unit/utils/test_version.py b/tests/unit/utils/test_version.py index 16f47b473..86c2e92e2 100644 --- a/tests/unit/utils/test_version.py +++ b/tests/unit/utils/test_version.py @@ -644,6 +644,7 @@ def test_version_output(git_commit, frozen, style, equal_qt, with_webkit, 'platform.platform': lambda: 'PLATFORM', 'platform.architecture': lambda: ('ARCHITECTURE', ''), '_os_info': lambda: ['OS INFO 1', 'OS INFO 2'], + '_path_info': lambda: {'PATH DESC': 'PATH NAME'}, 'QApplication': (stubs.FakeQApplication(style='STYLE') if style else stubs.FakeQApplication(instance=None)), } @@ -674,6 +675,9 @@ def test_version_output(git_commit, frozen, style, equal_qt, with_webkit, Imported from {import_path} OS INFO 1 OS INFO 2 + + Paths + PATH DESC: PATH NAME """.lstrip('\n')) substitutions = { From 0c4c84d821980c35a4cbac056e15224fb6a69c98 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Tue, 27 Sep 2016 13:22:28 +0200 Subject: [PATCH 03/13] adhere to style guide --- qutebrowser/utils/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qutebrowser/utils/version.py b/qutebrowser/utils/version.py index f24d0d46d..12009335f 100644 --- a/qutebrowser/utils/version.py +++ b/qutebrowser/utils/version.py @@ -277,6 +277,6 @@ def version(): 'Paths', ] for name, path in _path_info().items(): - lines += [ '{}: {}'.format(name, path) ] + lines += ['{}: {}'.format(name, path)] return '\n'.join(lines) From fb68245f2ef0b79cbe6318791f9b3b1f05d2b59e Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Tue, 27 Sep 2016 15:36:18 +0200 Subject: [PATCH 04/13] unit test for utils.version._path_info() refs #1947 --- tests/unit/utils/test_version.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/unit/utils/test_version.py b/tests/unit/utils/test_version.py index 86c2e92e2..a85ed1206 100644 --- a/tests/unit/utils/test_version.py +++ b/tests/unit/utils/test_version.py @@ -313,6 +313,32 @@ def test_release_info(files, expected, caplog, monkeypatch): assert caplog.records[0].message == "Error while reading fake-file." +def test_path_info(monkeypatch): + + """Test _path_info().""" + + patches = { + 'config': lambda: 'CONFIG PATH', + 'data': lambda: 'DATA PATH', + 'system_data': lambda: 'SYSTEM DATA PATH', + 'cache': lambda: 'CACHE PATH', + 'download': lambda: 'DOWNLOAD PATH', + 'runtime': lambda: 'RUNTIME PATH', + } + + for attr, val in patches.items(): + monkeypatch.setattr('qutebrowser.utils.standarddir.' + attr, val) + + pathinfo = version._path_info() + + assert pathinfo['config'] == 'CONFIG PATH' + assert pathinfo['data'] == 'DATA PATH' + assert pathinfo['system_data'] == 'SYSTEM DATA PATH' + assert pathinfo['cache'] == 'CACHE PATH' + assert pathinfo['download'] == 'DOWNLOAD PATH' + assert pathinfo['runtime'] == 'RUNTIME PATH' + + class ImportFake: """A fake for __import__ which is used by the import_fake fixture. From a3bf53d0cdebfaef098b26e8e6545875afc513de Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Tue, 27 Sep 2016 16:01:25 +0200 Subject: [PATCH 05/13] removed blank lines around function docstring D201/D202 --- tests/unit/utils/test_version.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/unit/utils/test_version.py b/tests/unit/utils/test_version.py index a85ed1206..483f08d1e 100644 --- a/tests/unit/utils/test_version.py +++ b/tests/unit/utils/test_version.py @@ -314,9 +314,7 @@ def test_release_info(files, expected, caplog, monkeypatch): def test_path_info(monkeypatch): - """Test _path_info().""" - patches = { 'config': lambda: 'CONFIG PATH', 'data': lambda: 'DATA PATH', From 50fb4a78c7ac2d106c48e966b9f1f9a2b7831dd1 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Wed, 28 Sep 2016 10:25:40 +0200 Subject: [PATCH 06/13] early init of qapp and standarddir this fixes the error that appeared when invoked with --version --- qutebrowser/app.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/qutebrowser/app.py b/qutebrowser/app.py index dc4b629f1..345d49b97 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -62,10 +62,6 @@ qApp = None def run(args): """Initialize everything and run the application.""" - if args.version: - print(version.version()) - sys.exit(usertypes.Exit.ok) - if args.temp_basedir: args.basedir = tempfile.mkdtemp(prefix='qutebrowser-basedir-') @@ -79,6 +75,13 @@ def run(args): qApp.setApplicationVersion(qutebrowser.__version__) qApp.lastWindowClosed.connect(quitter.on_last_window_closed) + log.init.debug("Initializing directories...") + standarddir.init(args) + + if args.version: + print(version.version()) + sys.exit(usertypes.Exit.ok) + crash_handler = crashsignal.CrashHandler( app=qApp, quitter=quitter, args=args, parent=qApp) crash_handler.activate() @@ -378,9 +381,6 @@ def _init_modules(args, crash_handler): readline_bridge = readline.ReadlineBridge() objreg.register('readline-bridge', readline_bridge) - log.init.debug("Initializing directories...") - standarddir.init(args) - log.init.debug("Initializing config...") config.init(qApp) save_manager.init_autosave() From 73e1460556d15c071adc84c7303a92bef67a10e6 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Wed, 28 Sep 2016 14:38:15 +0200 Subject: [PATCH 07/13] test for --version invocation --- tests/end2end/test_invocations.py | 86 +++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/tests/end2end/test_invocations.py b/tests/end2end/test_invocations.py index eade0b911..68580e61a 100644 --- a/tests/end2end/test_invocations.py +++ b/tests/end2end/test_invocations.py @@ -21,9 +21,15 @@ import sys import logging +import re import pytest +from PyQt5.QtCore import QProcess + +from end2end.fixtures.quteprocess import QuteProc +from end2end.fixtures.testprocess import ProcessExited + def _base_args(config): """Get the arguments to pass with every invocation.""" @@ -177,3 +183,83 @@ def test_optimize(request, quteproc_new, capfd, level): # Waiting for quit to make sure no other warning is emitted quteproc_new.send_cmd(':quit') quteproc_new.wait_for_quit() + + +def test_version(request): + """Test invocation with --version argument.""" + args = ['--version'] + _base_args(request.config) + # can't use quteproc_new here because it's confused by + # early process termination + proc = QuteProc(request) + proc.proc.setProcessChannelMode(QProcess.SeparateChannels) + + try: + proc.start(args) + proc.wait_for_quit() + except ProcessExited: + assert proc.proc.exitStatus() == QProcess.NormalExit + pass + else: + assert False + + proc.proc.setReadChannel(QProcess.StandardOutput) + lines = [] + while proc.proc.canReadLine(): + line = proc.proc.readLine() + lines.append(bytes(line).decode('utf-8').rstrip('\r\n')) + output = '\n'.join(lines) + + assert re.search('^qutebrowser\s+v\d+(\.\d+)*$', + output, re.MULTILINE) is not None + assert re.search('^CPython:\s+\d+(\.\d+)*$', + output, re.MULTILINE) is not None + assert re.search('^Qt:\s+\d+(\.\d+)*$', + output, re.MULTILINE) is not None + assert re.search('^PyQt:\s+\d+(\.\d+)*$', + output, re.MULTILINE) is not None + assert re.search('^sip:\s+(\d+(\.\d+)*|no)$', + output, re.MULTILINE) is not None + assert re.search('^colorama:\s+(\d+(\.\d+)*|no)$', + output, re.MULTILINE) is not None + assert re.search('^pypeg2:\s+(\d+(\.\d+)*|no)$', + output, re.MULTILINE) is not None + assert re.search('^jinja2:\s+(\d+(\.\d+)*|no)$', + output, re.MULTILINE) is not None + assert re.search('^pygments:\s+(\d+(\.\d+)*|no)$', + output, re.MULTILINE) is not None + assert re.search('^yaml:\s+(\d+(\.\d+)*|no)$', + output, re.MULTILINE) is not None + assert re.search('^cssutils:\s+(\d+(\.\d+)*.*|no)$', + output, re.MULTILINE) is not None + assert re.search('^typing:\s+(yes|no)$', + output, re.MULTILINE) is not None + assert re.search('^PyQt5\.QtWebEngineWidgets:\s+(yes|no)$', + output, re.MULTILINE) is not None + assert re.search('^pdf\.js:\s+(\d+(\.\d+)*|no)$', + output, re.MULTILINE) is not None + assert re.search('^Webkit:\s+(\d+(\.\d+)*|no)$', + output, re.MULTILINE) is not None + assert re.search('^SSL:\s.+$', + output, re.MULTILINE) is not None + assert re.search('^Platform:\s.+,\s+.+$', + output, re.MULTILINE) is not None + assert re.search('^Frozen:\s(True|False)$', + output, re.MULTILINE) is not None + assert re.search('^Imported from .+$', + output, re.MULTILINE) is not None + assert re.search('^OS Version: .*$', + output, re.MULTILINE) is not None + assert re.search('^Paths$', + output, re.MULTILINE) is not None + assert re.search('^config:\s+.+$', + output, re.MULTILINE) is not None + assert re.search('^system_data:\s+.+$', + output, re.MULTILINE) is not None + assert re.search('^cache:\s+.+$', + output, re.MULTILINE) is not None + assert re.search('^data:\s+.+$', + output, re.MULTILINE) is not None + assert re.search('^download:\s+.+$', + output, re.MULTILINE) is not None + assert re.search('^runtime:\s+.+$', + output, re.MULTILINE) is not None From 7884594f1b65ac1a7f31b6337176ab1289409023 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Wed, 28 Sep 2016 15:31:32 +0200 Subject: [PATCH 08/13] simplify checks in version invocation test --- tests/end2end/test_invocations.py | 62 +------------------------------ 1 file changed, 2 insertions(+), 60 deletions(-) diff --git a/tests/end2end/test_invocations.py b/tests/end2end/test_invocations.py index 68580e61a..1805420c2 100644 --- a/tests/end2end/test_invocations.py +++ b/tests/end2end/test_invocations.py @@ -202,64 +202,6 @@ def test_version(request): else: assert False - proc.proc.setReadChannel(QProcess.StandardOutput) - lines = [] - while proc.proc.canReadLine(): - line = proc.proc.readLine() - lines.append(bytes(line).decode('utf-8').rstrip('\r\n')) - output = '\n'.join(lines) + output = bytes(proc.proc.readAllStandardOutput()).decode('utf-8') - assert re.search('^qutebrowser\s+v\d+(\.\d+)*$', - output, re.MULTILINE) is not None - assert re.search('^CPython:\s+\d+(\.\d+)*$', - output, re.MULTILINE) is not None - assert re.search('^Qt:\s+\d+(\.\d+)*$', - output, re.MULTILINE) is not None - assert re.search('^PyQt:\s+\d+(\.\d+)*$', - output, re.MULTILINE) is not None - assert re.search('^sip:\s+(\d+(\.\d+)*|no)$', - output, re.MULTILINE) is not None - assert re.search('^colorama:\s+(\d+(\.\d+)*|no)$', - output, re.MULTILINE) is not None - assert re.search('^pypeg2:\s+(\d+(\.\d+)*|no)$', - output, re.MULTILINE) is not None - assert re.search('^jinja2:\s+(\d+(\.\d+)*|no)$', - output, re.MULTILINE) is not None - assert re.search('^pygments:\s+(\d+(\.\d+)*|no)$', - output, re.MULTILINE) is not None - assert re.search('^yaml:\s+(\d+(\.\d+)*|no)$', - output, re.MULTILINE) is not None - assert re.search('^cssutils:\s+(\d+(\.\d+)*.*|no)$', - output, re.MULTILINE) is not None - assert re.search('^typing:\s+(yes|no)$', - output, re.MULTILINE) is not None - assert re.search('^PyQt5\.QtWebEngineWidgets:\s+(yes|no)$', - output, re.MULTILINE) is not None - assert re.search('^pdf\.js:\s+(\d+(\.\d+)*|no)$', - output, re.MULTILINE) is not None - assert re.search('^Webkit:\s+(\d+(\.\d+)*|no)$', - output, re.MULTILINE) is not None - assert re.search('^SSL:\s.+$', - output, re.MULTILINE) is not None - assert re.search('^Platform:\s.+,\s+.+$', - output, re.MULTILINE) is not None - assert re.search('^Frozen:\s(True|False)$', - output, re.MULTILINE) is not None - assert re.search('^Imported from .+$', - output, re.MULTILINE) is not None - assert re.search('^OS Version: .*$', - output, re.MULTILINE) is not None - assert re.search('^Paths$', - output, re.MULTILINE) is not None - assert re.search('^config:\s+.+$', - output, re.MULTILINE) is not None - assert re.search('^system_data:\s+.+$', - output, re.MULTILINE) is not None - assert re.search('^cache:\s+.+$', - output, re.MULTILINE) is not None - assert re.search('^data:\s+.+$', - output, re.MULTILINE) is not None - assert re.search('^download:\s+.+$', - output, re.MULTILINE) is not None - assert re.search('^runtime:\s+.+$', - output, re.MULTILINE) is not None + assert re.search(r'^qutebrowser\s+v\d+(\.\d+)', output) is not None From d00750126e8f28c799c861b8f2647843430fcaaf Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Wed, 28 Sep 2016 15:50:44 +0200 Subject: [PATCH 09/13] remove superfluous pass statement --- tests/end2end/test_invocations.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/end2end/test_invocations.py b/tests/end2end/test_invocations.py index 1805420c2..b7809779a 100644 --- a/tests/end2end/test_invocations.py +++ b/tests/end2end/test_invocations.py @@ -198,7 +198,6 @@ def test_version(request): proc.wait_for_quit() except ProcessExited: assert proc.proc.exitStatus() == QProcess.NormalExit - pass else: assert False From 656d51d44fbf2ce81e8a6efdec3118bb747b59e9 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 29 Sep 2016 06:34:20 +0200 Subject: [PATCH 10/13] Update docs --- CHANGELOG.asciidoc | 1 + README.asciidoc | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 5e0711472..2c790010c 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -135,6 +135,7 @@ Changed * `fonts -> messages.warning` * `fonts -> messages.info` - The `qute:settings` page now also shows option descriptions. +- `qute:version` and `qutebrowser --version` now show various important paths Deprecated ~~~~~~~~~~ diff --git a/README.asciidoc b/README.asciidoc index 95f2fa6df..13a2db102 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -174,6 +174,7 @@ Contributors, sorted by the number of commits in descending order: * ZDarian * Milan Svoboda * John ShaggyTwoDope Jenkins +* Daniel Karbach * Clayton Craft * Peter Vilim * knaggita @@ -259,7 +260,6 @@ Contributors, sorted by the number of commits in descending order: * Dietrich Daroch * Derek Sivers * Daniel Lu -* Daniel Karbach * Arseniy Seroka * Andy Balaam * Andreas Fischer From 42b7d1d10f419d9e2a9057806f0eed2e0d62f9a7 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 29 Sep 2016 06:35:47 +0200 Subject: [PATCH 11/13] Add a colon --- qutebrowser/utils/version.py | 2 +- tests/unit/utils/test_version.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/qutebrowser/utils/version.py b/qutebrowser/utils/version.py index 12009335f..3f6b9c8d0 100644 --- a/qutebrowser/utils/version.py +++ b/qutebrowser/utils/version.py @@ -274,7 +274,7 @@ def version(): lines += [ '', - 'Paths', + 'Paths:', ] for name, path in _path_info().items(): lines += ['{}: {}'.format(name, path)] diff --git a/tests/unit/utils/test_version.py b/tests/unit/utils/test_version.py index 483f08d1e..39ae7cea1 100644 --- a/tests/unit/utils/test_version.py +++ b/tests/unit/utils/test_version.py @@ -700,7 +700,7 @@ def test_version_output(git_commit, frozen, style, equal_qt, with_webkit, OS INFO 1 OS INFO 2 - Paths + Paths: PATH DESC: PATH NAME """.lstrip('\n')) From 9eacf426937784224145231a3302b9915567fde4 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 29 Sep 2016 06:36:31 +0200 Subject: [PATCH 12/13] Import modules --- tests/end2end/test_invocations.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/end2end/test_invocations.py b/tests/end2end/test_invocations.py index b7809779a..2102b5f54 100644 --- a/tests/end2end/test_invocations.py +++ b/tests/end2end/test_invocations.py @@ -27,8 +27,7 @@ import pytest from PyQt5.QtCore import QProcess -from end2end.fixtures.quteprocess import QuteProc -from end2end.fixtures.testprocess import ProcessExited +from end2end.fixtures import quteprocess, testprocess def _base_args(config): @@ -190,13 +189,13 @@ def test_version(request): args = ['--version'] + _base_args(request.config) # can't use quteproc_new here because it's confused by # early process termination - proc = QuteProc(request) + proc = quteprocess.QuteProc(request) proc.proc.setProcessChannelMode(QProcess.SeparateChannels) try: proc.start(args) proc.wait_for_quit() - except ProcessExited: + except testprocess.ProcessExited: assert proc.proc.exitStatus() == QProcess.NormalExit else: assert False From 609e2068165d01929863ce9ace31891b0344059f Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 29 Sep 2016 06:37:04 +0200 Subject: [PATCH 13/13] Use pytest.fail --- tests/end2end/test_invocations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/end2end/test_invocations.py b/tests/end2end/test_invocations.py index 2102b5f54..fd414db12 100644 --- a/tests/end2end/test_invocations.py +++ b/tests/end2end/test_invocations.py @@ -198,7 +198,7 @@ def test_version(request): except testprocess.ProcessExited: assert proc.proc.exitStatus() == QProcess.NormalExit else: - assert False + pytest.fail("Process did not exit!") output = bytes(proc.proc.readAllStandardOutput()).decode('utf-8')