Repository: miurahr/aqtinstall
Pull request #507 (2022-03-27 03:30:24)

Support pyproject.toml:project section

Signed-off-by: Hiroshi Miura <miurahr@linux.com>

miurahr: @nikitalita When adding [project] section in `pyproject.toml' execution of standalone binary failed. Could you investigate it? 

nikitalita: It looks like it doesn’t like 
```

 [project.scripts]
 aqt = "aqt.__main___:main"

````
This has to point to the actual Mai no function, I think? 
miurahr: > It looks like it doesn’t like
> 
> ```
> 
>  [project.scripts]
>  aqt = "aqt.__main___:main"
> ```
> 
> This has to point to the actual main function, I think?

Thank you for the suggestion.
I'd like to add config as same as one in setup.cfg;

```
[options.entry_points]
console_scripts =
    aqt = aqt.__main__:main
```
I saw https://peps.python.org/pep-0621/#entry-points 


Patch:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 46acd92..c025026 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -9,6 +9,11 @@ All notable changes to this project will be documented in this file.
 
 Changed
 -------
+* Change security policy:
+  Supported 2.0.x
+  Unsupported 1.2.x and before
+* Bump py7zr@0.18.3(#509)
+* setuptools_scm configuraiton on pyproject.toml(#508)
 * Use SHA256 hash from trusted mirror for integrity check (#493)
 * Check Update.xml file with SHA256 hash (#493)
 * Update combinations.xml
@@ -19,6 +24,7 @@ Changed
 
 Fixed
 -----
+* Fix patching of Qt6.2.2-ios(#510, #503)
 * Test: Conditionally install dependencies on Ubuntu (#494)
 
 Added
diff --git a/README.rst b/README.rst
index 7533301..c7283ae 100644
--- a/README.rst
+++ b/README.rst
@@ -60,7 +60,8 @@ Requirements
     py7zr
     texttable
     bs4
-    dataclasses
+    dataclasses; python_version < "3.7"
+    defusedxml
 
 - Operating Systems:
     Linux, macOS, MS Windows
diff --git a/aqt/updater.py b/aqt/updater.py
index 2392022..86f78b9 100644
--- a/aqt/updater.py
+++ b/aqt/updater.py
@@ -24,6 +24,7 @@ import pathlib
 import re
 import subprocess
 from logging import getLogger
+from typing import Union
 
 import patch
 
@@ -33,6 +34,26 @@ from aqt.helper import Settings
 from aqt.metadata import SimpleSpec, Version
 
 
+def default_desktop_arch_dir(host: str, version: Union[Version, str]) -> str:
+    version: Version = version if isinstance(version, Version) else Version(version)
+    if host == "linux":
+        return "gcc_64"
+    elif host == "mac":
+        return "macos" if version in SimpleSpec(">=6.1.2") else "clang_64"
+    else:  # Windows
+        # This is a temporary solution. This arch directory cannot exist for many versions of Qt.
+        # TODO: determine this dynamically
+        return "mingw81_64"
+
+
+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 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 Updater:
     def __init__(self, prefix: pathlib.Path, logger):
         self.logger = logger
@@ -160,30 +181,14 @@ class Updater:
                 newpath=bytes(str(self.prefix), "UTF-8"),
             )
 
-    def patch_qmake_script(self, base_dir, qt_version, os_name):
-        if os_name == "linux":
-            self.logger.info("Patching {}/bin/qmake".format(self.prefix))
-            self._patch_textfile(
-                self.prefix / "bin" / "qmake",
-                "/home/qt/work/install/bin",
-                "{}/{}/{}/bin".format(base_dir, qt_version, "gcc_64"),
-            )
-        elif os_name == "mac":
-            self.logger.info("Patching {}/bin/qmake".format(self.prefix))
-            self._patch_textfile(
-                self.prefix / "bin" / "qmake",
-                "/Users/qt/work/install/bin",
-                "{}/{}/{}/bin".format(base_dir, qt_version, "clang_64"),
-            )
-        elif os_name == "windows":
-            self.logger.info("Patching {}/bin/qmake.bat".format(self.prefix))
-            self._patch_textfile(
-                self.prefix / "bin" / "qmake.bat",
-                "/Users/qt/work/install/bin",
-                "{}\\{}\\{}\\bin".format(base_dir, qt_version, "mingw81_64"),
-            )
-        else:
-            pass
+    def patch_qmake_script(self, base_dir, qt_version: str, os_name):
+        arch_dir = default_desktop_arch_dir(os_name, qt_version)
+        sep = "\\" if os_name == "windows" else "/"
+        patched = sep.join([base_dir, qt_version, arch_dir, "bin"])
+        unpatched = unpatched_path(os_name, "bin")
+        qmake_path = self.prefix / "bin" / ("qmake.bat" if os_name == "windows" else "qmake")
+        self.logger.info(f"Patching {qmake_path}")
+        self._patch_textfile(qmake_path, unpatched, patched)
 
     def patch_qtcore(self, target):
         """patch to QtCore"""
@@ -235,15 +240,8 @@ class Updater:
 
     def patch_target_qt_conf(self, base_dir, qt_version, arch_dir, os_name):
         target_qt_conf = self.prefix / "bin" / "target_qt.conf"
-        if os_name == "linux":
-            old_targetprefix = "Prefix=/home/qt/work/install/target"
-            new_hostprefix = "HostPrefix=../../gcc_64"
-        elif os_name == "mac":
-            old_targetprefix = "Prefix=/Users/qt/work/install/target"
-            new_hostprefix = "HostPrefix=../../clang_64"
-        else:
-            old_targetprefix = "Prefix=/Users/qt/work/install/target"
-            new_hostprefix = "HostPrefix=../../mingw81_64"
+        old_targetprefix = f'Prefix={unpatched_path(os_name, "target")}'
+        new_hostprefix = f"HostPrefix=../../{default_desktop_arch_dir(os_name, qt_version)}"
         new_targetprefix = "Prefix={}".format(str(pathlib.Path(base_dir).joinpath(qt_version, arch_dir, "target")))
         new_hostdata = "HostData=../{}".format(arch_dir)
         self._patch_textfile(target_qt_conf, old_targetprefix, new_targetprefix)
@@ -260,7 +258,7 @@ class Updater:
         arch = target.arch
         version = Version(target.version)
         os_name = target.os_name
-        version_dir = "5.9" if version == Version("5.9.0") else target.version
+        version_dir = dir_for_version(version)
         if arch is None:
             arch_dir = ""
         elif arch.startswith("win64_mingw"):
@@ -274,8 +272,8 @@ class Updater:
                 arch_dir = b + "_" + a
             else:
                 arch_dir = arch[6:]
-        elif version in SimpleSpec(">=6.1.2") and os_name == "mac" and arch == "clang_64":
-            arch_dir = "macos"
+        elif os_name == "mac" and arch == "clang_64":
+            arch_dir = default_desktop_arch_dir(os_name, version)
         else:
             arch_dir = arch
         try:
diff --git a/ci/build_standalone.bat b/ci/build_standalone.bat
index b678f01..9a3564d 100644
--- a/ci/build_standalone.bat
+++ b/ci/build_standalone.bat
@@ -1,3 +1,4 @@
+pip install -U pip
 pip install virtualenv
 virtualenv build_venv
 call build_venv\Scripts\activate.bat
diff --git a/ci/generate_azure_pipelines_matrices.py b/ci/generate_azure_pipelines_matrices.py
index ce7879b..b6bd545 100644
--- a/ci/generate_azure_pipelines_matrices.py
+++ b/ci/generate_azure_pipelines_matrices.py
@@ -269,6 +269,7 @@ mac_build_jobs.append(
 mac_build_jobs.extend(
     [
         BuildJob("install-qt", "5.15.2", "mac", "ios", "ios", "ios"),
+        BuildJob("install-qt", "6.2.2", "mac", "ios", "ios", "ios", module="qtsensors"),
         BuildJob(
             "install-qt", "6.1.0", "mac", "android", "android_armv7", "android_armv7"
         ),
diff --git a/ci/steps.yml b/ci/steps.yml
index 8eb16d0..aaa0d58 100644
--- a/ci/steps.yml
+++ b/ci/steps.yml
@@ -54,7 +54,8 @@ steps:
           if [[ "$(HOST)" == "windows" ]]; then
             python -m aqt install-qt $(HOST) desktop $(QT_VERSION) mingw81_64 --archives qtbase
           else
-            python -m aqt install-qt $(HOST) desktop $(QT_VERSION) --archives qtbase
+            # qtdeclarative contains `qmlimportscanner`: necessary for ios builds, Qt6+
+            python -m aqt install-qt $(HOST) desktop $(QT_VERSION) --archives qtbase qtdeclarative
           fi
         fi
         if [[ "$(OUTPUT_DIR)" != "" ]]; then
@@ -174,6 +175,21 @@ steps:
     condition: and(eq(variables['TARGET'], 'android'), or(eq(variables['Agent.OS'], 'Linux'), eq(variables['Agent.OS'], 'Darwin')), ne(variables['SUBCOMMAND'], 'list'), ne(variables['SUBCOMMAND'], 'install-tool'))
     displayName: Build accelbubble example application to test for android
 
+  ##----------------------------------------------------
+  # for iOS target
+  - bash: |
+      set -ex
+      mkdir $(Build.BinariesDirectory)/tests
+      (cd $(Build.BinariesDirectory)/tests; 7zr x $(Build.SourcesDirectory)/ci/accelbubble.7z)
+      export PATH=$(QT_BINDIR):$PATH
+      qmake $(Build.BinariesDirectory)/tests/accelbubble
+      make
+    condition: |
+        and(eq(variables['TARGET'], 'ios'), 
+            ne(variables['SUBCOMMAND'], 'list'), 
+            ne(variables['SUBCOMMAND'], 'install-tool'))
+    displayName: Build accelbubble example application to test for ios
+
   ##----------------------------------------------------
   # Cache Powershell Modules in $MODULES_FOLDER
   - task: Cache@2
diff --git a/pyproject.toml b/pyproject.toml
index 3012bb8..4f99591 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,3 +1,81 @@
+[project]
+name = "aqtinstall"
+description = "Another unofficial Qt installer"
+readme = "README.rst"
+license = {file = "LICENSE"}
+authors = [
+    {name = "Hiroshi Miura", email = "miurahr@linux.com"},
+]
+classifiers = [
+    "Development Status :: 4 - Beta",
+    "Environment :: Console",
+    "Environment :: X11 Applications :: Qt",
+    "Intended Audience :: Developers",
+    "License :: OSI Approved :: MIT License",
+    "Operating System :: MacOS :: MacOS X",
+    "Operating System :: Microsoft :: Windows",
+    "Operating System :: POSIX",
+    "Operating System :: POSIX :: Linux",
+    "Programming Language :: Python",
+    "Programming Language :: C++",
+    "Topic :: Software Development",
+    "Topic :: Software Development :: Libraries",
+]
+requires-python = ">=3.6"
+dependencies = [
+    "requests",
+    "semantic_version",
+    "patch>=1.16",
+    "py7zr>=0.18.3",
+    "texttable",
+    "bs4",
+    "dataclasses;python_version<'3.7'",
+    "defusedxml",
+]
+dynamic = ["version"]
+
+[project.scripts]
+aqt = "aqt.__main__:main"
+
+[project.optional-dependencies]
+test = [
+    "pytest>=6.0",
+    "pytest-pep8",
+    "pytest-remotedata",
+    "pytest-cov",
+    "pytest-socket",
+    "pytest-leaks",
+    "pympler",
+]
+check = [
+    "flake8",
+    "flake8-black",
+    "flake8-colors",
+    "flake8-isort",
+    "flake8-pyi",
+    "flake8-typing-imports",
+    "docutils",
+    "check-manifest",
+    "readme-renderer",
+    "pygments",
+    "packaging",
+]
+docs = [
+    "sphinx>=2.3",
+    "sphinx_rtd_theme",
+    "sphinx-py3doc-enhanced-theme",
+]
+
+[project.urls]
+Documentation = "https://aqtinstall.readthedocs.io/"
+Bug_Tracker = "https://github.com/miurahr/aqtinstall/issues"
+Wiki = "https://github.com/miurahr/aqtinstall/wiki"
+Source = "https://github.com/miurahr/aqtinstall"
+Changelog = "https://github.com/miurahr/aqtinstall/blob/master/CHANGELOG.rst"
+
+[tool.poetry]
+include = ["*.yml", "*.json", "*.ini"]
+
 [build-system]
 requires = ["setuptools>=61", "wheel", "setuptools_scm[toml]>=6.4"]
 build-backend = "setuptools.build_meta"
diff --git a/setup.cfg b/setup.cfg
index 330858d..b730654 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -81,6 +81,6 @@ check =
     pygments
     packaging
 docs =
-    sphinx>=1.8
+    sphinx>=2.3
     sphinx_rtd_theme
     sphinx-py3doc-enhanced-theme


Test patch:
diff --git a/tests/test_install.py b/tests/test_install.py
index a1abb93..64478f2 100644
--- a/tests/test_install.py
+++ b/tests/test_install.py
@@ -574,7 +574,117 @@ def tool_archive(host: str, tool_name: str, variant: str, date: datetime = datet
                 r"^aqtinstall\(aqt\) v.* on Python 3.*\n"
                 r"Downloading qtbase...\n"
                 r"Finished installation of qtbase-windows-android_armv7.7z in .*\n"
-                r"Patching .*/bin/qmake.bat\n"
+                r"Patching .*6\.1\.0[/\\]android_armv7[/\\]bin[/\\]qmake.bat\n"
+                r"Finished installation\n"
+                r"Time elapsed: .* second"
+            ),
+        ),
+        (
+            "install-qt linux android 6.3.0 android_arm64_v8a".split(),
+            "linux",
+            "android",
+            "6.3.0",
+            "android_arm64_v8a",
+            "android_arm64_v8a",
+            "linux_x64/android/qt6_630_arm64_v8a/Updates.xml",
+            [
+                MockArchive(
+                    filename_7z="qtbase-linux-android_arm64_v8a.7z",
+                    update_xml_name="qt.qt6.630.android_arm64_v8a",
+                    contents=(
+                        # Qt 6 non-desktop should patch qconfig.pri, qmake script and target_qt.conf
+                        PatchedFile(
+                            filename="mkspecs/qconfig.pri",
+                            unpatched_content="... blah blah blah ...\n"
+                            "QT_EDITION = Not OpenSource\n"
+                            "QT_LICHECK = Not Empty\n"
+                            "... blah blah blah ...\n",
+                            patched_content="... blah blah blah ...\n"
+                            "QT_EDITION = OpenSource\n"
+                            "QT_LICHECK =\n"
+                            "... blah blah blah ...\n",
+                        ),
+                        PatchedFile(
+                            filename="bin/target_qt.conf",
+                            unpatched_content="Prefix=/home/qt/work/install/target\n"
+                            "HostPrefix=../../\n"
+                            "HostData=target\n",
+                            patched_content="Prefix={base_dir}{sep}6.3.0{sep}android_arm64_v8a{sep}target\n"
+                            "HostPrefix=../../gcc_64\n"
+                            "HostData=../android_arm64_v8a\n",
+                        ),
+                        PatchedFile(
+                            filename="bin/qmake",
+                            unpatched_content="... blah blah blah ...\n"
+                            "/home/qt/work/install/bin\n"
+                            "... blah blah blah ...\n",
+                            patched_content="... blah blah blah ...\n"
+                            "{base_dir}/6.3.0/gcc_64/bin\n"
+                            "... blah blah blah ...\n",
+                        ),
+                    ),
+                ),
+            ],
+            re.compile(
+                r"^aqtinstall\(aqt\) v.* on Python 3.*\n"
+                r"Downloading qtbase...\n"
+                r"Finished installation of qtbase-linux-android_arm64_v8a.7z in .*\n"
+                r"Patching .*6\.3\.0[/\\]android_arm64_v8a[/\\]bin[/\\]qmake\n"
+                r"Finished installation\n"
+                r"Time elapsed: .* second"
+            ),
+        ),
+        (
+            "install-qt mac ios 6.1.2".split(),
+            "mac",
+            "ios",
+            "6.1.2",
+            "ios",
+            "ios",
+            "mac_x64/ios/qt6_612/Updates.xml",
+            [
+                MockArchive(
+                    filename_7z="qtbase-mac-ios.7z",
+                    update_xml_name="qt.qt6.612.ios",
+                    contents=(
+                        # Qt 6 non-desktop should patch qconfig.pri, qmake script and target_qt.conf
+                        PatchedFile(
+                            filename="mkspecs/qconfig.pri",
+                            unpatched_content="... blah blah blah ...\n"
+                            "QT_EDITION = Not OpenSource\n"
+                            "QT_LICHECK = Not Empty\n"
+                            "... blah blah blah ...\n",
+                            patched_content="... blah blah blah ...\n"
+                            "QT_EDITION = OpenSource\n"
+                            "QT_LICHECK =\n"
+                            "... blah blah blah ...\n",
+                        ),
+                        PatchedFile(
+                            filename="bin/target_qt.conf",
+                            unpatched_content="Prefix=/Users/qt/work/install/target\n"
+                            "HostPrefix=../../\n"
+                            "HostData=target\n",
+                            patched_content="Prefix={base_dir}{sep}6.1.2{sep}ios{sep}target\n"
+                            "HostPrefix=../../macos\n"
+                            "HostData=../ios\n",
+                        ),
+                        PatchedFile(
+                            filename="bin/qmake",
+                            unpatched_content="... blah blah blah ...\n"
+                            "/Users/qt/work/install/bin\n"
+                            "... blah blah blah ...\n",
+                            patched_content="... blah blah blah ...\n"
+                            "{base_dir}/6.1.2/macos/bin\n"
+                            "... blah blah blah ...\n",
+                        ),
+                    ),
+                ),
+            ],
+            re.compile(
+                r"^aqtinstall\(aqt\) v.* on Python 3.*\n"
+                r"Downloading qtbase...\n"
+                r"Finished installation of qtbase-mac-ios.7z in .*\n"
+                r"Patching .*6\.1\.2[/\\]ios[/\\]bin[/\\]qmake\n"
                 r"Finished installation\n"
                 r"Time elapsed: .* second"
             ),