summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKatja Marttila <katja.marttila@qt.io>2019-05-31 13:30:18 +0300
committerIikka Eklund <iikka.eklund@qt.io>2019-12-04 12:11:59 +0000
commit0842ea01554202b4552911c827417acb00a03cf1 (patch)
tree8633ef3e268a2f0064f0051755bd2e0d7ec6eb04
parentf8ade64515482e2079fde805b93ee11e3dae44f5 (diff)
Install selected packages from CLI
Also move targetDirWarning() from targetdirectorypage to packagemanager and move target directory check to checkTargetDir() function so that those are accessible also without UI. Change-Id: Ia38cc7e66bb542e6a60fea2c39cc3b80735564ef Reviewed-by: Iikka Eklund <iikka.eklund@qt.io>
-rw-r--r--src/libs/installer/globals.cpp5
-rw-r--r--src/libs/installer/globals.h1
-rw-r--r--src/libs/installer/packagemanagercore.cpp190
-rw-r--r--src/libs/installer/packagemanagercore.h5
-rw-r--r--src/libs/installer/packagemanagergui.cpp156
-rw-r--r--src/libs/installer/packagemanagergui.h2
-rw-r--r--src/sdk/commandlineparser.cpp6
-rw-r--r--src/sdk/constants.h2
-rw-r--r--src/sdk/installerbase.cpp27
9 files changed, 238 insertions, 156 deletions
diff --git a/src/libs/installer/globals.cpp b/src/libs/installer/globals.cpp
index a2177bc43..851ebd35d 100644
--- a/src/libs/installer/globals.cpp
+++ b/src/libs/installer/globals.cpp
@@ -55,6 +55,7 @@ const char IFW_PACKAGE_CHECKABLE[] = "ifw.package.checkable";
const char IFW_PACKAGE_LICENSES[] = "ifw.package.licenses";
const char IFW_PACKAGE_COMPRESSEDSIZE[] = "ifw.package.compressedsize";
const char IFW_PACKAGE_UNCOMPRESSEDSIZE[] = "ifw.package.uncompressedsize";
+const char IFW_INSTALLER_INSTALLLOG[] = "ifw.installer.installlog";
namespace QInstaller
{
@@ -85,6 +86,7 @@ Q_LOGGING_CATEGORY(lcPackageCheckable, IFW_PACKAGE_CHECKABLE)
Q_LOGGING_CATEGORY(lcPackageLicenses, IFW_PACKAGE_LICENSES)
Q_LOGGING_CATEGORY(lcPackageUncompressedSize, IFW_PACKAGE_UNCOMPRESSEDSIZE)
Q_LOGGING_CATEGORY(lcPackageCompressedSize, IFW_PACKAGE_COMPRESSEDSIZE)
+Q_LOGGING_CATEGORY(lcInstallerInstallLog, IFW_INSTALLER_INSTALLLOG)
QStringList loggingCategories()
@@ -114,7 +116,8 @@ QStringList loggingCategories()
<< QLatin1String(IFW_PACKAGE_CHECKABLE)
<< QLatin1String(IFW_PACKAGE_LICENSES)
<< QLatin1String(IFW_PACKAGE_UNCOMPRESSEDSIZE)
- << QLatin1String(IFW_PACKAGE_COMPRESSEDSIZE);
+ << QLatin1String(IFW_PACKAGE_COMPRESSEDSIZE)
+ << QLatin1String(IFW_INSTALLER_INSTALLLOG);
return categories;
}
diff --git a/src/libs/installer/globals.h b/src/libs/installer/globals.h
index d4ad78c55..ceca321ec 100644
--- a/src/libs/installer/globals.h
+++ b/src/libs/installer/globals.h
@@ -61,6 +61,7 @@ INSTALLER_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcPackageCheckable)
INSTALLER_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcPackageLicenses)
INSTALLER_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcPackageUncompressedSize)
INSTALLER_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcPackageCompressedSize)
+INSTALLER_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcInstallerInstallLog)
QStringList INSTALLER_EXPORT loggingCategories();
diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp
index ec1fff29d..8dc1018ea 100644
--- a/src/libs/installer/packagemanagercore.cpp
+++ b/src/libs/installer/packagemanagercore.cpp
@@ -834,6 +834,148 @@ QString PackageManagerCore::readFile(const QString &filePath, const QString &cod
return stream.readAll();
}
+/*!
+ Checks whether the target directory \a targetDirectory exists and has contents:
+ \list
+ \li Returns \c true if the directory exists and is empty.
+ \li Returns \c false if the directory already exists and contains an installation.
+ \li Returns \c false if the target is a file or a symbolic link.
+ \li Returns \c true or \c false if the directory exists but is not empty, depending on the
+ choice that the end users make in the displayed message box.
+ \endlist
+*/
+bool PackageManagerCore::checkTargetDir(const QString &targetDirectory)
+{
+ const QDir dir(targetDirectory);
+ // the directory exists and is empty...
+ if (dir.exists() && dir.entryList(QDir::AllEntries | QDir::NoDotAndDotDot).isEmpty())
+ return true;
+
+ const QFileInfo fi(targetDirectory);
+ if (fi.isDir()) {
+ QString fileName = settings().maintenanceToolName();
+#if defined(Q_OS_MACOS)
+ if (QInstaller::isInBundle(QCoreApplication::applicationDirPath()))
+ fileName += QLatin1String(".app/Contents/MacOS/") + fileName;
+#elif defined(Q_OS_WIN)
+ fileName += QLatin1String(".exe");
+#endif
+
+ QFileInfo fi2(targetDirectory + QDir::separator() + fileName);
+ if (fi2.exists()) {
+ MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(), QLatin1String("TargetDirectoryInUse"),
+ tr("Error"), tr("The directory you selected already "
+ "exists and contains an installation. Choose a different target for installation."));
+ return false;
+ }
+
+ QMessageBox::StandardButton bt =
+ MessageBoxHandler::warning(MessageBoxHandler::currentBestSuitParent(), QLatin1String("OverwriteTargetDirectory"),
+ tr("Warning"), tr("You have selected an existing, non-empty directory for installation.\nNote that it will be "
+ "completely wiped on uninstallation of this application.\nIt is not advisable to install into "
+ "this directory as installation might fail.\nDo you want to continue?"), QMessageBox::Yes | QMessageBox::No);
+ return bt == QMessageBox::Yes;
+ } else if (fi.isFile() || fi.isSymLink()) {
+ MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(), QLatin1String("WrongTargetDirectory"),
+ tr("Error"), tr("You have selected an existing file "
+ "or symlink, please choose a different target for installation."));
+ return false;
+ }
+ return true;
+}
+
+/*!
+ Returns a warning if the path to the target directory \a targetDirectory
+ is not set or if it is invalid.
+*/
+QString PackageManagerCore::targetDirWarning(const QString &targetDirectory) const
+{
+ if (targetDirectory.isEmpty())
+ return tr("The installation path cannot be empty, please specify a valid directory.");
+
+ QDir target(targetDirectory);
+ if (target.isRelative())
+ return tr("The installation path cannot be relative, please specify an absolute path.");
+
+ QString nativeTargetDir = QDir::toNativeSeparators(target.absolutePath());
+ if (!settings().allowNonAsciiCharacters()) {
+ for (int i = 0; i < nativeTargetDir.length(); ++i) {
+ if (nativeTargetDir.at(i).unicode() & 0xff80) {
+ return tr("The path or installation directory contains non ASCII characters. This "
+ "is currently not supported! Please choose a different path or installation "
+ "directory.");
+ }
+ }
+ }
+
+ target = target.canonicalPath();
+ if (!target.isEmpty() && (target == QDir::root() || target == QDir::home())) {
+ return tr("As the install directory is completely deleted, installing in %1 is forbidden.")
+ .arg(QDir::toNativeSeparators(target.path()));
+ }
+
+#ifdef Q_OS_WIN
+ // folder length (set by user) + maintenance tool name length (no extension) + extra padding
+ if ((nativeTargetDir.length()
+ + settings().maintenanceToolName().length() + 20) >= MAX_PATH) {
+ return tr("The path you have entered is too long, please make sure to "
+ "specify a valid path.");
+ }
+
+ static QRegularExpression reg(QLatin1String(
+ "^(?<drive>[a-zA-Z]:\\\\)|"
+ "^(\\\\\\\\(?<path>\\w+)\\\\)|"
+ "^(\\\\\\\\(?<ip>\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})\\\\)"));
+ const QRegularExpressionMatch regMatch = reg.match(nativeTargetDir);
+
+ const QString ipMatch = regMatch.captured(QLatin1String("ip"));
+ const QString pathMatch = regMatch.captured(QLatin1String("path"));
+ const QString driveMatch = regMatch.captured(QLatin1String("drive"));
+
+ if (ipMatch.isEmpty() && pathMatch.isEmpty() && driveMatch.isEmpty()) {
+ return tr("The path you have entered is not valid, please make sure to "
+ "specify a valid target.");
+ }
+
+ if (!driveMatch.isEmpty()) {
+ bool validDrive = false;
+ const QFileInfo drive(driveMatch);
+ foreach (const QFileInfo &driveInfo, QDir::drives()) {
+ if (drive == driveInfo) {
+ validDrive = true;
+ break;
+ }
+ }
+ if (!validDrive) { // right now we can only verify local drives
+ return tr("The path you have entered is not valid, please make sure to "
+ "specify a valid drive.");
+ }
+ nativeTargetDir = nativeTargetDir.mid(2);
+ }
+
+ if (nativeTargetDir.endsWith(QLatin1Char('.')))
+ return tr("The installation path must not end with '.', please specify a valid directory.");
+
+ QString ambiguousChars = QLatin1String("[\"~<>|?*!@#$%^&:,; ]"
+ "|(\\\\CON)(\\\\|$)|(\\\\PRN)(\\\\|$)|(\\\\AUX)(\\\\|$)|(\\\\NUL)(\\\\|$)|(\\\\COM\\d)(\\\\|$)|(\\\\LPT\\d)(\\\\|$)");
+#else // Q_OS_WIN
+ QString ambiguousChars = QStringLiteral("[~<>|?*!@#$%^&:,; \\\\]");
+#endif // Q_OS_WIN
+
+ if (settings().allowSpaceInPath())
+ ambiguousChars.remove(QLatin1Char(' '));
+
+ static QRegularExpression ambCharRegEx(ambiguousChars, QRegularExpression::CaseInsensitiveOption);
+ // check if there are not allowed characters in the target path
+ QRegularExpressionMatch match = ambCharRegEx.match(nativeTargetDir);
+ if (match.hasMatch()) {
+ return tr("The installation path must not contain \"%1\", "
+ "please specify a valid directory.").arg(match.captured(0));
+ }
+
+ return QString();
+}
+
// -- QInstaller
/*!
@@ -1927,6 +2069,54 @@ void PackageManagerCore::updateComponentsSilently(const QStringList &componentsT
}
/*!
+ Installs selected components \a components without user interface. Virtual components
+ cannot be installed unless made visible with --show-virtual-components. AutoDependOn
+ nor non-checkable components cannot be installed directly.
+*/
+void PackageManagerCore::installSelectedComponentsSilently(const QStringList& components)
+{
+ // Check if there are processes running in the install if maintenancetool is in used.
+ if (!isInstaller()) {
+ if (d->runningProcessesFound())
+ return;
+ setPackageManager();
+ }
+
+ ComponentModel *model = defaultComponentModel();
+ fetchRemotePackagesTree();
+
+ bool installComponentsFound = false;
+ foreach (const QString &name, components){
+ const QModelIndex &idx = model->indexFromComponentName(name);
+ Component *component = componentByName(name);
+ if (idx.isValid()) {
+ if (model->data(idx, Qt::CheckStateRole) == QVariant::Invalid) { // User cannot select the component, check why
+ if (component && component->autoDependencies().count() > 0)
+ qCDebug(QInstaller::lcInstallerInstallLog) << "Cannot install component "<< name
+ << "Component is installed only as automatic dependency to "<< component->autoDependencies().join(QLatin1Char(','));
+ if (component && !component->isCheckable())
+ qCDebug(QInstaller::lcInstallerInstallLog) << "Cannot install component "<< name
+ <<". Component is not checkable meaning you have to select one of the subcomponents.";
+ } else if (model->data(idx, Qt::CheckStateRole) == Qt::Checked ) {
+ qCDebug(QInstaller::lcInstallerInstallLog) << "Component " << name <<" already installed";
+ } else {
+ model->setData(idx, Qt::Checked, Qt::CheckStateRole);
+ installComponentsFound = true;
+ }
+ } else { // idx is invalid and component valid when we have invisible virtual component
+ if (component && component->isVirtual())
+ qCDebug(QInstaller::lcInstallerInstallLog) << "Cannot install " << name <<". Component is virtual.";
+ else
+ qCDebug(QInstaller::lcInstallerInstallLog) << "Cannot install " << name <<". Component not found.";
+ }
+ }
+ if (installComponentsFound) {
+ if (d->calculateComponentsAndRun())
+ qCDebug(QInstaller::lcInstallerInstallLog) << "Components installed successfully";
+ }
+}
+
+/*!
Returns the settings for the package manager.
*/
Settings &PackageManagerCore::settings() const
diff --git a/src/libs/installer/packagemanagercore.h b/src/libs/installer/packagemanagercore.h
index d9e953882..86760e8be 100644
--- a/src/libs/installer/packagemanagercore.h
+++ b/src/libs/installer/packagemanagercore.h
@@ -199,6 +199,9 @@ public:
Q_INVOKABLE bool fileExists(const QString &filePath) const;
Q_INVOKABLE QString readFile(const QString &filePath, const QString &codecName) const;
+ bool checkTargetDir(const QString &targetDirectory);
+ QString targetDirWarning(const QString &targetDirectory) const;
+
public:
ScriptEngine *componentScriptEngine() const;
ScriptEngine *controlScriptEngine() const;
@@ -228,6 +231,8 @@ public:
void listInstalledPackages();
void listAvailablePackages(const QString &regexp);
void updateComponentsSilently(const QStringList &componentsToUpdate);
+ void installSelectedComponentsSilently(const QStringList& components);
+
// convenience
Q_INVOKABLE bool isInstaller() const;
Q_INVOKABLE bool isOfflineOnly() const;
diff --git a/src/libs/installer/packagemanagergui.cpp b/src/libs/installer/packagemanagergui.cpp
index 934570ae1..a20290ef7 100644
--- a/src/libs/installer/packagemanagergui.cpp
+++ b/src/libs/installer/packagemanagergui.cpp
@@ -2145,15 +2145,7 @@ void TargetDirectoryPage::initializePage()
}
/*!
- Checks whether the target directory exists and has contents:
-
- \list
- \li Returns \c true if the directory exists and is empty.
- \li Returns \c false if the directory already exists and contains an installation.
- \li Returns \c false if the target is a file or a symbolic link.
- \li Returns \c true or \c false if the directory exists but is not empty, depending on the
- choice that the end users make in the displayed message box.
- \endlist
+ Checks whether the target directory exists and has correct content.
*/
bool TargetDirectoryPage::validatePage()
{
@@ -2169,37 +2161,7 @@ bool TargetDirectoryPage::validatePage()
if (!QVariant(remove).toBool())
return true;
- const QString targetDir = this->targetDir();
- const QDir dir(targetDir);
- // the directory exists and is empty...
- if (dir.exists() && dir.entryList(QDir::AllEntries | QDir::NoDotAndDotDot).isEmpty())
- return true;
-
- const QFileInfo fi(targetDir);
- if (fi.isDir()) {
- QString fileName = packageManagerCore()->settings().maintenanceToolName();
-#if defined(Q_OS_MACOS)
- if (QInstaller::isInBundle(QCoreApplication::applicationDirPath()))
- fileName += QLatin1String(".app/Contents/MacOS/") + fileName;
-#elif defined(Q_OS_WIN)
- fileName += QLatin1String(".exe");
-#endif
-
- QFileInfo fi2(targetDir + QDir::separator() + fileName);
- if (fi2.exists()) {
- return failWithError(QLatin1String("TargetDirectoryInUse"), tr("The directory you selected already "
- "exists and contains an installation. Choose a different target for installation."));
- }
-
- return askQuestion(QLatin1String("OverwriteTargetDirectory"),
- tr("You have selected an existing, non-empty directory for installation.\nNote that it will be "
- "completely wiped on uninstallation of this application.\nIt is not advisable to install into "
- "this directory as installation might fail.\nDo you want to continue?"));
- } else if (fi.isFile() || fi.isSymLink()) {
- return failWithError(QLatin1String("WrongTargetDirectory"), tr("You have selected an existing file "
- "or symlink, please choose a different target for installation."));
- }
- return true;
+ return this->packageManagerCore()->checkTargetDir(targetDir());
}
/*!
@@ -2238,122 +2200,10 @@ void TargetDirectoryPage::dirRequested()
*/
bool TargetDirectoryPage::isComplete() const
{
- m_warningLabel->setText(targetDirWarning());
+ m_warningLabel->setText(packageManagerCore()->targetDirWarning(targetDir()));
return m_warningLabel->text().isEmpty();
}
-/*!
- Returns a warning if the path to the target directory is not set or if it
- is invalid. Installation can continue only after a valid target path is given.
-*/
-QString TargetDirectoryPage::targetDirWarning() const
-{
- if (targetDir().isEmpty())
- return tr("The installation path cannot be empty, please specify a valid directory.");
-
- QDir target(targetDir());
- if (target.isRelative())
- return tr("The installation path cannot be relative, please specify an absolute path.");
-
- QString nativeTargetDir = QDir::toNativeSeparators(target.absolutePath());
- if (!packageManagerCore()->settings().allowNonAsciiCharacters()) {
- for (int i = 0; i < nativeTargetDir.length(); ++i) {
- if (nativeTargetDir.at(i).unicode() & 0xff80) {
- return tr("The path or installation directory contains non ASCII characters. This "
- "is currently not supported! Please choose a different path or installation "
- "directory.");
- }
- }
- }
-
- target = target.canonicalPath();
- if (!target.isEmpty() && (target == QDir::root() || target == QDir::home())) {
- return tr("As the install directory is completely deleted, installing in %1 is forbidden.")
- .arg(QDir::toNativeSeparators(target.path()));
- }
-
-#ifdef Q_OS_WIN
- // folder length (set by user) + maintenance tool name length (no extension) + extra padding
- if ((nativeTargetDir.length()
- + packageManagerCore()->settings().maintenanceToolName().length() + 20) >= MAX_PATH) {
- return tr("The path you have entered is too long, please make sure to "
- "specify a valid path.");
- }
-
- static QRegularExpression reg(QLatin1String(
- "^(?<drive>[a-zA-Z]:\\\\)|"
- "^(\\\\\\\\(?<path>\\w+)\\\\)|"
- "^(\\\\\\\\(?<ip>\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})\\\\)"));
- const QRegularExpressionMatch regMatch = reg.match(nativeTargetDir);
-
- const QString ipMatch = regMatch.captured(QLatin1String("ip"));
- const QString pathMatch = regMatch.captured(QLatin1String("path"));
- const QString driveMatch = regMatch.captured(QLatin1String("drive"));
-
- if (ipMatch.isEmpty() && pathMatch.isEmpty() && driveMatch.isEmpty()) {
- return tr("The path you have entered is not valid, please make sure to "
- "specify a valid target.");
- }
-
- if (!driveMatch.isEmpty()) {
- bool validDrive = false;
- const QFileInfo drive(driveMatch);
- foreach (const QFileInfo &driveInfo, QDir::drives()) {
- if (drive == driveInfo) {
- validDrive = true;
- break;
- }
- }
- if (!validDrive) { // right now we can only verify local drives
- return tr("The path you have entered is not valid, please make sure to "
- "specify a valid drive.");
- }
- nativeTargetDir = nativeTargetDir.mid(2);
- }
-
- if (nativeTargetDir.endsWith(QLatin1Char('.')))
- return tr("The installation path must not end with '.', please specify a valid directory.");
-
- QString ambiguousChars = QLatin1String("[\"~<>|?*!@#$%^&:,; ]"
- "|(\\\\CON)(\\\\|$)|(\\\\PRN)(\\\\|$)|(\\\\AUX)(\\\\|$)|(\\\\NUL)(\\\\|$)|(\\\\COM\\d)(\\\\|$)|(\\\\LPT\\d)(\\\\|$)");
-#else // Q_OS_WIN
- QString ambiguousChars = QStringLiteral("[~<>|?*!@#$%^&:,; \\\\]");
-#endif // Q_OS_WIN
-
- if (packageManagerCore()->settings().allowSpaceInPath())
- ambiguousChars.remove(QLatin1Char(' '));
-
- static QRegularExpression ambCharRegEx(ambiguousChars, QRegularExpression::CaseInsensitiveOption);
- // check if there are not allowed characters in the target path
- QRegularExpressionMatch match = ambCharRegEx.match(nativeTargetDir);
- if (match.hasMatch()) {
- return tr("The installation path must not contain \"%1\", "
- "please specify a valid directory.").arg(match.captured(0));
- }
-
- return QString();
-}
-
-/*!
- Returns \c true if a warning message specified by \a message with the
- identifier \a identifier is presented to end users for acknowledgment.
-*/
-bool TargetDirectoryPage::askQuestion(const QString &identifier, const QString &message)
-{
- QMessageBox::StandardButton bt =
- MessageBoxHandler::warning(MessageBoxHandler::currentBestSuitParent(), identifier,
- tr("Warning"), message, QMessageBox::Yes | QMessageBox::No);
- return bt == QMessageBox::Yes;
-}
-
-bool TargetDirectoryPage::failWithError(const QString &identifier, const QString &message)
-{
- MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(), identifier,
- tr("Error"), message);
- return false;
-}
-
-
// -- StartMenuDirectoryPage
/*!
diff --git a/src/libs/installer/packagemanagergui.h b/src/libs/installer/packagemanagergui.h
index b233086c3..df47df44e 100644
--- a/src/libs/installer/packagemanagergui.h
+++ b/src/libs/installer/packagemanagergui.h
@@ -352,8 +352,6 @@ private Q_SLOTS:
private:
QString targetDirWarning() const;
- bool askQuestion(const QString &identifier, const QString &message);
- bool failWithError(const QString &identifier, const QString &message);
private:
QLineEdit *m_lineEdit;
diff --git a/src/sdk/commandlineparser.cpp b/src/sdk/commandlineparser.cpp
index 7f833417c..493a77866 100644
--- a/src/sdk/commandlineparser.cpp
+++ b/src/sdk/commandlineparser.cpp
@@ -124,10 +124,16 @@ CommandLineParser::CommandLineParser()
QLatin1String("Lists installed packages.")));
m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::ListPackages),
QLatin1String("Lists available packages."), QLatin1String("regexp")));
+ m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::InstallPackages),
+ QLatin1String("Install selected packages"),
+ QLatin1String("package,...")));
m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::Platform),
QLatin1String("Use the specified platform plugin."), QLatin1String("plugin")));
m_parser.addPositionalArgument(QLatin1String(CommandLineOptions::KeyValue),
QLatin1String("Key Value pair to be set."));
+ m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::TargetDir),
+ QLatin1String("Set install directory"),
+ QLatin1String("directory")));
m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::SquishPort),
QLatin1String("Give a port where Squish can connect to. If no port is given, default "
"port 11233 is used. Note: To enable Squish support you first need to build IFW with "
diff --git a/src/sdk/constants.h b/src/sdk/constants.h
index 0c3b2edc9..0cdf36bf4 100644
--- a/src/sdk/constants.h
+++ b/src/sdk/constants.h
@@ -57,6 +57,8 @@ const char SilentUpdate[] = "silentUpdate";
const char UpdatePackages[] = "updatePackages";
const char ListInstalledPackages[] = "listInstalledPackages";
const char ListPackages[] = "listPackages";
+const char InstallPackages[] = "installPackages";
+const char TargetDir[] = "targetDir";
const char Platform[] = "platform";
const char SquishPort[] = "squish-port";
diff --git a/src/sdk/installerbase.cpp b/src/sdk/installerbase.cpp
index 09cc547d2..e32b4f127 100644
--- a/src/sdk/installerbase.cpp
+++ b/src/sdk/installerbase.cpp
@@ -341,6 +341,33 @@ int InstallerBase::run()
if (!value.isEmpty())
packages = value.split(QLatin1Char(','), QString::SkipEmptyParts);
m_core->updateComponentsSilently(packages);
+ } else if (parser.isSet(QLatin1String(CommandLineOptions::InstallPackages))) {
+ checkLicense();
+ m_core->autoRejectMessageBoxes();
+ if (m_core->isInstaller()) {
+ if (parser.isSet(QLatin1String(CommandLineOptions::TargetDir))) {
+ const QString &value = parser.value(QLatin1String(CommandLineOptions::TargetDir));
+ if (m_core->checkTargetDir(value)) {
+ QString targetDirWarning = m_core->targetDirWarning(value);
+ if (!targetDirWarning.isEmpty()) {
+ qDebug() << m_core->targetDirWarning(value);
+ return EXIT_FAILURE;
+ }
+ m_core->setValue(QLatin1String("TargetDir"), value);
+ } else {
+ return EXIT_FAILURE;
+ }
+ } else {
+ qWarning() << "Please specify target directory.";
+ return EXIT_FAILURE;
+ }
+ }
+
+ QStringList packages;
+ const QString &value = parser.value(QLatin1String(CommandLineOptions::InstallPackages));
+ if (!value.isEmpty())
+ packages = value.split(QLatin1Char(','), QString::SkipEmptyParts);
+ m_core->installSelectedComponentsSilently(packages);
} else {
//create the wizard GUI
TabController controller(nullptr);