diff --git a/aqt/archives.py b/aqt/archives.py index 29c6b0d0..a50a072a 100644 --- a/aqt/archives.py +++ b/aqt/archives.py @@ -361,14 +361,38 @@ def _target_packages(self) -> ModuleToPackage: return target_packages def _get_archives(self): - if self.version >= Version("6.8.0"): - name = ( - f"qt{self.version.major}_{self._version_str()}" - f"/qt{self.version.major}_{self._version_str()}{self._arch_ext()}" - ) + if self.target == "desktop" and self.version >= Version("6.7.0") and self.arch in ("wasm_singlethread", "wasm_multithread"): + base_url = "online/qtsdkrepository/all_os/wasm" + if self.version >= Version("6.8.0"): + name = f"qt6_{self._version_str()}/qt6_{self._version_str()}_{self.arch}" + else: + name = f"qt6_{self._version_str()}_{self.arch}" + self.logger.debug(f"WASM path: {self.base}/{base_url}/{name}/Updates.xml") + os_target_folder = posixpath.join(base_url, name) else: - name = f"qt{self.version.major}_{self._version_str()}{self._arch_ext()}" - self._get_archives_base(name, self._target_packages()) + if self.version >= Version("6.8.0"): + name = ( + f"qt{self.version.major}_{self._version_str()}" + f"/qt{self.version.major}_{self._version_str()}{self._arch_ext()}" + ) + else: + name = f"qt{self.version.major}_{self._version_str()}{self._arch_ext()}" + + os_name = self.os_name + if self.target == "android" and self.version >= Version("6.7.0"): + os_name = "all_os" + + os_target_folder = posixpath.join( + "online/qtsdkrepository", + os_name + ("_x86" if os_name == "windows" else ( + "" if os_name in ("linux_arm64", "all_os", "windows_arm64") else "_x64")), + self.target, + name + ) + + update_xml_url = posixpath.join(os_target_folder, "Updates.xml") + update_xml_text = self._download_update_xml(update_xml_url) + self._parse_update_xml(os_target_folder, update_xml_text, self._target_packages()) def _append_depends_tool(self, arch, tool_name): os_target_folder = posixpath.join( diff --git a/aqt/metadata.py b/aqt/metadata.py index 4750537d..4d19271c 100644 --- a/aqt/metadata.py +++ b/aqt/metadata.py @@ -170,31 +170,67 @@ def flattened(self) -> List[Version]: def get_semantic_version(qt_ver: str, is_preview: bool) -> Optional[Version]: - """Converts a Qt version string (596, 512, 5132, etc) into a semantic version. - This makes a lot of assumptions based on established patterns: - If is_preview is True, the number is interpreted as ver[0].ver[1:], with no patch. - If the version is 3 digits, then major, minor, and patch each get 1 digit. - If the version is 4 or more digits, then major gets 1 digit, minor gets 2 digits - and patch gets all the rest. - As of May 2021, the version strings at https://download.qt.io/online/qtsdkrepository - conform to this pattern; they are not guaranteed to do so in the future. + """Converts a Qt version string into a semantic version. + Handles both traditional format (e.g. '51212' -> '5.12.12') and + new format with underscores (e.g. '6_7_3' -> '6.7.3'). + + Args: + qt_ver: Version string (e.g. '51212', '600', '6_7_3') + is_preview: Whether this is a preview version + + Returns: + Version object or None if invalid format + + Examples: + >>> get_semantic_version('51212', False) + Version('5.12.12') + >>> get_semantic_version('600', False) + Version('6.0.0') + >>> get_semantic_version('6_7_3', False) + Version('6.7.3') """ - if not qt_ver or any(not ch.isdigit() for ch in qt_ver): + if not qt_ver: + return None + + try: + # Handle versions with underscores (new format) + if '_' in qt_ver: + parts = qt_ver.split('_') + if len(parts) < 2 or len(parts) > 3: + return None + + major = int(parts[0]) + minor = int(parts[1]) + patch = int(parts[2]) if len(parts) == 3 else 0 + + version_str = f"{major}.{minor}.{patch}" + if is_preview: + version_str += ".dev0" + return Version(version_str) + + # Handle traditional format (continuous digits) + if any(not ch.isdigit() for ch in qt_ver): + return None + + # For traditional format, construct version parts first + if len(qt_ver) >= 4: + major, minor, patch = int(qt_ver[:1]), int(qt_ver[1:3]), int(qt_ver[3:]) + elif len(qt_ver) == 3: + major, minor, patch = int(qt_ver[:1]), int(qt_ver[1:2]), int(qt_ver[2:]) + elif len(qt_ver) == 2: + major, minor, patch = int(qt_ver[:1]), int(qt_ver[1:]), 0 + else: + return None + + # Then create the version string with appropriate preview suffix + version_str = f"{major}.{minor}.{patch}" + if is_preview: + version_str += ".dev0" + + return Version(version_str) + + except ValueError: return None - if is_preview: - return Version( - major=int(qt_ver[:1]), - minor=int(qt_ver[1:]), - patch=0, - prerelease=("preview",), - ) - elif len(qt_ver) >= 4: - return Version(major=int(qt_ver[:1]), minor=int(qt_ver[1:3]), patch=int(qt_ver[3:])) - elif len(qt_ver) == 3: - return Version(major=int(qt_ver[:1]), minor=int(qt_ver[1:2]), patch=int(qt_ver[2:])) - elif len(qt_ver) == 2: - return Version(major=int(qt_ver[:1]), minor=int(qt_ver[1:2]), patch=0) - raise ValueError("Invalid version string '{}'".format(qt_ver)) class ArchiveId: @@ -206,7 +242,7 @@ class ArchiveId: "mac": ["android", "desktop", "ios"], "linux": ["android", "desktop"], "linux_arm64": ["desktop"], - "all_os": ["qt"], + "all_os": ["qt", "wasm"], } EXTENSIONS_REQUIRED_ANDROID_QT6 = {"x86_64", "x86", "armv7", "arm64_v8a"} ALL_EXTENSIONS = {"", "wasm", "src_doc_examples", *EXTENSIONS_REQUIRED_ANDROID_QT6} @@ -232,6 +268,8 @@ def is_tools(self) -> bool: return self.category == "tools" def to_url(self) -> str: + if self.target == "desktop" and self.host in ("wasm_singlethread", "wasm_multithread"): + return "online/qtsdkrepository/all_os/wasm/" return "online/qtsdkrepository/{os}{arch}/{target}/".format( os=self.host, arch=( @@ -521,6 +559,8 @@ def contains_qmake_exe(arch_path: Path) -> bool: @staticmethod def is_in_wasm_range(host: str, version: Version) -> bool: + if version >= Version("6.7.0"): + return True return ( version in SimpleSpec(">=6.2.0,<6.5.0") or (host == "linux" and version in SimpleSpec(">=5.13,<6"))