From 4abb9cd9b360278f5c8984a9fd2e62677e7c940c Mon Sep 17 00:00:00 2001 From: Katja Marttila Date: Tue, 28 May 2019 12:50:13 +0300 Subject: Add possibility to move component in component tree Setting -tag to component.xml will overwrite the default location of component in installer's tree view. This way we can define the component location without a complete repo build. Updates.xml can be directly modified by adding -tag for easy relocation of components. TreeName must be an unique name - it cannot conflict with existing tree name or name. Task-number: QTIFW-594 Change-Id: Ie69f90f1303d932369d566d0d7b4bc0e354505c6 Reviewed-by: Arttu Tarkiainen --- doc/examples/package.xml | 1 + doc/installerfw.qdoc | 6 + src/libs/installer/component.cpp | 12 ++ src/libs/installer/component.h | 4 +- src/libs/installer/componentmodel.cpp | 20 +-- src/libs/installer/componentselectionpage_p.cpp | 4 +- src/libs/installer/constants.h | 1 + src/libs/installer/packagemanagercore.cpp | 77 ++++++++---- src/libs/installer/packagemanagercore_p.cpp | 4 +- src/libs/kdtools/localpackagehub.cpp | 7 +- src/libs/kdtools/localpackagehub.h | 4 +- .../auto/installer/componentmodel/data/updates.xml | 10 ++ .../componentmodel/tst_componentmodel.cpp | 30 ++--- tests/auto/installer/installer.pro | 3 +- .../treename/data/invalid_repository/Updates.xml | 40 ++++++ .../installer/treename/data/repository/Updates.xml | 119 ++++++++++++++++++ .../repository/componentA.sub1/1.0.0content.7z | Bin 0 -> 243 bytes .../componentA.sub1/1.0.0content.7z.sha1 | 1 + .../data/repository/componentA.sub1/1.0.0meta.7z | Bin 0 -> 138 bytes .../repository/componentA.sub2/1.0.0content.7z | Bin 0 -> 243 bytes .../componentA.sub2/1.0.0content.7z.sha1 | 1 + .../data/repository/componentA.sub2/1.0.0meta.7z | Bin 0 -> 138 bytes .../data/repository/componentA/1.0.0content.7z | Bin 0 -> 235 bytes .../repository/componentA/1.0.0content.7z.sha1 | 1 + .../data/repository/componentA/1.0.0meta.7z | Bin 0 -> 130 bytes .../componentB.sub1.sub1/1.0.0content.7z | Bin 0 -> 251 bytes .../componentB.sub1.sub1/1.0.0content.7z.sha1 | 1 + .../repository/componentB.sub1.sub1/1.0.0meta.7z | Bin 0 -> 146 bytes .../componentB.sub1.sub2/1.0.0content.7z | Bin 0 -> 251 bytes .../componentB.sub1.sub2/1.0.0content.7z.sha1 | 1 + .../repository/componentB.sub1.sub2/1.0.0meta.7z | Bin 0 -> 146 bytes .../repository/componentB.sub1/1.0.0content.7z | Bin 0 -> 243 bytes .../componentB.sub1/1.0.0content.7z.sha1 | 1 + .../data/repository/componentB.sub1/1.0.0meta.7z | Bin 0 -> 138 bytes .../repository/componentB.sub2/1.0.0content.7z | Bin 0 -> 243 bytes .../componentB.sub2/1.0.0content.7z.sha1 | 1 + .../data/repository/componentB.sub2/1.0.0meta.7z | Bin 0 -> 138 bytes .../data/repository/componentB/1.0.0content.7z | Bin 0 -> 235 bytes .../repository/componentB/1.0.0content.7z.sha1 | 1 + .../data/repository/componentB/1.0.0meta.7z | Bin 0 -> 130 bytes .../data/repository/componentC/1.0.0content.7z | Bin 0 -> 235 bytes .../repository/componentC/1.0.0content.7z.sha1 | 1 + .../data/repository/componentC/1.0.0meta.7z | Bin 0 -> 130 bytes .../data/repository/componentD/1.0.0content.7z | Bin 0 -> 235 bytes .../repository/componentD/1.0.0content.7z.sha1 | 1 + .../data/repository/componentD/1.0.0meta.7z | Bin 0 -> 130 bytes tests/auto/installer/treename/settings.qrc | 26 ++++ tests/auto/installer/treename/treename.pro | 10 ++ tests/auto/installer/treename/tst_treename.cpp | 136 +++++++++++++++++++++ 49 files changed, 472 insertions(+), 52 deletions(-) create mode 100644 tests/auto/installer/treename/data/invalid_repository/Updates.xml create mode 100644 tests/auto/installer/treename/data/repository/Updates.xml create mode 100644 tests/auto/installer/treename/data/repository/componentA.sub1/1.0.0content.7z create mode 100644 tests/auto/installer/treename/data/repository/componentA.sub1/1.0.0content.7z.sha1 create mode 100644 tests/auto/installer/treename/data/repository/componentA.sub1/1.0.0meta.7z create mode 100644 tests/auto/installer/treename/data/repository/componentA.sub2/1.0.0content.7z create mode 100644 tests/auto/installer/treename/data/repository/componentA.sub2/1.0.0content.7z.sha1 create mode 100644 tests/auto/installer/treename/data/repository/componentA.sub2/1.0.0meta.7z create mode 100644 tests/auto/installer/treename/data/repository/componentA/1.0.0content.7z create mode 100644 tests/auto/installer/treename/data/repository/componentA/1.0.0content.7z.sha1 create mode 100644 tests/auto/installer/treename/data/repository/componentA/1.0.0meta.7z create mode 100644 tests/auto/installer/treename/data/repository/componentB.sub1.sub1/1.0.0content.7z create mode 100644 tests/auto/installer/treename/data/repository/componentB.sub1.sub1/1.0.0content.7z.sha1 create mode 100644 tests/auto/installer/treename/data/repository/componentB.sub1.sub1/1.0.0meta.7z create mode 100644 tests/auto/installer/treename/data/repository/componentB.sub1.sub2/1.0.0content.7z create mode 100644 tests/auto/installer/treename/data/repository/componentB.sub1.sub2/1.0.0content.7z.sha1 create mode 100644 tests/auto/installer/treename/data/repository/componentB.sub1.sub2/1.0.0meta.7z create mode 100644 tests/auto/installer/treename/data/repository/componentB.sub1/1.0.0content.7z create mode 100644 tests/auto/installer/treename/data/repository/componentB.sub1/1.0.0content.7z.sha1 create mode 100644 tests/auto/installer/treename/data/repository/componentB.sub1/1.0.0meta.7z create mode 100644 tests/auto/installer/treename/data/repository/componentB.sub2/1.0.0content.7z create mode 100644 tests/auto/installer/treename/data/repository/componentB.sub2/1.0.0content.7z.sha1 create mode 100644 tests/auto/installer/treename/data/repository/componentB.sub2/1.0.0meta.7z create mode 100644 tests/auto/installer/treename/data/repository/componentB/1.0.0content.7z create mode 100644 tests/auto/installer/treename/data/repository/componentB/1.0.0content.7z.sha1 create mode 100644 tests/auto/installer/treename/data/repository/componentB/1.0.0meta.7z create mode 100644 tests/auto/installer/treename/data/repository/componentC/1.0.0content.7z create mode 100644 tests/auto/installer/treename/data/repository/componentC/1.0.0content.7z.sha1 create mode 100644 tests/auto/installer/treename/data/repository/componentC/1.0.0meta.7z create mode 100644 tests/auto/installer/treename/data/repository/componentD/1.0.0content.7z create mode 100644 tests/auto/installer/treename/data/repository/componentD/1.0.0content.7z.sha1 create mode 100644 tests/auto/installer/treename/data/repository/componentD/1.0.0meta.7z create mode 100644 tests/auto/installer/treename/settings.qrc create mode 100644 tests/auto/installer/treename/treename.pro create mode 100644 tests/auto/installer/treename/tst_treename.cpp diff --git a/doc/examples/package.xml b/doc/examples/package.xml index 16b9e07ce..81792416c 100644 --- a/doc/examples/package.xml +++ b/doc/examples/package.xml @@ -42,4 +42,5 @@ @TargetDir@/Folder2 + com.vendor.subcomponent diff --git a/doc/installerfw.qdoc b/doc/installerfw.qdoc index fe49d6a9e..0543a800c 100644 --- a/doc/installerfw.qdoc +++ b/doc/installerfw.qdoc @@ -938,6 +938,12 @@ For more information, see \l{Adding Operations}. For a summary of available operations, see \l {Operations}. + \row + \li TreeName + \li Specifies the component location in the install tree view. Overwrites the original + location which is calculated from component name. Component names and tree names + must be unique. Optional. + \endtable \section2 Component Dependencies diff --git a/src/libs/installer/component.cpp b/src/libs/installer/component.cpp index 2e797944b..ff01e4251 100644 --- a/src/libs/installer/component.cpp +++ b/src/libs/installer/component.cpp @@ -274,6 +274,7 @@ void Component::loadDataFromPackage(const KDUpdater::LocalPackage &package) { setValue(scName, package.name); setValue(scDisplayName, package.title); + setValue(scTreeName, package.treeName); setValue(scDescription, package.description); setValue(scVersion, package.version); setValue(scInheritVersion, package.inheritVersionFrom); @@ -301,6 +302,7 @@ void Component::loadDataFromPackage(const Package &package) setValue(scName, package.data(scName).toString()); setValue(scDisplayName, package.data(scDisplayName).toString()); + setValue(scTreeName, package.data(scTreeName).toString()); setValue(scDescription, package.data(scDescription).toString()); setValue(scDefault, package.data(scDefault).toString()); setValue(scAutoDependOn, package.data(scAutoDependOn).toString()); @@ -522,6 +524,16 @@ QString Component::displayName() const return d->m_vars.value(scDisplayName); } +/*! + Returns this component's location in the tree view. If the tree name is not + set, returns the component name. The tree name must be unique, it must not + conflict with other tree names or component names. +*/ +QString Component::treeName() const +{ + return d->m_vars.value(scTreeName, name()); +} + /*! Loads the component script into the script engine. */ diff --git a/src/libs/installer/component.h b/src/libs/installer/component.h index f7f03391f..d042bfe6a 100644 --- a/src/libs/installer/component.h +++ b/src/libs/installer/component.h @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -62,6 +62,7 @@ class INSTALLER_EXPORT Component : public QObject, public ComponentModelHelper Q_PROPERTY(bool installed READ isInstalled) Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) Q_PROPERTY(bool unstable READ isUnstable) + Q_PROPERTY(QString treeName READ treeName) public: explicit Component(PackageManagerCore *core); @@ -157,6 +158,7 @@ public: QString name() const; QString displayName() const; + QString treeName() const; quint64 updateUncompressedSize(); QUrl repositoryUrl() const; diff --git a/src/libs/installer/componentmodel.cpp b/src/libs/installer/componentmodel.cpp index 45e27ba4a..aab487b45 100644 --- a/src/libs/installer/componentmodel.cpp +++ b/src/libs/installer/componentmodel.cpp @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -159,7 +159,7 @@ QModelIndex ComponentModel::parent(const QModelIndex &child) const if (Component *childComponent = componentFromIndex(child)) { if (Component *parent = childComponent->parentComponent()) - return indexFromComponentName(parent->name()); + return indexFromComponentName(parent->treeName()); } return QModelIndex(); } @@ -513,18 +513,18 @@ void ComponentModel::updateAndEmitModelState() emit checkStateChanged(m_modelState); foreach (const Component *component, m_rootComponentList) { - emit dataChanged(indexFromComponentName(component->name()), - indexFromComponentName(component->name())); + emit dataChanged(indexFromComponentName(component->treeName()), + indexFromComponentName(component->treeName())); QList children = component->childItems(); foreach (const Component *child, children) - emit dataChanged(indexFromComponentName(child->name()), - indexFromComponentName(child->name())); + emit dataChanged(indexFromComponentName(child->treeName()), + indexFromComponentName(child->treeName())); } } void ComponentModel::collectComponents(Component *const component, const QModelIndex &parent) const { - m_indexByNameCache.insert(component->name(), parent); + m_indexByNameCache.insert(component->treeName(), parent); for (int i = 0; i < component->childCount(); ++i) collectComponents(component->childAt(i), index(i, 0, parent)); } @@ -568,8 +568,8 @@ QSet ComponentModel::updateCheckedState(const ComponentSet &compone // get all parent nodes for the components we're going to update QMap sortedNodesMap; foreach (Component *component, components) { - while (component && !sortedNodesMap.values(component->name()).contains(component)) { - sortedNodesMap.insertMulti(component->name(), component); + while (component && !sortedNodesMap.values(component->treeName()).contains(component)) { + sortedNodesMap.insertMulti(component->treeName(), component); component = component->parentComponent(); } } @@ -596,7 +596,7 @@ QSet ComponentModel::updateCheckedState(const ComponentSet &compone continue; node->setCheckState(newState); - changed.insert(indexFromComponentName(node->name())); + changed.insert(indexFromComponentName(node->treeName())); m_currentCheckedState[Qt::Checked].remove(node); m_currentCheckedState[Qt::Unchecked].remove(node); diff --git a/src/libs/installer/componentselectionpage_p.cpp b/src/libs/installer/componentselectionpage_p.cpp index 31c4dbedc..a9f4ba134 100644 --- a/src/libs/installer/componentselectionpage_p.cpp +++ b/src/libs/installer/componentselectionpage_p.cpp @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -274,7 +274,7 @@ void ComponentSelectionPagePrivate::updateTreeView() m_treeView->setExpanded(m_currentModel->index(0, 0), true); foreach (Component *component, m_core->components(PackageManagerCore::ComponentType::All)) { if (component->isExpandedByDefault()) { - const QModelIndex index = m_currentModel->indexFromComponentName(component->name()); + const QModelIndex index = m_currentModel->indexFromComponentName(component->treeName()); m_treeView->setExpanded(index, true); } } diff --git a/src/libs/installer/constants.h b/src/libs/installer/constants.h index feee73fad..42b14ce63 100644 --- a/src/libs/installer/constants.h +++ b/src/libs/installer/constants.h @@ -55,6 +55,7 @@ static const QLatin1String scTargetDir("TargetDir"); static const QLatin1String scReleaseDate("ReleaseDate"); static const QLatin1String scDescription("Description"); static const QLatin1String scDisplayName("DisplayName"); +static const QLatin1String scTreeName("TreeName"); static const QLatin1String scDependencies("Dependencies"); static const QLatin1String scAutoDependOn("AutoDependOn"); static const QLatin1String scNewComponent("NewComponent"); diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp index 7eaae7b33..41744ff96 100644 --- a/src/libs/installer/packagemanagercore.cpp +++ b/src/libs/installer/packagemanagercore.cpp @@ -1372,11 +1372,11 @@ bool PackageManagerCore::fetchLocalPackagesTree() foreach (const QString &key, keys) { QScopedPointer component(new QInstaller::Component(this)); component->loadDataFromPackage(installedPackages.value(key)); - const QString &name = component->name(); + const QString &name = component->treeName(); if (components.contains(name)) { - qCritical("Cannot register component! Component with identifier %s already registered.", - qPrintable(name)); - continue; + d->setStatus(Failure, tr("Cannot register component! Component with identifier %1 " + "already exists.").arg(name)); + return false; } components.insert(name, component.take()); } @@ -2210,7 +2210,7 @@ bool PackageManagerCore::componentUninstallableFromCommandLine(const QString &co return false; } ComponentModel *model = defaultComponentModel(); - const QModelIndex &idx = model->indexFromComponentName(componentName); + const QModelIndex &idx = model->indexFromComponentName(component->treeName()); if (model->data(idx, Qt::CheckStateRole) == QVariant::Invalid) { // Component cannot be unselected, check why if (component->forcedInstallation()) { @@ -2246,9 +2246,13 @@ bool PackageManagerCore::checkComponentsForInstallation(const QStringList &compo ComponentModel *model = defaultComponentModel(); foreach (const QString &name, components) { - const QModelIndex &idx = model->indexFromComponentName(name); Component *component = componentByName(name); - if (component && idx.isValid()) { + if (!component) { + errorMessage.append(tr("Cannot install %1. Component not found.\n").arg(name)); + continue; + } + const QModelIndex &idx = model->indexFromComponentName(component->treeName()); + if (idx.isValid()) { if ((model->data(idx, Qt::CheckStateRole) == QVariant::Invalid) && !component->forcedInstallation()) { // User cannot select the component, check why if (component->autoDependencies().count() > 0) { @@ -2265,7 +2269,7 @@ bool PackageManagerCore::checkComponentsForInstallation(const QStringList &compo installComponentsFound = true; } } else { // idx is invalid and component valid when we have invisible virtual component - component && component->isVirtual() + component->isVirtual() ? errorMessage.append(tr("Cannot install %1. Component is virtual.\n").arg(name)) : errorMessage.append(tr("Cannot install %1. Component not found.\n").arg(name)); } @@ -2330,7 +2334,7 @@ PackageManagerCore::Status PackageManagerCore::updateComponentsSilently(const QS QList componentsToBeUpdated; //Mark components to be updated foreach (Component *comp, componentList) { - const QModelIndex &idx = model->indexFromComponentName(comp->name()); + const QModelIndex &idx = model->indexFromComponentName(comp->treeName()); if (!userSelectedComponents) { // No components given, update all model->setData(idx, Qt::Checked, Qt::CheckStateRole); } else { @@ -2350,7 +2354,7 @@ PackageManagerCore::Status PackageManagerCore::updateComponentsSilently(const QS return PackageManagerCore::Success; } foreach (Component *componentToUpdate, componentsToBeUpdated) { - const QModelIndex &idx = model->indexFromComponentName(componentToUpdate->name()); + const QModelIndex &idx = model->indexFromComponentName(componentToUpdate->treeName()); model->setData(idx, Qt::Checked, Qt::CheckStateRole); } } @@ -2434,11 +2438,11 @@ PackageManagerCore::Status PackageManagerCore::uninstallComponentsSilently(const bool uninstallComponentFound = false; foreach (const QString &componentName, components){ - const QModelIndex &idx = model->indexFromComponentName(componentName); Component *component = componentByName(componentName); if (component) { - if (componentUninstallableFromCommandLine(componentName)) { + const QModelIndex &idx = model->indexFromComponentName(component->treeName()); + if (componentUninstallableFromCommandLine(component->name())) { model->setData(idx, Qt::Unchecked, Qt::CheckStateRole); uninstallComponentFound = true; } @@ -3516,14 +3520,17 @@ QString PackageManagerCore::maintenanceToolName() const bool PackageManagerCore::updateComponentData(struct Data &data, Component *component) { try { - // check if we already added the component to the available components list - const QString name = data.package->data(scName).toString(); + // Check if we already added the component to the available components list. + // Component treenames and names must be unique. + QString name = data.package->data(scTreeName).toString(); + if (name.isEmpty()) + name = data.package->data(scName).toString(); if (data.components->contains(name)) { - qCritical("Cannot register component! Component with identifier %s already registered.", - qPrintable(name)); + d->setStatus(Failure, tr("Cannot register component! Component with identifier %1 " + "already exists.").arg(name)); return false; } - + name = data.package->data(scName).toString(); if (settings().allowUnstableComponents()) { // Check if there are sha checksum mismatch. Component will still show in install tree // but is unselectable. @@ -3643,6 +3650,7 @@ bool PackageManagerCore::fetchAllPackages(const PackagesList &remotes, const Loc data.components = &components; data.installedPackages = &locals; + QMap treeNameComponents; foreach (Package *const package, remotes) { if (d->statusCanceledOrFailed()) return false; @@ -3654,17 +3662,42 @@ bool PackageManagerCore::fetchAllPackages(const PackagesList &remotes, const Loc data.package = package; component->loadDataFromPackage(*package); if (updateComponentData(data, component.data())) { - const QString name = component->name(); + // Create a list where is name and treename. Repo can contain a package with + // a different treename of component which is already installed. We don't want + // to move already installed local packages. + const QString treeName = component->value(scTreeName); + if (!treeName.isEmpty()) + treeNameComponents.insert(component->name(), treeName); + QString name = component->treeName(); components.insert(name, component.take()); + } else { + return false; } } foreach (const QString &key, locals.keys()) { QScopedPointer component(new QInstaller::Component(this)); component->loadDataFromPackage(locals.value(key)); - const QString &name = component->name(); - if (!components.contains(name)) - components.insert(name, component.take()); + QString treeName = component->treeName(); + + // 1. Component has a treename in local but not in remote + if (!treeNameComponents.contains(component->name()) && !component->value(scTreeName).isEmpty()) { + Component *comp = components.take(component->name()); + delete comp; + components.insert(treeName, component.take()); + // 2. Component has different treename in local and remote, add with local treename + } else if (treeNameComponents.contains(component->name())) { + QString remoteTreeName = treeNameComponents.value(component->name()); + QString componentTreeName = component->value(scTreeName); + if (remoteTreeName != componentTreeName) { + Component *comp = components.take(treeNameComponents.value(component->name())); + delete comp; + components.insert(treeName, component.take()); + } + // 3. Component has same treename in local and remote, don't add the component again. + } else if (!components.contains(treeName)) { + components.insert(treeName, component.take()); + } } // store all components that got a replacement @@ -3750,6 +3783,8 @@ bool PackageManagerCore::fetchUpdaterPackages(const PackagesList &remotes, const // this is not a dependency, it is a real update components.insert(name, d->m_updaterComponentsDeps.takeLast()); + } else { + return false; } } diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp index 94e08018a..924de0de3 100644 --- a/src/libs/installer/packagemanagercore_p.cpp +++ b/src/libs/installer/packagemanagercore_p.cpp @@ -2233,6 +2233,7 @@ void PackageManagerCorePrivate::installComponent(Component *component, double pr m_localPackageHub->addPackage(component->name(), component->value(scVersion), component->value(scDisplayName), + component->value(scTreeName), component->value(scDescription), component->dependencies(), component->autoDependencies(), @@ -2273,7 +2274,8 @@ bool PackageManagerCorePrivate::runningProcessesFound() void PackageManagerCorePrivate::setComponentSelection(const QString &id, Qt::CheckState state) { ComponentModel *model = m_core->isUpdater() ? m_core->updaterComponentModel() : m_core->defaultComponentModel(); - const QModelIndex &idx = model->indexFromComponentName(id); + Component *component = m_core->componentByName(id); + const QModelIndex &idx = model->indexFromComponentName(component->treeName()); if (idx.isValid()) model->setData(idx, state, Qt::CheckStateRole); } diff --git a/src/libs/kdtools/localpackagehub.cpp b/src/libs/kdtools/localpackagehub.cpp index d6208a610..9d35a9d1d 100644 --- a/src/libs/kdtools/localpackagehub.cpp +++ b/src/libs/kdtools/localpackagehub.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB) -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -317,6 +317,7 @@ void LocalPackageHub::refresh() void LocalPackageHub::addPackage(const QString &name, const QString &version, const QString &title, + const QString &treeName, const QString &description, const QStringList &dependencies, const QStringList &autoDependencies, @@ -339,6 +340,7 @@ void LocalPackageHub::addPackage(const QString &name, info.inheritVersionFrom = inheritVersionFrom; info.installDate = QDate::currentDate(); info.title = title; + info.treeName = treeName; info.description = description; info.dependencies = dependencies; info.autoDependencies = autoDependencies; @@ -398,6 +400,7 @@ void LocalPackageHub::writeToDisk() addTextChildHelper(&package, QLatin1String("Name"), info.name); addTextChildHelper(&package, QLatin1String("Title"), info.title); addTextChildHelper(&package, QLatin1String("Description"), info.description); + addTextChildHelper(&package, scTreeName, info.treeName); if (info.inheritVersionFrom.isEmpty()) addTextChildHelper(&package, QLatin1String("Version"), info.version); else @@ -468,6 +471,8 @@ void LocalPackageHub::PackagesInfoData::addPackageFrom(const QDomElement &packag info.title = childNodeE.text(); else if (childNodeE.tagName() == QLatin1String("Description")) info.description = childNodeE.text(); + else if (childNodeE.tagName() == scTreeName) + info.treeName = childNodeE.text(); else if (childNodeE.tagName() == QLatin1String("Version")) { info.version = childNodeE.text(); info.inheritVersionFrom = childNodeE.attribute(QLatin1String("inheritVersionFrom")); diff --git a/src/libs/kdtools/localpackagehub.h b/src/libs/kdtools/localpackagehub.h index 7a067e73e..d43c4a6a5 100644 --- a/src/libs/kdtools/localpackagehub.h +++ b/src/libs/kdtools/localpackagehub.h @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB) -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -43,6 +43,7 @@ struct KDTOOLS_EXPORT LocalPackage QString name; QString title; QString description; + QString treeName; QString version; QString inheritVersionFrom; QStringList dependencies; @@ -98,6 +99,7 @@ public: void addPackage(const QString &pkgName, const QString &version, // mandatory const QString &title, + const QString &treeName, const QString &description, const QStringList &dependencies, const QStringList &autoDependencies, diff --git a/tests/auto/installer/componentmodel/data/updates.xml b/tests/auto/installer/componentmodel/data/updates.xml index 2341866ee..3a6139446 100644 --- a/tests/auto/installer/componentmodel/data/updates.xml +++ b/tests/auto/installer/componentmodel/data/updates.xml @@ -177,4 +177,14 @@ file="license.txt"/> + + com.vendor.fifth.product.noncheckable.sub2 + A sub component, moved to top level + Install this example. + 0.1.0-1 + 2010-09-21 + 0 + + moved_with_treename + diff --git a/tests/auto/installer/componentmodel/tst_componentmodel.cpp b/tests/auto/installer/componentmodel/tst_componentmodel.cpp index 220aa73e3..0672a03ec 100644 --- a/tests/auto/installer/componentmodel/tst_componentmodel.cpp +++ b/tests/auto/installer/componentmodel/tst_componentmodel.cpp @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -37,8 +37,8 @@ using namespace KDUpdater; using namespace QInstaller; -#define EXPECTED_COUNT_VIRTUALS_VISIBLE 11 -#define EXPECTED_COUNT_VIRTUALS_INVISIBLE 10 +#define EXPECTED_COUNT_VIRTUALS_VISIBLE 12 +#define EXPECTED_COUNT_VIRTUALS_INVISIBLE 11 static const char vendorProduct[] = "com.vendor.product"; static const char vendorSecondProduct[] = "com.vendor.second.product"; @@ -51,6 +51,7 @@ static const char vendorThirdProductVirtual[] = "com.vendor.third.product.virtua static const char vendorFourthProductCheckable[] = "com.vendor.fourth.product.checkable"; static const char vendorFifthProductNonCheckable[] = "com.vendor.fifth.product.noncheckable"; static const char vendorFifthProductSub[] = "com.vendor.fifth.product.noncheckable.sub"; +static const char vendorFifthProductSubWithTreeName[] = "moved_with_treename"; static const QMap rootComponentDisplayNames = { {"", QLatin1String("The root component")}, @@ -78,7 +79,7 @@ private slots: m_defaultPartially << vendorSecondProduct; m_defaultUnchecked << vendorSecondProductSub1 << vendorSecondProductSubnode << vendorSecondProductSubnodeSub << vendorFourthProductCheckable - << vendorFifthProductSub; + << vendorFifthProductSub << vendorFifthProductSubWithTreeName; m_uncheckable << vendorFifthProductNonCheckable; } @@ -99,7 +100,7 @@ private slots: foreach (const QString &name, all) { QVERIFY(model.indexFromComponentName(name).isValid()); QVERIFY(model.componentFromIndex(model.indexFromComponentName(name)) != 0); - QCOMPARE(model.componentFromIndex(model.indexFromComponentName(name))->name(), name); + QCOMPARE(model.componentFromIndex(model.indexFromComponentName(name))->treeName(), name); } foreach (Component *const component, rootComponents) @@ -124,7 +125,7 @@ private slots: foreach (const QString &name, all) { QVERIFY(model.indexFromComponentName(name).isValid()); QVERIFY(model.componentFromIndex(model.indexFromComponentName(name)) != 0); - QCOMPARE(model.componentFromIndex(model.indexFromComponentName(name))->name(), name); + QCOMPARE(model.componentFromIndex(model.indexFromComponentName(name))->treeName(), name); } foreach (Component *const component, rootComponents) @@ -415,8 +416,8 @@ private: void testComponentsLoaded(const QList &rootComponents) const { - // we need to have five root components - QCOMPARE(rootComponents.count(), 5); + // we need to have six root components + QCOMPARE(rootComponents.count(), 6); QList components = rootComponents; foreach (Component *const component, rootComponents) @@ -431,9 +432,9 @@ private: { // row count with invalid model index should return: if (m_core.virtualComponentsVisible()) - QCOMPARE(model->rowCount(), 5); // 5 (4 non virtual and 1 virtual root component) + QCOMPARE(model->rowCount(), 6); // 6 (5 non virtual and 1 virtual root component) else - QCOMPARE(model->rowCount(), 4); // 4 (the 4 non virtual root components) + QCOMPARE(model->rowCount(), 5); // 5 (the 5 non virtual root components) QCOMPARE(model->columnCount(), columnCount); const QModelIndex firstParent = model->indexFromComponentName(vendorProduct); @@ -497,15 +498,15 @@ private: // these components should have checked state foreach (Component *const component, model->checked()) - QVERIFY(checked.contains(component->name())); + QVERIFY(checked.contains(component->treeName())); // these components should not have partially checked state foreach (Component *const component, model->partially()) - QVERIFY(partially.contains(component->name())); + QVERIFY(partially.contains(component->treeName())); // these components should not have checked state foreach (Component *const component, model->unchecked()) - QVERIFY(unchecked.contains(component->name())); + QVERIFY(unchecked.contains(component->treeName())); } QList loadComponents() const @@ -520,6 +521,7 @@ private: // we need at least these to be able to test the model component->setValue("Name", info.data.value("Name").toString()); + component->setValue("TreeName", info.data.value("TreeName").toString()); QString isDefault = info.data.value("Default").toString(); if (m_core.noDefaultInstallation()) isDefault = scFalse; @@ -537,7 +539,7 @@ private: component->setCheckable(false); component->setCheckState(Qt::Checked); } - components.insert(component->name(), component); + components.insert(component->treeName(), component); } QList rootComponents; diff --git a/tests/auto/installer/installer.pro b/tests/auto/installer/installer.pro index 4421643b8..2f65d607e 100644 --- a/tests/auto/installer/installer.pro +++ b/tests/auto/installer/installer.pro @@ -37,7 +37,8 @@ SUBDIRS += \ environmentvariableoperation \ licenseagreement \ globalsettingsoperation \ - elevatedexecuteoperation + elevatedexecuteoperation \ + treename win32 { SUBDIRS += registerfiletypeoperation \ diff --git a/tests/auto/installer/treename/data/invalid_repository/Updates.xml b/tests/auto/installer/treename/data/invalid_repository/Updates.xml new file mode 100644 index 000000000..a9542eb0d --- /dev/null +++ b/tests/auto/installer/treename/data/invalid_repository/Updates.xml @@ -0,0 +1,40 @@ + + {AnyApplication} + 1.0.0 + false + + componentA + Component A + This component depends on componentB.sub2. + 1.0.0 + 2014-08-25 + 80 + componentB.sub2 + + content.7z + 570dec768b1f266c66656f015e772f0e6e41b73d + + + componentA.sub1 + Component A subcomponent 1 + component + 1.0.0 + 2014-08-25 + 80 + + content.7z + da5819910a7f7c95eb61a49543e273fd6e2e9aae + + + componentB + Component B + Component B + 1.0.0 + 2014-08-25 + 40 + + content.7z + 72eee5304ff866e024b477d7b2432df8f2428483 + componentA.sub1 + + diff --git a/tests/auto/installer/treename/data/repository/Updates.xml b/tests/auto/installer/treename/data/repository/Updates.xml new file mode 100644 index 000000000..1ab3caa23 --- /dev/null +++ b/tests/auto/installer/treename/data/repository/Updates.xml @@ -0,0 +1,119 @@ + + {AnyApplication} + 1.0.0 + false + + componentA + Component A + This component depends on componentB.sub2. + 1.0.0 + 2014-08-25 + 80 + componentB.sub2 + + content.7z + 570dec768b1f266c66656f015e772f0e6e41b73d + + + componentA.sub1 + Component A subcomponent 1 + component + 1.0.0 + 2014-08-25 + 80 + + content.7z + da5819910a7f7c95eb61a49543e273fd6e2e9aae + + + componentA.sub2 + Component A subcomponent 2 + component + 1.0.0 + 2014-08-25 + 80 + ASub2ToRoot + + content.7z + 73ac2c332ce01fadf0f1c7e16a27faaf0f853e18 + + + componentB + Component B + Component B + 1.0.0 + 2014-08-25 + 40 + + content.7z + 72eee5304ff866e024b477d7b2432df8f2428483 + + + componentB.sub1 + Component B subcomponent 2 1 + Subcomponent for B + 1.0.0 + 2014-08-25 + 100 + + content.7z + e19f1a26698afe0b72c9048b403253421b8fed4b + + + componentB.sub1.sub1 + Component B sub component for sub1 + Subsubcomponent for B. Moved to root with treename. + 1.0.0 + 2014-08-25 + 100 + BSub1Sub1ToRoot + + content.7z + 6a348979273336862c7a5e16305779e81fee1081 + + + componentB.sub1.sub2 + Component B second sub component for sub1 + Subsubcomponent for B. Moved under componentC with treename. + 1.0.0 + 2014-08-25 + 100 + componentC.sub1 + + content.7z + c1bca8944147ec64343c146f461288990268b4a9 + + + componentB.sub2 + Component B subcomponent 2 + Subcomponent for B. Moved to root with treename. + 1.0.0 + 2014-08-25 + 8000 + BSub2ToRoot + + content.7z + bde9feba3a8134e9c1412b674ee21642938fafec + + + componentC + Component C + Component C + 1.0.0 + 2014-08-25 + + content.7z + cc33e730d9127e1636566ea35bbe4f186ba4bcb7 + + + componentD + Component D + Component D. Autodepends on moved item componentA.sub2 + 1.0.0 + 2014-08-25 + componentA.sub2 + + content.7z + 3ca69d6bb062c4442fdb20fe0e62bb0f04e8a419 + + diff --git a/tests/auto/installer/treename/data/repository/componentA.sub1/1.0.0content.7z b/tests/auto/installer/treename/data/repository/componentA.sub1/1.0.0content.7z new file mode 100644 index 000000000..f7e22c055 Binary files /dev/null and b/tests/auto/installer/treename/data/repository/componentA.sub1/1.0.0content.7z differ diff --git a/tests/auto/installer/treename/data/repository/componentA.sub1/1.0.0content.7z.sha1 b/tests/auto/installer/treename/data/repository/componentA.sub1/1.0.0content.7z.sha1 new file mode 100644 index 000000000..3378d2da5 --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentA.sub1/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +d46bf0f128c64749fb03050045afc816774185e2 \ No newline at end of file diff --git a/tests/auto/installer/treename/data/repository/componentA.sub1/1.0.0meta.7z b/tests/auto/installer/treename/data/repository/componentA.sub1/1.0.0meta.7z new file mode 100644 index 000000000..81ff563fc Binary files /dev/null and b/tests/auto/installer/treename/data/repository/componentA.sub1/1.0.0meta.7z differ diff --git a/tests/auto/installer/treename/data/repository/componentA.sub2/1.0.0content.7z b/tests/auto/installer/treename/data/repository/componentA.sub2/1.0.0content.7z new file mode 100644 index 000000000..d7f4c781c Binary files /dev/null and b/tests/auto/installer/treename/data/repository/componentA.sub2/1.0.0content.7z differ diff --git a/tests/auto/installer/treename/data/repository/componentA.sub2/1.0.0content.7z.sha1 b/tests/auto/installer/treename/data/repository/componentA.sub2/1.0.0content.7z.sha1 new file mode 100644 index 000000000..0eb4045af --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentA.sub2/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +6561aae70d055e1c4d72b30b12aef7a85cf2139e \ No newline at end of file diff --git a/tests/auto/installer/treename/data/repository/componentA.sub2/1.0.0meta.7z b/tests/auto/installer/treename/data/repository/componentA.sub2/1.0.0meta.7z new file mode 100644 index 000000000..38d7c557d Binary files /dev/null and b/tests/auto/installer/treename/data/repository/componentA.sub2/1.0.0meta.7z differ diff --git a/tests/auto/installer/treename/data/repository/componentA/1.0.0content.7z b/tests/auto/installer/treename/data/repository/componentA/1.0.0content.7z new file mode 100644 index 000000000..e50fc1e92 Binary files /dev/null and b/tests/auto/installer/treename/data/repository/componentA/1.0.0content.7z differ diff --git a/tests/auto/installer/treename/data/repository/componentA/1.0.0content.7z.sha1 b/tests/auto/installer/treename/data/repository/componentA/1.0.0content.7z.sha1 new file mode 100644 index 000000000..082bcbf64 --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentA/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +d8486606a02b9c492e4c17d1e42cfea835a1da51 \ No newline at end of file diff --git a/tests/auto/installer/treename/data/repository/componentA/1.0.0meta.7z b/tests/auto/installer/treename/data/repository/componentA/1.0.0meta.7z new file mode 100644 index 000000000..c062c3cee Binary files /dev/null and b/tests/auto/installer/treename/data/repository/componentA/1.0.0meta.7z differ diff --git a/tests/auto/installer/treename/data/repository/componentB.sub1.sub1/1.0.0content.7z b/tests/auto/installer/treename/data/repository/componentB.sub1.sub1/1.0.0content.7z new file mode 100644 index 000000000..2c254e3aa Binary files /dev/null and b/tests/auto/installer/treename/data/repository/componentB.sub1.sub1/1.0.0content.7z differ diff --git a/tests/auto/installer/treename/data/repository/componentB.sub1.sub1/1.0.0content.7z.sha1 b/tests/auto/installer/treename/data/repository/componentB.sub1.sub1/1.0.0content.7z.sha1 new file mode 100644 index 000000000..019ab5051 --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentB.sub1.sub1/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +3fd04b8e55846f9622ffb8f9ae5f4e6c8b57f90e \ No newline at end of file diff --git a/tests/auto/installer/treename/data/repository/componentB.sub1.sub1/1.0.0meta.7z b/tests/auto/installer/treename/data/repository/componentB.sub1.sub1/1.0.0meta.7z new file mode 100644 index 000000000..31630e810 Binary files /dev/null and b/tests/auto/installer/treename/data/repository/componentB.sub1.sub1/1.0.0meta.7z differ diff --git a/tests/auto/installer/treename/data/repository/componentB.sub1.sub2/1.0.0content.7z b/tests/auto/installer/treename/data/repository/componentB.sub1.sub2/1.0.0content.7z new file mode 100644 index 000000000..261ea6ab9 Binary files /dev/null and b/tests/auto/installer/treename/data/repository/componentB.sub1.sub2/1.0.0content.7z differ diff --git a/tests/auto/installer/treename/data/repository/componentB.sub1.sub2/1.0.0content.7z.sha1 b/tests/auto/installer/treename/data/repository/componentB.sub1.sub2/1.0.0content.7z.sha1 new file mode 100644 index 000000000..c3753ca62 --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentB.sub1.sub2/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +2e89c27c3590e12cd900cb55fa2c91428babfd45 \ No newline at end of file diff --git a/tests/auto/installer/treename/data/repository/componentB.sub1.sub2/1.0.0meta.7z b/tests/auto/installer/treename/data/repository/componentB.sub1.sub2/1.0.0meta.7z new file mode 100644 index 000000000..c449e57f6 Binary files /dev/null and b/tests/auto/installer/treename/data/repository/componentB.sub1.sub2/1.0.0meta.7z differ diff --git a/tests/auto/installer/treename/data/repository/componentB.sub1/1.0.0content.7z b/tests/auto/installer/treename/data/repository/componentB.sub1/1.0.0content.7z new file mode 100644 index 000000000..d938d0fb2 Binary files /dev/null and b/tests/auto/installer/treename/data/repository/componentB.sub1/1.0.0content.7z differ diff --git a/tests/auto/installer/treename/data/repository/componentB.sub1/1.0.0content.7z.sha1 b/tests/auto/installer/treename/data/repository/componentB.sub1/1.0.0content.7z.sha1 new file mode 100644 index 000000000..3db5bca08 --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentB.sub1/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +2407a2adb3d82211921b509e6dd792d67862de0e \ No newline at end of file diff --git a/tests/auto/installer/treename/data/repository/componentB.sub1/1.0.0meta.7z b/tests/auto/installer/treename/data/repository/componentB.sub1/1.0.0meta.7z new file mode 100644 index 000000000..6996a4d01 Binary files /dev/null and b/tests/auto/installer/treename/data/repository/componentB.sub1/1.0.0meta.7z differ diff --git a/tests/auto/installer/treename/data/repository/componentB.sub2/1.0.0content.7z b/tests/auto/installer/treename/data/repository/componentB.sub2/1.0.0content.7z new file mode 100644 index 000000000..7319cf08f Binary files /dev/null and b/tests/auto/installer/treename/data/repository/componentB.sub2/1.0.0content.7z differ diff --git a/tests/auto/installer/treename/data/repository/componentB.sub2/1.0.0content.7z.sha1 b/tests/auto/installer/treename/data/repository/componentB.sub2/1.0.0content.7z.sha1 new file mode 100644 index 000000000..855e2edab --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentB.sub2/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +a8b85ffe4f91b4dc68a6402b314402949ef17a7a \ No newline at end of file diff --git a/tests/auto/installer/treename/data/repository/componentB.sub2/1.0.0meta.7z b/tests/auto/installer/treename/data/repository/componentB.sub2/1.0.0meta.7z new file mode 100644 index 000000000..b91e41207 Binary files /dev/null and b/tests/auto/installer/treename/data/repository/componentB.sub2/1.0.0meta.7z differ diff --git a/tests/auto/installer/treename/data/repository/componentB/1.0.0content.7z b/tests/auto/installer/treename/data/repository/componentB/1.0.0content.7z new file mode 100644 index 000000000..b3a0e683c Binary files /dev/null and b/tests/auto/installer/treename/data/repository/componentB/1.0.0content.7z differ diff --git a/tests/auto/installer/treename/data/repository/componentB/1.0.0content.7z.sha1 b/tests/auto/installer/treename/data/repository/componentB/1.0.0content.7z.sha1 new file mode 100644 index 000000000..377526fb6 --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentB/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +274b3dbe9cceeca1b577eb2a8302d7690ad93eb3 \ No newline at end of file diff --git a/tests/auto/installer/treename/data/repository/componentB/1.0.0meta.7z b/tests/auto/installer/treename/data/repository/componentB/1.0.0meta.7z new file mode 100644 index 000000000..e9ab3969d Binary files /dev/null and b/tests/auto/installer/treename/data/repository/componentB/1.0.0meta.7z differ diff --git a/tests/auto/installer/treename/data/repository/componentC/1.0.0content.7z b/tests/auto/installer/treename/data/repository/componentC/1.0.0content.7z new file mode 100644 index 000000000..7eca1e977 Binary files /dev/null and b/tests/auto/installer/treename/data/repository/componentC/1.0.0content.7z differ diff --git a/tests/auto/installer/treename/data/repository/componentC/1.0.0content.7z.sha1 b/tests/auto/installer/treename/data/repository/componentC/1.0.0content.7z.sha1 new file mode 100644 index 000000000..d3b44feee --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentC/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +d3015ef5340508ad426c43daa2517c7b62581bab \ No newline at end of file diff --git a/tests/auto/installer/treename/data/repository/componentC/1.0.0meta.7z b/tests/auto/installer/treename/data/repository/componentC/1.0.0meta.7z new file mode 100644 index 000000000..47ea321ec Binary files /dev/null and b/tests/auto/installer/treename/data/repository/componentC/1.0.0meta.7z differ diff --git a/tests/auto/installer/treename/data/repository/componentD/1.0.0content.7z b/tests/auto/installer/treename/data/repository/componentD/1.0.0content.7z new file mode 100644 index 000000000..2299f9812 Binary files /dev/null and b/tests/auto/installer/treename/data/repository/componentD/1.0.0content.7z differ diff --git a/tests/auto/installer/treename/data/repository/componentD/1.0.0content.7z.sha1 b/tests/auto/installer/treename/data/repository/componentD/1.0.0content.7z.sha1 new file mode 100644 index 000000000..51dcdd0ed --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentD/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +5ce5b91fb7ce209d83ba616ac01bf30e2942f70c \ No newline at end of file diff --git a/tests/auto/installer/treename/data/repository/componentD/1.0.0meta.7z b/tests/auto/installer/treename/data/repository/componentD/1.0.0meta.7z new file mode 100644 index 000000000..3443e843b Binary files /dev/null and b/tests/auto/installer/treename/data/repository/componentD/1.0.0meta.7z differ diff --git a/tests/auto/installer/treename/settings.qrc b/tests/auto/installer/treename/settings.qrc new file mode 100644 index 000000000..3837d4440 --- /dev/null +++ b/tests/auto/installer/treename/settings.qrc @@ -0,0 +1,26 @@ + + + data/repository/Updates.xml + data/repository/componentA/1.0.0meta.7z + data/repository/componentA/1.0.0content.7z + data/repository/componentA.sub1/1.0.0meta.7z + data/repository/componentA.sub1/1.0.0content.7z + data/repository/componentA.sub2/1.0.0meta.7z + data/repository/componentA.sub2/1.0.0content.7z + data/repository/componentB/1.0.0meta.7z + data/repository/componentB/1.0.0content.7z + data/repository/componentB.sub1/1.0.0meta.7z + data/repository/componentB.sub1/1.0.0content.7z + data/repository/componentB.sub1.sub1/1.0.0meta.7z + data/repository/componentB.sub1.sub1/1.0.0content.7z + data/repository/componentB.sub1.sub2/1.0.0meta.7z + data/repository/componentB.sub1.sub2/1.0.0content.7z + data/repository/componentB.sub2/1.0.0meta.7z + data/repository/componentB.sub2/1.0.0content.7z + data/repository/componentC/1.0.0meta.7z + data/repository/componentC/1.0.0content.7z + data/repository/componentD/1.0.0meta.7z + data/repository/componentD/1.0.0content.7z + data/invalid_repository/Updates.xml + + diff --git a/tests/auto/installer/treename/treename.pro b/tests/auto/installer/treename/treename.pro new file mode 100644 index 000000000..f983b39cf --- /dev/null +++ b/tests/auto/installer/treename/treename.pro @@ -0,0 +1,10 @@ +include(../../qttest.pri) + +QT -= gui +QT += testlib + +SOURCES += tst_treename.cpp + +RESOURCES += \ + settings.qrc \ + ..\shared\config.qrc diff --git a/tests/auto/installer/treename/tst_treename.cpp b/tests/auto/installer/treename/tst_treename.cpp new file mode 100644 index 000000000..0dc7bfa33 --- /dev/null +++ b/tests/auto/installer/treename/tst_treename.cpp @@ -0,0 +1,136 @@ +/************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ +#include "../shared/packagemanager.h" +#include "../shared/verifyinstaller.h" + +#include +#include +#include + +#include +#include + +class tst_TreeName : public QObject +{ + Q_OBJECT + +private slots: + void moveToRoot(); + void moveToSubItem(); + void dependencyToMovedItem(); + void autodependOnMovedItem(); + void moveToExistingItem(); + + void init(); + void cleanup(); + +private: + QString m_installDir; + +}; + +void tst_TreeName::moveToRoot() +{ + // componentB.sub1.sub1 moved from sub item to root (BSub1Sub1ToRoot) + PackageManagerCore *core = PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/repository"); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "componentB.sub1.sub1")); + QList installedComponents = core->orderedComponentsToInstall(); + + QCOMPARE(installedComponents.count(), 1); + QCOMPARE(installedComponents.at(0)->name(), "componentB.sub1.sub1"); + QCOMPARE(installedComponents.at(0)->treeName(), "BSub1Sub1ToRoot"); + QVERIFY(core->componentByName("componentB.sub1.sub1") != 0); + QVERIFY(core->componentByName("BSub1Sub1ToRoot") == 0); + VerifyInstaller::verifyInstallerResources(m_installDir, "componentB.sub1.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "componentBSub1Sub1.txt"); +} + +void tst_TreeName::moveToSubItem() +{ + // componentB.sub1.sub2 moved under componentC (componentC.sub1) + PackageManagerCore *core = PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/repository"); + + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "componentC")); + VerifyInstaller::verifyInstallerResources(m_installDir, "componentB.sub1.sub2", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "componentC", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "componentBSub1Sub2.txt" << "componentC.txt"); +} + +void tst_TreeName::dependencyToMovedItem() +{ + // componentA depends on componentB.sub2 which is moved to root + PackageManagerCore *core = PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/repository"); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "componentA")); + + VerifyInstaller::verifyInstallerResources(m_installDir, "componentA", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "componentA.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "componentB.sub2", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "componentA.txt" << "componentASub1.txt" << "componentBSub2.txt"); +} + +void tst_TreeName::autodependOnMovedItem() +{ + // componentD autodepends on componentA.sub2 which is moved to root + PackageManagerCore *core = PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/repository"); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "componentA.sub2")); + VerifyInstaller::verifyInstallerResources(m_installDir, "componentA.sub2", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "componentD", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "componentASub2.txt" << "componentD.txt"); +} + +void tst_TreeName::moveToExistingItem() +{ + PackageManagerCore *core = PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/invalid_repository"); + QCOMPARE(PackageManagerCore::Failure, core->installSelectedComponentsSilently(QStringList() << "componentA")); + QCOMPARE(core->error(), "Cannot register component! Component with identifier componentA.sub1 already exists."); +} + +void tst_TreeName::init() +{ + m_installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(m_installDir)); +} + +void tst_TreeName::cleanup() +{ + QDir dir(m_installDir); + QVERIFY(dir.removeRecursively()); +} + +QTEST_MAIN(tst_TreeName) + +#include "tst_treename.moc" -- cgit v1.2.3