def test_parse_update_xml(monkeypatch, os_name, version, target, datafile): def _mock(self, url): with open(os.path.join(os.path.dirname(__file__), 'data', datafile), 'r') as f: self.update_xml_text = f.read() monkeypatch.setattr(QtArchives, "_download_update_xml", _mock) qt_archives = QtArchives(os_name, 'desktop', version, target, BASE_URL) assert qt_archives.archives is not None # Get packages with all extra modules qt_archives_all_modules = QtArchives(os_name, 'desktop', version, target, BASE_URL, None, ['all'], None, True) assert qt_archives_all_modules.archives is not None # Extract all urls url_list = [item.url for item in qt_archives.archives] url_all_modules_list = [item.url for item in qt_archives_all_modules.archives] # Check the difference list contains only extra modules urls for target specified list_diff = [item for item in url_all_modules_list if item not in url_list] unwanted_targets = [item for item in list_diff if target not in item] # Assert if list_diff contains urls without target specified assert unwanted_targets == []
def test_parse_update_xml(monkeypatch, os_name, version, arch, datafile): def _mock(self, url): return (Path(__file__).parent / "data" / datafile).read_text("utf-8") monkeypatch.setattr(QtArchives, "_download_update_xml", _mock) qt_archives = QtArchives(os_name, "desktop", version, arch, Settings.baseurl) assert qt_archives.archives is not None # Get packages with all extra modules qt_archives_all_modules = QtArchives( os_name, "desktop", version, arch, base="https://example.com/", modules=["all"], all_extra=True, ) assert qt_archives_all_modules.archives is not None # Extract all urls url_list = [item.archive_path for item in qt_archives.archives] url_all_modules_list = [ item.archive_path for item in qt_archives_all_modules.archives ] # Check the difference list contains only extra modules urls for target specified list_diff = [item for item in url_all_modules_list if item not in url_list] unwanted_targets = [item for item in list_diff if arch not in item] # Assert if list_diff contains urls without target specified assert unwanted_targets == []
def run_install(self, args): start_time = time.perf_counter() arch = args.arch target = args.target os_name = args.host qt_version = args.qt_version output_dir = args.outputdir arch = self._set_arch(args, arch, os_name, target, qt_version) modules = args.modules sevenzip = self._set_sevenzip(args) mirror = args.base self.show_aqt_version() if not self._check_mirror(mirror): self.parser.print_help() exit(1) if not self._check_qt_arg_versions(qt_version): self.logger.warning("Specified Qt version is unknown: {}.".format(qt_version)) if not self._check_qt_arg_combination(qt_version, os_name, target, arch): self.logger.warning("Specified target combination is not valid or unknown: {} {} {}".format(os_name, target, arch)) all_extra = True if modules is not None and 'all' in modules else False if not all_extra and not self._check_modules_arg(qt_version, modules): self.logger.warning("Some of specified modules are unknown.") QtInstaller(QtArchives(os_name, target, qt_version, arch, modules=modules, mirror=mirror, logging=self.logger, all_extra=all_extra), logging=self.logger, command=sevenzip, target_dir=output_dir).install() self.logger.info("Time elasped: {time:.8f} second".format(time=time.perf_counter() - start_time))
def run_install(self, args): arch = args.arch target = args.target os_name = args.host qt_version = args.qt_version output_dir = args.outputdir arch = self._set_arch(args, arch, os_name, target, qt_version) modules = args.modules sevenzip = self._set_sevenzip(args) mirror = args.base if not self._check_mirror(mirror): self.parser.print_help() exit(1) if not self._check_qt_arg_combination(qt_version, os_name, target, arch): self.logger.warning( "Specified target combination is not valid: {} {} {}".format( os_name, target, arch)) all_extra = True if modules is not None and 'all' in modules else False if not all_extra and not self._check_modules_arg(qt_version, modules): self.logger.warning("Some of specified modules are unknown.") QtInstaller(QtArchives(os_name, target, qt_version, arch, modules=modules, mirror=mirror, logging=self.logger, all_extra=all_extra), logging=self.logger).install(command=sevenzip, target_dir=output_dir) sys.stdout.write("\033[K") print("Finished installation")
def run_install(self, args): start_time = time.perf_counter() arch = args.arch target = args.target os_name = args.host qt_version = args.qt_version output_dir = args.outputdir if output_dir is None: base_dir = os.getcwd() else: base_dir = output_dir arch = self._set_arch(args, arch, os_name, target, qt_version) modules = args.modules sevenzip = self._set_sevenzip(args) mirror = args.base archives = args.archives self._run_common_part(output_dir, mirror) if not self._check_qt_arg_versions(qt_version): self.logger.warning( "Specified Qt version is unknown: {}.".format(qt_version)) if not self._check_qt_arg_combination(qt_version, os_name, target, arch): self.logger.warning( "Specified target combination is not valid or unknown: {} {} {}" .format(os_name, target, arch)) all_extra = True if modules is not None and 'all' in modules else False if not all_extra and not self._check_modules_arg(qt_version, modules): self.logger.warning("Some of specified modules are unknown.") try: qt_archives = QtArchives(os_name, target, qt_version, arch, subarchives=archives, modules=modules, mirror=mirror, logging=self.logger, all_extra=all_extra) except ArchiveDownloadError or ArchiveListError: exit(1) else: target_config = qt_archives.get_target_config() self.call_installer(qt_archives, output_dir, sevenzip) finisher(target_config, base_dir, self.logger) self.logger.info("Finished installation") self.logger.info("Time elasped: {time:.8f} second".format( time=time.perf_counter() - start_time))
def test_parse_update_xml(monkeypatch, os_name, version, target, datafile): def _mock(self, url): with open(os.path.join(os.path.dirname(__file__), 'data', datafile), 'r') as f: self.update_xml_text = f.read() monkeypatch.setattr(QtArchives, "_download_update_xml", _mock) qt_archives = QtArchives(os_name, 'desktop', version, target) assert qt_archives.archives is not None
def make_qt_archives(subarchives, modules, is_include_base) -> QtArchives: return QtArchives( "mac", "desktop", "5.14.0", "win32_mingw73", "www.example.com", subarchives, modules, "all" in modules, is_include_base, )
def run_install(self, args): arch = args.arch target = args.target os_name = args.host output_dir = args.outputdir mirror = args.base if arch is None: if os_name == "linux" and target == "desktop": arch = "gcc_64" elif os_name == "mac" and target == "desktop": arch = "clang_64" elif os_name == "mac" and target == "ios": arch = "ios" if arch == "": print("Please supply a target architecture.") args.print_help() exit(1) qt_version = args.qt_version if not self.check_arg_combination(qt_version, os_name, target, arch): print("Specified target combination is not valid: {} {} {}".format( os_name, target, arch)) exit(1) if mirror is not None: if not mirror.startswith('http://') or mirror.startswith( 'https://') or mirror.startswith('ftp://'): args.print_help() exit(1) if output_dir is not None: QtInstaller( QtArchives(os_name, qt_version, target, arch, mirror=mirror)).install(target_dir=output_dir) else: QtInstaller( QtArchives(os_name, qt_version, target, arch, mirror=mirror)).install() sys.stdout.write("\033[K") print("Finished installation")
def run_install(self, args): arch = args.arch target = args.target os_name = args.host output_dir = args.outputdir arch = self._set_arch(args, arch, os_name, target) modules = args.modules sevenzip = self._set_sevenzip(args) mirror = self._check_mirror(args) qt_version = args.qt_version if not self._check_qt_arg_combination(qt_version, os_name, target, arch): self.logger.error("Specified target combination is not valid: {} {} {}".format(os_name, target, arch)) exit(1) QtInstaller(QtArchives(os_name, target, qt_version, arch, modules=modules, mirror=mirror, logging=self.logger), logging=self.logger).install(command=sevenzip, target_dir=output_dir) sys.stdout.write("\033[K") print("Finished installation")
def test_qt_archives_modules(monkeypatch, arch, requested_module_names, has_nonexistent_modules: bool): def _mock(self, *args): return (Path(__file__).parent / "data" / "windows-5140-update.xml").read_text("utf-8") monkeypatch.setattr(QtArchives, "_download_update_xml", _mock) expect_json = json.loads((Path(__file__).parent / "data" / "windows-5140-expect.json").read_text("utf-8")) expected = expect_json["modules_metadata_by_arch"][arch] base_expected = expect_json["qt_base_pkgs_by_arch"][arch] os_name, target, base, version = "windows", "desktop", "https://example.com", Version( "5.14.0") qt_base = "QT-BASE" def locate_module_data(haystack: Iterable[Dict[str, str]], name: str) -> Dict[str, str]: if name == qt_base: return base_expected for mod_meta in haystack: if mod_meta["Name"] == f"qt.qt5.5140.{name}.{arch}": return mod_meta return {} def verify_qt_package_stride(pkgs: Iterable[QtPackage], expect: Dict[str, str]): # https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/qt5_5140/ # qt.qt5.5140.qtcharts.win32_mingw73/5.14.0-0-202108190846qtcharts-windows-win32_mingw73.7z url_begin = "online/qtsdkrepository/windows_x86/desktop/qt5_5140" expected_archive_url_pattern = re.compile( r"^" + re.escape(url_begin) + "/(" + expect["Name"] + ")/" + re.escape(expect["Version"]) + r"(.+\.7z)$") expected_7z_files = set(expect["DownloadableArchives"]) for pkg in pkgs: if not expect["Description"]: assert not pkg.package_desc else: assert pkg.package_desc == expect["Description"] url_match = expected_archive_url_pattern.match(pkg.archive_path) assert url_match mod_name, archive_name = url_match.groups() assert pkg.archive == archive_name assert archive_name in expected_7z_files expected_7z_files.remove(archive_name) assert len(expected_7z_files ) == 0, "Actual number of packages was fewer than expected" if has_nonexistent_modules: expect_help = [ f"Please use 'aqt list-qt {os_name} {target} --modules {version} <arch>' to show modules available." ] for unexpected_module in requested_module_names: with pytest.raises(NoPackageFound) as e: mod_names = ("qtcharts", unexpected_module) QtArchives(os_name, target, str(version), arch, base, modules=mod_names) assert e.type == NoPackageFound assert unexpected_module in str( e.value), "Message should include the missing module" assert e.value.suggested_action == expect_help return is_all_modules = "all" in requested_module_names qt_pkgs = QtArchives(os_name, target, str(version), arch, base, modules=requested_module_names, all_extra=is_all_modules).archives if is_all_modules: requested_module_names = [ module["Name"].split(".")[-2] for module in expected ] unvisited_modules = {*requested_module_names, qt_base} # This assumes that qt_pkgs are in a specific order for pkg_update_name, qt_packages in groupby(qt_pkgs, lambda x: x.pkg_update_name): match = re.match( r"^qt\.qt5\.5140(\.addons\.\w+|\.\w+|)\." + arch + r"$", pkg_update_name) assert match, f"QtArchive includes package named '{pkg_update_name}' with unexpected naming convention" mod_name = match.group(1) mod_name = mod_name[1:] if mod_name else qt_base assert mod_name in unvisited_modules unvisited_modules.remove(mod_name) expected_meta = locate_module_data(expected, mod_name) verify_qt_package_stride(qt_packages, expected_meta) assert len(unvisited_modules ) == 0, f"Failed to produce packages for {unvisited_modules}"
def run_install(self, args): """Run install subcommand""" start_time = time.perf_counter() arch = args.arch target = args.target os_name = args.host qt_version = args.qt_version output_dir = args.outputdir keep = args.keep if output_dir is None: base_dir = os.getcwd() else: base_dir = output_dir if args.timeout is not None: timeout = (args.timeout, args.timeout) else: timeout = (5, 5) arch = self._set_arch(args, arch, os_name, target, qt_version) modules = args.modules sevenzip = self._set_sevenzip(args.external) if EXT7Z and sevenzip is None: # override when py7zr is not exist sevenzip = self._set_sevenzip("7z") if args.base is not None: base = args.base + "/online/qtsdkrepository/" else: base = BASE_URL archives = args.archives if args.noarchives: if modules is None: print( "When specified option --no-archives, an option --modules is mandatory." ) exit(1) if archives is not None: print( "Option --archives and --no-archives are conflicted. Aborting..." ) exit(1) else: archives = modules else: if modules is not None and archives is not None: archives.append(modules) nopatch = args.noarchives or ( archives is not None and "qtbase" not in archives ) # type: bool self._run_common_part(output_dir, base) if not self._check_qt_arg_versions(qt_version): self.logger.warning( "Specified Qt version is unknown: {}.".format(qt_version) ) if not self._check_qt_arg_combination(qt_version, os_name, target, arch): self.logger.warning( "Specified target combination is not valid or unknown: {} {} {}".format( os_name, target, arch ) ) all_extra = True if modules is not None and "all" in modules else False if not all_extra and not self._check_modules_arg(qt_version, modules): self.logger.warning("Some of specified modules are unknown.") try: qt_archives = QtArchives( os_name, target, qt_version, arch, base, subarchives=archives, modules=modules, logging=self.logger, all_extra=all_extra, timeout=timeout, ) except ArchiveConnectionError: try: self.logger.warning( "Connection to the download site failed and fallback to mirror site." ) qt_archives = QtArchives( os_name, target, qt_version, arch, random.choice(FALLBACK_URLS), subarchives=archives, modules=modules, logging=self.logger, all_extra=all_extra, timeout=timeout, ) except Exception: self.logger.error("Connection to the download site failed. Aborted...") exit(1) except ArchiveDownloadError or ArchiveListError or NoPackageFound: exit(1) target_config = qt_archives.get_target_config() self.call_installer(qt_archives, output_dir, sevenzip, keep) if not nopatch: Updater.update(target_config, base_dir, self.logger) self.logger.info("Finished installation") self.logger.info( "Time elasped: {time:.8f} second".format( time=time.perf_counter() - start_time ) )
def run_install_qt(self, args): """Run install subcommand""" start_time = time.perf_counter() self.show_aqt_version() if args.is_legacy: self._warn_on_deprecated_command("install", "install-qt") target: str = args.target os_name: str = args.host arch: str = self._set_arch( args.arch, os_name, target, getattr(args, "qt_version", getattr(args, "qt_version_spec", None))) if hasattr(args, "qt_version_spec"): qt_version: str = str( Cli._determine_qt_version(args.qt_version_spec, os_name, target, arch)) else: qt_version: str = args.qt_version Cli._validate_version_str(qt_version) keep = args.keep output_dir = args.outputdir if output_dir is None: base_dir = os.getcwd() else: base_dir = output_dir if args.timeout is not None: timeout = (args.timeout, args.timeout) else: timeout = (Settings.connection_timeout, Settings.response_timeout) modules = args.modules sevenzip = self._set_sevenzip(args.external) if EXT7Z and sevenzip is None: # override when py7zr is not exist sevenzip = self._set_sevenzip("7z") if args.base is not None: if not self._check_mirror(args.base): raise CliInputError( "The `--base` option requires a url where the path `online/qtsdkrepository` exists.", should_show_help=True, ) base = args.base else: base = Settings.baseurl archives = args.archives if args.noarchives: if modules is None: raise CliInputError( "When `--noarchives` is set, the `--modules` option is mandatory." ) if archives is not None: raise CliInputError( "Options `--archives` and `--noarchives` are mutually exclusive." ) else: if modules is not None and archives is not None: archives.append(modules) nopatch = args.noarchives or ( archives is not None and "qtbase" not in archives) # type: bool if not self._check_qt_arg_versions(qt_version): self.logger.warning( "Specified Qt version is unknown: {}.".format(qt_version)) if not self._check_qt_arg_combination(qt_version, os_name, target, arch): self.logger.warning( "Specified target combination is not valid or unknown: {} {} {}" .format(os_name, target, arch)) all_extra = True if modules is not None and "all" in modules else False if not all_extra and not self._check_modules_arg(qt_version, modules): self.logger.warning("Some of specified modules are unknown.") qt_archives = self.retry_on_bad_connection( lambda base_url: QtArchives( os_name, target, qt_version, arch, base=base_url, subarchives=archives, modules=modules, all_extra=all_extra, is_include_base_package=not args.noarchives, timeout=timeout, ), base, ) target_config = qt_archives.get_target_config() run_installer(qt_archives.get_packages(), base_dir, sevenzip, keep) if not nopatch: Updater.update(target_config, base_dir) self.logger.info("Finished installation") self.logger.info("Time elapsed: {time:.8f} second".format( time=time.perf_counter() - start_time))