From e7d89e470fff40adb94ab310c035c5c58f9efa10 Mon Sep 17 00:00:00 2001 From: renbin Date: Tue, 21 Nov 2023 16:18:20 +0800 Subject: [PATCH] fix: Optimize virtual pkg install strategy. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 优化虚包安装策略,旧版软件包仅处理首个匹配的 虚包,不会遍历其它虚包,可能不满足最优策略。 之前几笔修复调整了在或包依赖时虚包的处理, 现在增加对单独依赖虚包的处理,允许查找后续 虚包实现包以取得影响最小的依赖关系。 Log: 优化虚包安装策略 Bug: https://pms.uniontech.com/bug-view-229757.html Influence: VirtualPackage --- src/deb-installer/manager/packagesmanager.cpp | 86 ++++++++++++++----- 1 file changed, 63 insertions(+), 23 deletions(-) diff --git a/src/deb-installer/manager/packagesmanager.cpp b/src/deb-installer/manager/packagesmanager.cpp index adb9a4fc..c7b67e08 100644 --- a/src/deb-installer/manager/packagesmanager.cpp +++ b/src/deb-installer/manager/packagesmanager.cpp @@ -869,6 +869,28 @@ void PackagesManager::getPackageOrDepends(const QString &package, const QString } }; + auto checkVirtualPackage = [this](QVector &dependStatus, const QString &depend){ + QVector virtualPackage; + Backend *backend = PackageAnalyzer::instance().backendPtr(); + for (auto *availablePackage : backend->availablePackages()) { + if (!availablePackage->providesList().contains(depend)) { + continue; + } + + if (!dependStatus.contains(availablePackage->name())) { + dependStatus.append(availablePackage->name()); + virtualPackage.append(availablePackage->name()); + + // 使用虚包的依赖关系 + if (m_dependsInfo.contains(depend)) { + m_dependsInfo.insert(availablePackage->name(), m_dependsInfo.value(depend)); + } + } + } + + qInfo() << QString("Detect or depends %1 contains virtual packages: ").arg(depend) << virtualPackage; + }; + QString packageName; QString controlDepends; if (flag) { @@ -892,14 +914,42 @@ void PackagesManager::getPackageOrDepends(const QString &package, const QString qDebug() << qPrintable("Package:") << packageName << qPrintable("controlDepends") << controlDepends; QStringList dependsList = controlDepends.split(","); - auto removedIter = std::remove_if(dependsList.begin(), dependsList.end(), [](const QString & str) { - return !str.contains("|"); - }); - dependsList.erase(removedIter, dependsList.end()); + // 移除非或包依赖 + // auto removedIter = std::remove_if(dependsList.begin(), dependsList.end(), [](const QString & str) { + // return !str.contains("|"); + // }); + // dependsList.erase(removedIter, dependsList.end()); - //使用二维数组进行存储 + // 使用二维数组进行存储 for (QString depend : dependsList) { depend = depend.remove(QRegExp("\\s")); + + // 非或包,判断虚包依赖 + if (!depend.contains("|")) { + //截取依赖包名 + if (depend.contains("(")) { + int mid = depend.indexOf("("); + depend = depend.left(mid); + } + + QVector dependStatus; + // 判断是否为虚包,若为虚包,将实现包都加入或列表 + Package *package = packageWithArch(depend, arch, arch); + if (package && depend != package->name()) { + // 需要将当前包同样插入,方便查找 + dependStatus.append(depend); + + checkVirtualPackage(dependStatus, depend); + } + + if (!dependStatus.isEmpty()) { + m_orDepends.append(dependStatus); + m_unCheckedOrDepends.append(dependStatus); + } + + continue; + } + QStringList orDepends = depend.split("|"); QVector dependStatus; for (QString ordepend : orDepends) { @@ -912,23 +962,7 @@ void PackagesManager::getPackageOrDepends(const QString &package, const QString // 判断是否为虚包,若为虚包,将实现包都加入或列表 Package *package = packageWithArch(ordepend, arch, arch); if (package && ordepend != package->name()) { - Backend *backend = PackageAnalyzer::instance().backendPtr(); - for (auto *availablePackage : backend->availablePackages()) { - if (!availablePackage->providesList().contains(ordepend)) { - continue; - } - - if (!dependStatus.contains(availablePackage->name())) { - dependStatus.append(availablePackage->name()); - - // 使用虚包的依赖关系 - if (m_dependsInfo.contains(ordepend)) { - m_dependsInfo.insert(availablePackage->name(), m_dependsInfo.value(ordepend)); - - qInfo() << QString("Detect or depends %1 contains virtual package: %2").arg(ordepend).arg(availablePackage->name()); - } - } - } + checkVirtualPackage(dependStatus, ordepend); } else { dependStatus.append(ordepend); } @@ -1633,7 +1667,8 @@ const PackageDependsStatus PackagesManager::checkDependsPackageStatus(QSet