summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--misc/qutebrowser.spec19
-rw-r--r--misc/requirements/requirements-pyinstaller.txt2
-rw-r--r--misc/requirements/requirements-pyinstaller.txt-raw2
-rw-r--r--qutebrowser/app.py9
-rw-r--r--qutebrowser/browser/qutescheme.py3
-rw-r--r--qutebrowser/extensions/loader.py28
-rw-r--r--qutebrowser/html/warning-sandboxing.html16
-rw-r--r--qutebrowser/utils/resources.py5
-rwxr-xr-xscripts/dev/build_release.py66
-rw-r--r--tests/unit/extensions/test_loader.py8
-rw-r--r--tox.ini2
11 files changed, 50 insertions, 110 deletions
diff --git a/misc/qutebrowser.spec b/misc/qutebrowser.spec
index 1eee9161d..ecb9da68e 100644
--- a/misc/qutebrowser.spec
+++ b/misc/qutebrowser.spec
@@ -64,17 +64,17 @@ INFO_PLIST_UPDATES = {
def get_data_files():
data_files = [
- ('../qutebrowser/html', 'html'),
- ('../qutebrowser/img', 'img'),
- ('../qutebrowser/icons', 'icons'),
- ('../qutebrowser/javascript', 'javascript'),
- ('../qutebrowser/html/doc', 'html/doc'),
- ('../qutebrowser/git-commit-id', '.'),
- ('../qutebrowser/config/configdata.yml', 'config'),
+ ('../qutebrowser/html', 'qutebrowser/html'),
+ ('../qutebrowser/img', 'qutebrowser/img'),
+ ('../qutebrowser/icons', 'qutebrowser/icons'),
+ ('../qutebrowser/javascript', 'qutebrowser/javascript'),
+ ('../qutebrowser/html/doc', 'qutebrowser/html/doc'),
+ ('../qutebrowser/git-commit-id', 'qutebrowser/git-commit-id'),
+ ('../qutebrowser/config/configdata.yml', 'qutebrowser/config'),
]
if os.path.exists(os.path.join('qutebrowser', '3rdparty', 'pdfjs')):
- data_files.append(('../qutebrowser/3rdparty/pdfjs', '3rdparty/pdfjs'))
+ data_files.append(('../qutebrowser/3rdparty/pdfjs', 'qutebrowser/3rdparty/pdfjs'))
else:
print("Warning: excluding pdfjs as it's not present!")
@@ -137,5 +137,4 @@ app = BUNDLE(coll,
name='qutebrowser.app',
icon=icon,
info_plist=INFO_PLIST_UPDATES,
- # https://github.com/pyinstaller/pyinstaller/blob/b78bfe530cdc2904f65ce098bdf2de08c9037abb/PyInstaller/hooks/hook-PyQt5.QtWebEngineWidgets.py#L24
- bundle_identifier='org.qt-project.Qt.QtWebEngineCore')
+ bundle_identifier='org.qutebrowser.qutebrowser')
diff --git a/misc/requirements/requirements-pyinstaller.txt b/misc/requirements/requirements-pyinstaller.txt
index 912b38cd3..b112963b0 100644
--- a/misc/requirements/requirements-pyinstaller.txt
+++ b/misc/requirements/requirements-pyinstaller.txt
@@ -1,5 +1,5 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
altgraph==0.17.3
-pyinstaller==5.13.0
+pyinstaller @ git+https://github.com/pyinstaller/pyinstaller.git@79f62ef29822169ae00cd4271390d0e3175476ad
pyinstaller-hooks-contrib==2023.6
diff --git a/misc/requirements/requirements-pyinstaller.txt-raw b/misc/requirements/requirements-pyinstaller.txt-raw
index c313980b0..7b4c8c84c 100644
--- a/misc/requirements/requirements-pyinstaller.txt-raw
+++ b/misc/requirements/requirements-pyinstaller.txt-raw
@@ -1 +1 @@
-PyInstaller
+pyinstaller @ git+https://github.com/pyinstaller/pyinstaller.git@79f62ef29822169ae00cd4271390d0e3175476ad
diff --git a/qutebrowser/app.py b/qutebrowser/app.py
index 94cc53c72..60eedeb1b 100644
--- a/qutebrowser/app.py
+++ b/qutebrowser/app.py
@@ -346,15 +346,6 @@ def _open_special_pages(args):
True,
'qute://warning/sessions'),
- ('sandboxing-warning-shown',
- (
- hasattr(sys, "frozen") and
- utils.is_mac and
- machinery.IS_QT6 and
- os.environ.get("QTWEBENGINE_DISABLE_SANDBOX") == "1"
- ),
- 'qute://warning/sandboxing'),
-
('qt5-warning-shown',
(
machinery.IS_QT5 and
diff --git a/qutebrowser/browser/qutescheme.py b/qutebrowser/browser/qutescheme.py
index dae862b8b..f325ff9e3 100644
--- a/qutebrowser/browser/qutescheme.py
+++ b/qutebrowser/browser/qutescheme.py
@@ -568,9 +568,6 @@ def qute_warning(url: QUrl) -> _HandlerRet:
title='Qt 5.15 sessions warning',
datadir=standarddir.data(),
sep=os.sep)
- elif path == '/sandboxing':
- src = jinja.render('warning-sandboxing.html',
- title='Qt 6 macOS sandboxing warning')
elif path == '/qt5':
is_venv = hasattr(sys, 'real_prefix') or sys.base_prefix != sys.prefix
src = jinja.render('warning-qt5.html',
diff --git a/qutebrowser/extensions/loader.py b/qutebrowser/extensions/loader.py
index b5b232c5a..7ccdabc88 100644
--- a/qutebrowser/extensions/loader.py
+++ b/qutebrowser/extensions/loader.py
@@ -6,11 +6,12 @@
import pkgutil
import types
+import sys
import pathlib
import importlib
import argparse
import dataclasses
-from typing import Callable, Iterator, List, Optional, Tuple
+from typing import Callable, Iterator, List, Optional, Set, Tuple
from qutebrowser.qt.core import pyqtSlot
@@ -79,6 +80,14 @@ def load_components(*, skip_hooks: bool = False) -> None:
def walk_components() -> Iterator[ExtensionInfo]:
"""Yield ExtensionInfo objects for all modules."""
+ if hasattr(sys, 'frozen'):
+ yield from _walk_pyinstaller()
+ else:
+ yield from _walk_normal()
+
+
+def _walk_normal() -> Iterator[ExtensionInfo]:
+ """Walk extensions when not using PyInstaller."""
for _finder, name, ispkg in pkgutil.walk_packages(
path=components.__path__,
prefix=components.__name__ + '.',
@@ -93,6 +102,23 @@ def walk_components() -> Iterator[ExtensionInfo]:
yield ExtensionInfo(name=name)
+def _walk_pyinstaller() -> Iterator[ExtensionInfo]:
+ """Walk extensions when using PyInstaller.
+
+ See https://github.com/pyinstaller/pyinstaller/issues/1905
+
+ Inspired by:
+ https://github.com/webcomics/dosage/blob/master/dosagelib/loader.py
+ """
+ toc: Set[str] = set()
+ for importer in pkgutil.iter_importers('qutebrowser'):
+ if hasattr(importer, 'toc'):
+ toc |= importer.toc
+ for name in toc:
+ if name.startswith(components.__name__ + '.'):
+ yield ExtensionInfo(name=name)
+
+
def _get_init_context() -> InitContext:
"""Get an InitContext object."""
return InitContext(data_dir=pathlib.Path(standarddir.data()),
diff --git a/qutebrowser/html/warning-sandboxing.html b/qutebrowser/html/warning-sandboxing.html
deleted file mode 100644
index 186d938e7..000000000
--- a/qutebrowser/html/warning-sandboxing.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{% extends "styled.html" %}
-
-{% block content %}
-<h1>{{ title }}</h1>
-<span class="note">Note this warning will only appear once. Use <span class="mono">:open
-qute://warning/sandboxing</span> to show it again at a later time.</span>
-
-<p>
- Due to a <a href="https://github.com/pyinstaller/pyinstaller/pull/6903">PyInstaller issue</a>,
- Chromium's <a href="https://chromium.googlesource.com/chromium/src/+/HEAD/docs/design/sandbox_faq.md">sandboxing</a>
- is currently disabled for macOS builds with Qt 6. This means that there will be no additional layer of protection
- in case of Chromium security bugs. Thus, it's advised to
- <b>not use this build in production</b>. Hopefully, this situation will be
- resolved before the final 3.0.0 release.
-</p>
-{% endblock %}
diff --git a/qutebrowser/utils/resources.py b/qutebrowser/utils/resources.py
index 494f01bff..60d90fd31 100644
--- a/qutebrowser/utils/resources.py
+++ b/qutebrowser/utils/resources.py
@@ -36,11 +36,6 @@ def _path(filename: str) -> _ResourceType:
assert not posixpath.isabs(filename), filename
assert os.path.pardir not in filename.split(posixpath.sep), filename
- if hasattr(sys, 'frozen'):
- # For PyInstaller, where we can't store resource files in a qutebrowser/ folder
- # because the executable is already named "qutebrowser" (at least on macOS).
- return pathlib.Path(sys.executable).parent / filename
-
return importlib_resources.files(qutebrowser) / filename
@contextlib.contextmanager
diff --git a/scripts/dev/build_release.py b/scripts/dev/build_release.py
index 73689ea88..4c443136f 100755
--- a/scripts/dev/build_release.py
+++ b/scripts/dev/build_release.py
@@ -171,9 +171,6 @@ def smoke_test(executable: pathlib.Path, debug: bool, qt5: bool) -> None:
r'[0-9:]* WARNING: Qt WebEngine resources not found at .*',
(r'[0-9:]* WARNING: Installed Qt WebEngine locales directory not found at '
r'location /qtwebengine_locales\. Trying application directory\.\.\.'),
-
- # https://github.com/pyinstaller/pyinstaller/pull/6903
- r"[0-9:]* INFO: Sandboxing disabled by user\.",
])
elif IS_WINDOWS:
stderr_whitelist.extend([
@@ -245,66 +242,11 @@ def verify_windows_exe(exe_path: pathlib.Path) -> None:
assert pe.verify_checksum()
-def patch_mac_app(qt5: bool) -> None:
- """Patch .app to save some space and make it signable."""
- dist_path = pathlib.Path('dist')
- ver = '5' if qt5 else '6'
- app_path = dist_path / 'qutebrowser.app'
-
- contents_path = app_path / 'Contents'
- macos_path = contents_path / 'MacOS'
- resources_path = contents_path / 'Resources'
- pyqt_path = macos_path / f'PyQt{ver}'
-
- # Replace some duplicate files by symlinks
- framework_path = pyqt_path / f'Qt{ver}' / 'lib' / 'QtWebEngineCore.framework'
-
- framework_resource_path = framework_path / 'Resources'
- for file_path in framework_resource_path.iterdir():
- target = pathlib.Path(*[os.pardir] * 5, file_path.name)
- if file_path.is_dir():
- shutil.rmtree(file_path)
- else:
- file_path.unlink()
- file_path.symlink_to(target)
-
- if not qt5:
- # Symlinking QtWebEngineCore.framework does not seem to work with Qt 6.
- # Also, the symlinking/moving before signing doesn't seem to be required.
- return
-
- core_lib = framework_path / 'Versions' / '5' / 'QtWebEngineCore'
- core_lib.unlink()
- core_target = pathlib.Path(*[os.pardir] * 7, 'MacOS', 'QtWebEngineCore')
- core_lib.symlink_to(core_target)
-
- # Move stuff around to make things signable on macOS
- # See https://github.com/pyinstaller/pyinstaller/issues/6612
- pyqt_path_dest = resources_path / pyqt_path.name
- shutil.move(pyqt_path, pyqt_path_dest)
- pyqt_path_target = pathlib.Path("..") / pyqt_path_dest.relative_to(contents_path)
- pyqt_path.symlink_to(pyqt_path_target)
-
- for path in macos_path.glob("Qt*"):
- link_path = resources_path / path.name
- target_path = pathlib.Path("..") / path.relative_to(contents_path)
- link_path.symlink_to(target_path)
-
-
-def sign_mac_app() -> None:
+def verify_mac_app() -> None:
"""Re-sign and verify the Mac .app."""
app_path = pathlib.Path('dist') / 'qutebrowser.app'
subprocess.run([
'codesign',
- '-s', '-',
- '--force',
- '--timestamp',
- '--deep',
- '--verbose',
- app_path,
- ], check=True)
- subprocess.run([
- 'codesign',
'--verify',
'--strict',
'--deep',
@@ -341,10 +283,8 @@ def build_mac(
utils.print_title("Building .app via pyinstaller")
call_tox(f'pyinstaller{"-qt5" if qt5 else ""}', '-r', debug=debug)
- utils.print_title("Patching .app")
- patch_mac_app(qt5=qt5)
- utils.print_title("Re-signing .app")
- sign_mac_app()
+ utils.print_title("Verifying .app")
+ verify_mac_app()
dist_path = pathlib.Path("dist")
diff --git a/tests/unit/extensions/test_loader.py b/tests/unit/extensions/test_loader.py
index a2a99f305..fd15130ba 100644
--- a/tests/unit/extensions/test_loader.py
+++ b/tests/unit/extensions/test_loader.py
@@ -20,10 +20,16 @@ def test_on_walk_error():
def test_walk_normal():
- names = [info.name for info in loader.walk_components()]
+ names = [info.name for info in loader._walk_normal()]
assert 'qutebrowser.components.scrollcommands' in names
+def test_walk_pyinstaller():
+ # We can't test whether we get something back without being frozen by
+ # PyInstaller, but at least we can test that we don't crash.
+ list(loader._walk_pyinstaller())
+
+
def test_load_component(monkeypatch):
monkeypatch.setattr(objects, 'commands', {})
diff --git a/tox.ini b/tox.ini
index 541effc2c..0014f261c 100644
--- a/tox.ini
+++ b/tox.ini
@@ -187,6 +187,7 @@ passenv =
APPDATA
HOME
PYINSTALLER_DEBUG
+ PYINSTALLER_COMPILE_BOOTLOADER
setenv =
qt5: PYINSTALLER_QT5=true
deps =
@@ -268,6 +269,7 @@ passenv = *
# Override default PyQt6 from [testenv]
setenv =
qt5: QUTE_QT_WRAPPER=PyQt5
+ PYINSTALLER_COMPILE_BOOTLOADER=true
usedevelop = true
deps =
-r{toxinidir}/requirements.txt