From 21aef7e78341b1931ca029dda5e5118172bdaafa Mon Sep 17 00:00:00 2001 From: Arttu Tarkiainen Date: Mon, 30 Mar 2020 16:42:21 +0300 Subject: Remove existing installation from command line Add new "purge" command to command line interface. This removes all components and all program directory contents. Add test function to unit tests. Task-number: QTIFW-1574 Change-Id: Iccd4a052c7e2fc8eec0a6ae2b5a93c0c607604cb Reviewed-by: Leena Miettinen Reviewed-by: Katja Marttila --- src/libs/installer/commandlineparser.cpp | 6 ++++-- src/libs/installer/constants.h | 6 +++++- src/libs/installer/packagemanagercore.cpp | 16 +++++++++++++++ src/libs/installer/packagemanagercore.h | 1 + src/sdk/commandlineinterface.cpp | 17 +++++++++++++++ src/sdk/commandlineinterface.h | 1 + src/sdk/main.cpp | 3 +++ .../installer/cliinterface/tst_cliinterface.cpp | 24 ++++++++++++++++++++++ 8 files changed, 71 insertions(+), 3 deletions(-) diff --git a/src/libs/installer/commandlineparser.cpp b/src/libs/installer/commandlineparser.cpp index c82dde944..8c0fb1ee7 100644 --- a/src/libs/installer/commandlineparser.cpp +++ b/src/libs/installer/commandlineparser.cpp @@ -53,8 +53,10 @@ CommandLineParser::CommandLineParser() .arg(CommandLineOptions::scRemoveShort, CommandLineOptions::scRemoveLong) + QString::fromLatin1("\t%1, %2 - list currently installed packages\n") .arg(CommandLineOptions::scListShort, CommandLineOptions::scListLong) - + QString::fromLatin1("\t%1, %2 - search available packages - ") - .arg(CommandLineOptions::scSearchShort, CommandLineOptions::scSearchLong); + + QString::fromLatin1("\t%1, %2 - search available packages - \n") + .arg(CommandLineOptions::scSearchShort, CommandLineOptions::scSearchLong) + + QString::fromLatin1("\t%1, %2 - uninstall all packages and remove entire program directory") + .arg(CommandLineOptions::scPurgeShort, CommandLineOptions::scPurgeLong); m_parser.setApplicationDescription(preformatted); diff --git a/src/libs/installer/constants.h b/src/libs/installer/constants.h index 37eb9600a..8f3291b04 100644 --- a/src/libs/installer/constants.h +++ b/src/libs/installer/constants.h @@ -124,6 +124,8 @@ static const QLatin1String scListShort("li"); static const QLatin1String scListLong("list"); static const QLatin1String scSearchShort("se"); static const QLatin1String scSearchLong("search"); +static const QLatin1String scPurgeShort("pr"); +static const QLatin1String scPurgeLong("purge"); // Repository management options static const QLatin1String scAddRepositoryShort("ar"); @@ -186,7 +188,9 @@ static const QStringList scCommandLineInterfaceOptions = { scListShort, scListLong, scSearchShort, - scSearchLong + scSearchLong, + scPurgeShort, + scPurgeLong }; } // namespace CommandLineOptions diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp index 55a143ceb..0a5eec513 100644 --- a/src/libs/installer/packagemanagercore.cpp +++ b/src/libs/installer/packagemanagercore.cpp @@ -2218,6 +2218,22 @@ bool PackageManagerCore::uninstallComponentsSilently(const QStringList& componen return false; } +/*! + Uninstalls all installed components without GUI and removes + the program directory. Returns \c true if components are + uninstalled successfully, otherwise returns \c false. +*/ +bool PackageManagerCore::removeInstallationSilently() +{ + if (d->runningProcessesFound()) + throw Error(tr("Running processes found.")); + + autoRejectMessageBoxes(); + + setCompleteUninstallation(true); + return run(); +} + /*! Installs the selected components \a components without displaying a user interface. Virtual components cannot be installed unless made visible with diff --git a/src/libs/installer/packagemanagercore.h b/src/libs/installer/packagemanagercore.h index 82ab779c3..979ff50e6 100644 --- a/src/libs/installer/packagemanagercore.h +++ b/src/libs/installer/packagemanagercore.h @@ -221,6 +221,7 @@ public: bool installSelectedComponentsSilently(const QStringList& components); bool installDefaultComponentsSilently(); bool uninstallComponentsSilently(const QStringList& components); + bool removeInstallationSilently(); // convenience Q_INVOKABLE void setInstaller(); diff --git a/src/sdk/commandlineinterface.cpp b/src/sdk/commandlineinterface.cpp index de9332b35..f64f41834 100644 --- a/src/sdk/commandlineinterface.cpp +++ b/src/sdk/commandlineinterface.cpp @@ -193,6 +193,23 @@ int CommandLineInterface::uninstallPackages() } } +int CommandLineInterface::removeInstallation() +{ + if (!initialize()) + return EXIT_FAILURE; + if (m_core->isInstaller()) { + qCWarning(QInstaller::lcInstallerInstallLog) << "Cannot uninstall packages with installer."; + return EXIT_FAILURE; + } + m_core->setUninstaller(); + try { + return m_core->removeInstallationSilently() ? EXIT_SUCCESS : EXIT_FAILURE; + } catch (const QInstaller::Error &err) { + qCCritical(QInstaller::lcInstallerInstallLog) << err.message(); + return EXIT_FAILURE; + } +} + bool CommandLineInterface::checkLicense() { const ProductKeyCheck *const productKeyCheck = ProductKeyCheck::instance(); diff --git a/src/sdk/commandlineinterface.h b/src/sdk/commandlineinterface.h index efdbb54c8..7b5053253 100644 --- a/src/sdk/commandlineinterface.h +++ b/src/sdk/commandlineinterface.h @@ -44,6 +44,7 @@ public: int updatePackages(); int installPackages(); int uninstallPackages(); + int removeInstallation(); private: bool initialize(); diff --git a/src/sdk/main.cpp b/src/sdk/main.cpp index b6f2209ed..70214a9c5 100644 --- a/src/sdk/main.cpp +++ b/src/sdk/main.cpp @@ -244,6 +244,9 @@ int main(int argc, char *argv[]) } else if (parser.positionalArguments().contains(CommandLineOptions::scRemoveShort) || parser.positionalArguments().contains(CommandLineOptions::scRemoveLong)){ return CommandLineInterface(argc, argv).uninstallPackages(); + } else if (parser.positionalArguments().contains(CommandLineOptions::scPurgeShort) + || parser.positionalArguments().contains(CommandLineOptions::scPurgeLong)){ + return CommandLineInterface(argc, argv).removeInstallation(); } if (QInstaller::isVerbose()) std::cout << VERSION << std::endl << BUILDDATE << std::endl << SHA << std::endl; diff --git a/tests/auto/installer/cliinterface/tst_cliinterface.cpp b/tests/auto/installer/cliinterface/tst_cliinterface.cpp index 527d8295e..c38e0c850 100644 --- a/tests/auto/installer/cliinterface/tst_cliinterface.cpp +++ b/tests/auto/installer/cliinterface/tst_cliinterface.cpp @@ -206,6 +206,30 @@ private slots: VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" << "installcontentE.txt"); } + void testRemoveAllSilently() + { + QInstaller::init(); //This will eat debug output + PackageManagerCore &core = initPackagemanager(":///data/installPackagesRepository"); + core.installSelectedComponentsSilently(QStringList() << QLatin1String("componentA")); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" << "installcontentE.txt" + << "installcontentA.txt" << "installcontent.txt" << "installcontentG.txt"); + + core.commitSessionOperations(); + core.setUninstaller(); + QVERIFY(core.removeInstallationSilently()); + VerifyInstaller::verifyInstallerResourcesDeletion(m_installDir, "componentA"); + VerifyInstaller::verifyInstallerResourcesDeletion(m_installDir, "componentE"); + VerifyInstaller::verifyInstallerResourcesDeletion(m_installDir, "componentG"); + + // On Windows we have to settle for the resources check above as maintenance + // tool (if it would exists) and target directory are only removed later via + // started VBScript process. On Unix platforms the target directory should + // be removed in PackageManagerCorePrivate::runUninstaller(). +#if defined(Q_OS_UNIX) + QVERIFY(!QDir(m_installDir).exists()); +#endif + } + void testInstallWithDependencySilently() { QInstaller::init(); //This will eat debug output -- cgit v1.2.3