Skip to content

Commit

Permalink
Refactoring Notifier as class
Browse files Browse the repository at this point in the history
Signed-off-by: Hiroshi Miura <[email protected]>
  • Loading branch information
miurahr committed Aug 17, 2022
1 parent 978bba7 commit 0a52212
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 114 deletions.
4 changes: 4 additions & 0 deletions aqt/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,7 @@ class UpdaterError(AqtException):

class OutOfMemory(AqtException):
pass


class QmakeNotFound(AqtException):
pass
3 changes: 2 additions & 1 deletion aqt/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
setup_logging,
)
from aqt.metadata import ArchiveId, MetadataFactory, QtRepoProperty, SimpleSpec, Version, show_list, suggested_follow_up
from aqt.updater import Updater
from aqt.updater import Notifier, Updater

try:
import py7zr
Expand Down Expand Up @@ -330,6 +330,7 @@ def run_install_qt(self, args):
run_installer(qt_archives.get_packages(), base_dir, sevenzip, keep, _archive_dest)
if not nopatch:
Updater.update(target_config, base_dir)
Notifier.notify_sdk(target_config, base_dir)
self.logger.info("Finished installation")
self.logger.info("Time elapsed: {time:.8f} second".format(time=time.perf_counter() - start_time))

Expand Down
243 changes: 130 additions & 113 deletions aqt/updater.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import patch

from aqt.archives import TargetConfig
from aqt.exceptions import UpdaterError
from aqt.exceptions import UpdaterError, QmakeNotFound
from aqt.helper import Settings
from aqt.metadata import SimpleSpec, Version

Expand All @@ -50,16 +50,61 @@ def dir_for_version(ver: Version) -> str:
return "5.9" if ver == Version("5.9.0") else f"{ver.major}.{ver.minor}.{ver.patch}"


def dir_for_arch(arch: str, os_name: str, version: Version) -> str:
if arch is None:
arch_dir = ""
elif arch.startswith("win64_mingw"):
arch_dir = arch[6:] + "_64"
elif arch.startswith("win32_mingw"):
arch_dir = arch[6:] + "_32"
elif arch.startswith("win"):
m = re.match(r"win\d{2}_(msvc\d{4})_(winrt_x\d{2})", arch)
if m:
a, b = m.groups()
arch_dir = b + "_" + a
else:
arch_dir = arch[6:]
elif os_name == "mac" and arch == "clang_64":
arch_dir = default_desktop_arch_dir(os_name, version)
else:
arch_dir = arch
return arch_dir


def unpatched_path(os_name: str, final_component: str) -> str:
return ("/home/qt/work/install" if os_name == "linux" else "/Users/qt/work/install") + "/" + final_component


class QtConfig:
"""
detect Qt configurations from qmake.
"""
def __init__(self, prefix: pathlib.Path):
self.qmake_path = None
self.qconfigs = {}
for qmake_path in [
prefix.joinpath("bin", "qmake"),
prefix.joinpath("bin", "qmake.exe"),
]:
if not qmake_path.exists():
continue
try:
result = subprocess.run([str(qmake_path), "-query"], stdout=subprocess.PIPE)
except (subprocess.SubprocessError, IOError, OSError):
raise QmakeNotFound()
if result.returncode == 0:
self.qmake_path = qmake_path
for line in result.stdout.splitlines():
vals = line.decode("UTF-8").split(":")
self.qconfigs[vals[0]] = vals[1]
return
raise QmakeNotFound()


class Updater:
def __init__(self, prefix: pathlib.Path, logger):
self.logger = logger
self.prefix = prefix
self.qmake_path = None
self.qconfigs = {}

def _patch_binfile(self, file: pathlib.Path, key: bytes, newpath: bytes):
"""Patch binary file with key/value"""
Expand Down Expand Up @@ -91,26 +136,6 @@ def _patch_textfile(self, file: pathlib.Path, old: str, new: str):
file.write_text(data, "UTF-8")
os.chmod(str(file), st.st_mode)

def _detect_qmake(self) -> bool:
"""detect Qt configurations from qmake."""
for qmake_path in [
self.prefix.joinpath("bin", "qmake"),
self.prefix.joinpath("bin", "qmake.exe"),
]:
if not qmake_path.exists():
continue
try:
result = subprocess.run([str(qmake_path), "-query"], stdout=subprocess.PIPE)
except (subprocess.SubprocessError, IOError, OSError):
return False
if result.returncode == 0:
self.qmake_path = qmake_path
for line in result.stdout.splitlines():
vals = line.decode("UTF-8").split(":")
self.qconfigs[vals[0]] = vals[1]
return True
return False

def patch_pkgconfig(self, oldvalue, os_name):
for pcfile in self.prefix.joinpath("lib", "pkgconfig").glob("*.pc"):
self.logger.info("Patching {}".format(pcfile))
Expand Down Expand Up @@ -163,23 +188,26 @@ def patch_libtool(self, oldvalue, os_name):

def patch_qmake(self):
"""Patch to qmake binary"""
if self._detect_qmake():
self.logger.info("Patching {}".format(str(self.qmake_path)))
try:
qmake_config = QtConfig(prefix=self.prefix)
self.logger.info("Patching {}".format(str(qmake_config.qmake_path)))
self._patch_binfile(
self.qmake_path,
qmake_config.qmake_path,
key=b"qt_prfxpath=",
newpath=bytes(str(self.prefix), "UTF-8"),
)
self._patch_binfile(
self.qmake_path,
qmake_config.qmake_path,
key=b"qt_epfxpath=",
newpath=bytes(str(self.prefix), "UTF-8"),
)
self._patch_binfile(
self.qmake_path,
qmake_config.qmake_path,
key=b"qt_hpfxpath=",
newpath=bytes(str(self.prefix), "UTF-8"),
)
except QmakeNotFound:
pass

def patch_qmake_script(self, base_dir, qt_version: str, os_name):
arch_dir = default_desktop_arch_dir(os_name, qt_version)
Expand Down Expand Up @@ -248,57 +276,6 @@ def patch_target_qt_conf(self, base_dir, qt_version, arch_dir, os_name):
self._patch_textfile(target_qt_conf, "HostPrefix=../../", new_hostprefix)
self._patch_textfile(target_qt_conf, "HostData=target", new_hostdata)

def notify_sdk(self, base_dir, qt_version, arch, os_name, toolchain, component_name):
if os_name == "windows":
sdktoolbinary = pathlib.Path(base_dir) / "Tools" / "QtCreator" / "bin" / "sdktool.exe"
else:
sdktoolbinary = pathlib.Path(base_dir) / "Tools" / "QtCreator" / "libexec" / "qtcreator" / "sdktool"
if not sdktoolbinary.exists():
return
# register Qt
if self._detect_qmake():
qmake_full_path = pathlib.Path(self.qmake_path).absolute()
command_args = [
sdktoolbinary,
"addQt",
"--id",
component_name,
"--name",
"Desktop Qt {} {}".format(qt_version, arch),
"--type",
"Qt4ProjectManager.QtVersion.Desktop",
"--qmake",
qmake_full_path,
]
try:
subprocess.run(command_args, stdout=subprocess.PIPE, check=True)
except subprocess.CalledProcessError as cpe:
msg = "\n".join(filter(None, [f"sdktool error: {cpe.returncode}", cpe.stdout, cpe.stderr]))
raise UpdaterError(msg) from cpe
# register SDK
kitname = component_name + "_kit"
command_args = [
sdktoolbinary,
"addKit",
"--id",
kitname,
"--name",
"Desktop Qt {} {}".format(qt_version, arch),
"--Ctoolchain",
toolchain,
"--Cxxtoolchain",
toolchain,
"--qt",
component_name,
"--devicetype",
"Desktop",
]
try:
subprocess.run(command_args, stdout=subprocess.PIPE, check=True)
except subprocess.CalledProcessError as cpe:
msg = "\n".join(filter(None, [f"sdktool error: {cpe.returncode}", cpe.stdout, cpe.stderr]))
raise UpdaterError(msg) from cpe

@classmethod
def update(cls, target: TargetConfig, base_dir: str):
"""
Expand All @@ -310,25 +287,9 @@ def update(cls, target: TargetConfig, base_dir: str):
version = Version(target.version)
os_name = target.os_name
version_dir = dir_for_version(version)
if arch is None:
arch_dir = ""
elif arch.startswith("win64_mingw"):
arch_dir = arch[6:] + "_64"
elif arch.startswith("win32_mingw"):
arch_dir = arch[6:] + "_32"
elif arch.startswith("win"):
m = re.match(r"win\d{2}_(msvc\d{4})_(winrt_x\d{2})", arch)
if m:
a, b = m.groups()
arch_dir = b + "_" + a
else:
arch_dir = arch[6:]
elif os_name == "mac" and arch == "clang_64":
arch_dir = default_desktop_arch_dir(os_name, version)
else:
arch_dir = arch
arch_dir = dir_for_arch(arch, os_name, version)
prefix = pathlib.Path(base_dir) / version_dir / arch_dir
try:
prefix = pathlib.Path(base_dir) / version_dir / arch_dir
updater = Updater(prefix, logger)
updater.set_license(base_dir, version_dir, arch_dir)
if target.arch not in [
Expand All @@ -345,25 +306,9 @@ def update(cls, target: TargetConfig, base_dir: str):
if target.os_name == "linux":
updater.patch_pkgconfig("/home/qt/work/install", target.os_name)
updater.patch_libtool("/home/qt/work/install/lib", target.os_name)
updater.notify_sdk(
base_dir,
version,
arch,
os_name,
"x86-linux-generic-elf-64bit",
"fix.me.component.name.should.unique", # FIXME
)
elif target.os_name == "mac":
updater.patch_pkgconfig("/Users/qt/work/install", target.os_name)
updater.patch_libtool("/Users/qt/work/install/lib", target.os_name)
updater.notify_sdk(
base_dir,
version,
arch,
os_name,
"x86-macos-generic-mach_o-64bit",
"fix.me.component.name.should.unique", # FIXME
)
elif target.os_name == "windows":
updater.make_qtenv2(base_dir, version_dir, arch_dir)
if version < Version("5.14.0"):
Expand All @@ -384,3 +329,75 @@ def patch_kde(cls, src_dir):
logger.info("Apply patch: " + p)
patchfile = patch.fromurl(PATCH_URL_BASE + p)
patchfile.apply(strip=True, root=os.path.join(src_dir, "qtbase"))


class Notifier:
@staticmethod
def notify_sdk(target, base_dir):
arch = target.arch
version = Version(target.version)
os_name = target.os_name
version_dir = dir_for_version(version)
arch_dir = dir_for_arch(arch, os_name, version)
prefix = pathlib.Path(base_dir) / version_dir / arch_dir
if os_name == "windows":
sdktoolbinary = pathlib.Path(base_dir) / "Tools" / "QtCreator" / "bin" / "sdktool.exe"
toolchain = "x86-windows-generic-64bit"
component_name = "fix.me.component.name.should.unique" # FIXME
elif os_name == "mac":
sdktoolbinary = pathlib.Path(base_dir) / "Tools" / "QtCreator" / "libexec" / "qtcreator" / "sdktool"
toolchain = "x86-macos-generic-mach_o-64bit"
component_name = "fix.me.component.name.should.unique" # FIXME
else:
sdktoolbinary = pathlib.Path(base_dir) / "Tools" / "QtCreator" / "libexec" / "qtcreator" / "sdktool"
toolchain = "x86-linux-generic-elf-64bit"
component_name = "fix.me.component.name.should.unique" # FIXME
if not sdktoolbinary.exists():
return
try:
qmake_config = QtConfig(prefix)
except QmakeNotFound:
# give up notifying
return
# register Qt
qmake_full_path = qmake_config.qmake_path.absolute()
command_args = [
sdktoolbinary,
"addQt",
"--id",
component_name,
"--name",
"Desktop Qt {} {}".format(version, arch),
"--type",
"Qt4ProjectManager.QtVersion.Desktop",
"--qmake",
qmake_full_path,
]
try:
subprocess.run(command_args, stdout=subprocess.PIPE, check=True)
except subprocess.CalledProcessError as cpe:
msg = "\n".join(filter(None, [f"sdktool error: {cpe.returncode}", cpe.stdout, cpe.stderr]))
raise UpdaterError(msg) from cpe
# register SDK
kitname = component_name + "_kit"
command_args = [
sdktoolbinary,
"addKit",
"--id",
kitname,
"--name",
"Desktop Qt {} {}".format(version, arch),
"--Ctoolchain",
toolchain,
"--Cxxtoolchain",
toolchain,
"--qt",
component_name,
"--devicetype",
"Desktop",
]
try:
subprocess.run(command_args, stdout=subprocess.PIPE, check=True)
except subprocess.CalledProcessError as cpe:
msg = "\n".join(filter(None, [f"sdktool error: {cpe.returncode}", cpe.stdout, cpe.stderr]))
raise UpdaterError(msg) from cpe

0 comments on commit 0a52212

Please sign in to comment.