Merge pull request #898 from jdpurcell/pr-macos-official
Some checks are pending
Check tox tests / Check packaging 📦 (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
Publish Python 🐍 distributions 📦 to PyPI / publish Python 🐍 distributions 📦 to PyPI (push) Blocked by required conditions
Publish Python 🐍 distributions 📦 to PyPI / Build package (push) Waiting to run
Test on GH actions environment / test (binary, windows-latest, 3.12, 6.6.3) (push) Waiting to run
Test on GH actions environment / test (standard, ubuntu-latest, 3.12, 6.5.3) (push) Waiting to run
Test on GH actions environment / test (standard, ubuntu-latest, 3.12, 6.6.3) (push) Waiting to run
Test on GH actions environment / test (standard, ubuntu-latest, 3.12, 6.8.0) (push) Waiting to run
Test on GH actions environment / test (standard, ubuntu-latest, 3.12, 6.8.1) (push) Waiting to run
Test on GH actions environment / test (standard, windows-latest, 3.12, 6.5.3) (push) Waiting to run
Test on GH actions environment / test (standard, windows-latest, 3.12, 6.6.3) (push) Waiting to run
Test on GH actions environment / test (standard, windows-latest, 3.12, 6.7.3) (push) Waiting to run

Fix official installer on macOS
This commit is contained in:
Hiroshi Miura
2025-03-11 23:48:48 +09:00
committed by GitHub
4 changed files with 36 additions and 15 deletions

View File

@@ -35,6 +35,7 @@ from aqt.helper import (
get_os_name,
get_qt_account_path,
get_qt_installer_name,
prepare_installer,
safely_run,
safely_run_save_output,
)
@@ -340,7 +341,8 @@ class CommercialInstaller:
self.logger.info(f"Downloading Qt installer to {installer_path}")
timeout = (Settings.connection_timeout, Settings.response_timeout)
download_installer(self.base_url, self._installer_filename, self.os_name, installer_path, timeout)
download_installer(self.base_url, self._installer_filename, installer_path, timeout)
installer_path = prepare_installer(installer_path, self.os_name)
try:
if self.override:

View File

@@ -27,6 +27,7 @@ import secrets
import shutil
import subprocess
import sys
import uuid
from configparser import ConfigParser
from logging import Handler, getLogger
from logging.handlers import QueueListener
@@ -78,7 +79,7 @@ def get_qt_account_path() -> Path:
def get_qt_installer_name() -> str:
installer_dict = {
"windows": "qt-unified-windows-x64-online.exe",
"mac": "qt-unified-macOS-x64-online.dmg",
"mac": "qt-unified-mac-x64-online.dmg",
"linux": "qt-unified-linux-x64-online.run",
}
return installer_dict[get_os_name()]
@@ -669,15 +670,37 @@ def extract_auth(args: List[str]) -> Tuple[str | None, str | None, List[str] | N
return username, password, args
def download_installer(
base_url: str, installer_filename: str, os_name: str, target_path: Path, timeout: Tuple[float, float]
) -> None:
def download_installer(base_url: str, installer_filename: str, target_path: Path, timeout: Tuple[float, float]) -> None:
base_path = f"official_releases/online_installers/{installer_filename}"
url = f"{base_url}/{base_path}"
try:
hash = get_hash(base_path, Settings.hash_algorithm, timeout)
downloadBinaryFile(url, target_path, Settings.hash_algorithm, hash, timeout=timeout)
if os_name != "windows":
os.chmod(target_path, 0o500)
except Exception as e:
raise RuntimeError(f"Failed to download installer: {e}")
def prepare_installer(installer_path: Path, os_name: str) -> Path:
"""
Prepares the installer for execution. This may involve setting the correct permissions or
extracting the installer if it's packaged. Returns the path to the installer executable.
"""
if os_name == "linux":
os.chmod(installer_path, 0o500)
return installer_path
elif os_name == "mac":
volume_path = Path(f"/Volumes/{str(uuid.uuid4())}")
subprocess.run(
["hdiutil", "attach", str(installer_path), "-mountpoint", str(volume_path)],
stdout=subprocess.DEVNULL,
check=True,
)
try:
src_app_name = next(volume_path.glob("*.app")).name
dst_app_path = installer_path.with_suffix(".app")
shutil.copytree(volume_path / src_app_name, dst_app_path)
finally:
subprocess.run(["hdiutil", "detach", str(volume_path), "-force"], stdout=subprocess.DEVNULL, check=True)
return dst_app_path / "Contents" / "MacOS" / Path(src_app_name).stem
else:
return installer_path

View File

@@ -65,6 +65,7 @@ from aqt.helper import (
get_hash,
get_os_name,
get_qt_installer_name,
prepare_installer,
retry_on_bad_connection,
retry_on_errors,
safely_run_save_output,
@@ -905,7 +906,8 @@ class Cli:
# Download installer
self.logger.info(f"Downloading Qt installer to {installer_path}")
timeout = (Settings.connection_timeout, Settings.response_timeout)
download_installer(Settings.baseurl, installer_filename, get_os_name(), installer_path, timeout)
download_installer(Settings.baseurl, installer_filename, installer_path, timeout)
installer_path = prepare_installer(installer_path, get_os_name())
# Build command
cmd = [str(installer_path), "--accept-licenses", "--accept-obligations", "--confirm-command"]

View File

@@ -221,13 +221,7 @@ def test_commercial_installer_download_sha256(tmp_path, monkeypatch, commercial_
target_path = tmp_path / "qt-installer"
timeout = (Settings.connection_timeout, Settings.response_timeout)
download_installer(
commercial_installer.base_url,
commercial_installer._installer_filename,
commercial_installer.os_name,
target_path,
timeout,
)
download_installer(commercial_installer.base_url, commercial_installer._installer_filename,target_path, timeout)
assert target_path.exists()