McuSupport: Detect dependency versions when building MCU kits

Task-number: QTCREATORBUG-25261
Change-Id: I79d24aa2e26a3f647bd2251c0407c7d09eea73b3
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: Dawid Śliwa <dawid.sliwa@qt.io>
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
Christiaan Janssen
2021-02-15 16:20:38 +01:00
committed by christiaan.janssen
parent 3cb6d17d5a
commit 3e08210998
9 changed files with 365 additions and 32 deletions

View File

@@ -11,4 +11,5 @@ add_qtc_plugin(McuSupport
mcusupportplugin.cpp mcusupportplugin.h
mcusupportsdk.cpp mcusupportsdk.h
mcusupportrunconfiguration.cpp mcusupportrunconfiguration.h
mcusupportversiondetection.cpp mcusupportversiondetection.h
)

View File

@@ -12,7 +12,8 @@ HEADERS += \
mcusupportoptionspage.h \
mcusupportplugin.h \
mcusupportsdk.h \
mcusupportrunconfiguration.h
mcusupportrunconfiguration.h \
mcusupportversiondetection.h
SOURCES += \
mcusupportdevice.cpp \
@@ -20,7 +21,8 @@ SOURCES += \
mcusupportoptionspage.cpp \
mcusupportplugin.cpp \
mcusupportsdk.cpp \
mcusupportrunconfiguration.cpp
mcusupportrunconfiguration.cpp \
mcusupportversiondetection.cpp
RESOURCES += \
mcusupport.qrc

View File

@@ -30,5 +30,7 @@ QtcPlugin {
"mcusupportsdk.h",
"mcusupportrunconfiguration.cpp",
"mcusupportrunconfiguration.h",
"mcusupportversiondetection.cpp",
"mcusupportversiondetection.h",
]
}

View File

@@ -96,11 +96,13 @@ static bool kitNeedsQtVersion()
}
McuPackage::McuPackage(const QString &label, const QString &defaultPath,
const QString &detectionPath, const QString &settingsKey)
const QString &detectionPath, const QString &settingsKey,
const McuPackageVersionDetector *versionDetector)
: m_label(label)
, m_defaultPath(packagePathFromSettings(settingsKey, QSettings::SystemScope, defaultPath))
, m_detectionPath(detectionPath)
, m_settingsKey(settingsKey)
, m_versionDetector(versionDetector)
{
m_path = packagePathFromSettings(settingsKey, QSettings::UserScope, m_defaultPath);
m_automaticKitCreation = automaticKitCreationFromSettings(QSettings::UserScope);
@@ -182,6 +184,11 @@ McuPackage::Status McuPackage::status() const
return m_status;
}
bool McuPackage::validStatus() const
{
return m_status == McuPackage::ValidPackage || m_status == McuPackage::ValidPackageMismatchedVersion;
}
void McuPackage::setDownloadUrl(const QString &url)
{
m_downloadUrl = url;
@@ -227,6 +234,11 @@ void McuPackage::setRelativePathModifier(const QString &path)
m_relativePathModifier = path;
}
void McuPackage::setVersions(const QVector<QString> &versions)
{
m_versions = versions;
}
bool McuPackage::automaticKitCreationEnabled() const
{
return m_automaticKitCreation;
@@ -249,34 +261,59 @@ void McuPackage::updateStatus()
bool validPath = !m_path.isEmpty() && FilePath::fromString(m_path).exists();
const FilePath detectionPath = FilePath::fromString(basePath() + "/" + m_detectionPath);
const bool validPackage = m_detectionPath.isEmpty() || detectionPath.exists();
m_detectedVersion = validPath && validPackage && m_versionDetector ? m_versionDetector->parseVersion(basePath()) : QString();
const bool validVersion = m_detectedVersion.isEmpty() ||
m_versions.isEmpty() || m_versions.contains(m_detectedVersion);
m_status = validPath ? (validPackage ? ValidPackage : ValidPathInvalidPackage) :
m_path.isEmpty() ? EmptyPath : InvalidPath;
m_status = validPath ?
( validPackage ?
(validVersion ? ValidPackage : ValidPackageMismatchedVersion)
: ValidPathInvalidPackage )
: m_path.isEmpty() ? EmptyPath : InvalidPath;
emit statusChanged();
}
void McuPackage::updateStatusUi()
{
m_infoLabel->setType(m_status == ValidPackage ? InfoLabel::Ok : InfoLabel::NotOk);
m_infoLabel->setType(validStatus() ? InfoLabel::Ok : InfoLabel::NotOk);
m_infoLabel->setText(statusText());
}
QString McuPackage::statusText() const
{
const QString displayPackagePath = FilePath::fromString(m_path).toUserOutput();
const QString displayDetectionPath = FilePath::fromString(m_detectionPath).toUserOutput();
const QString displayVersions = m_versions.isEmpty() ? "" :
QString(" (%1)").arg(QStringList(m_versions.toList()).join(" / "));
const QString displayRequiredPath = QString("%1 %2").arg(
FilePath::fromString(m_detectionPath).toUserOutput(),
displayVersions);
const QString displayDetectedPath = QString("%1 %2").arg(
FilePath::fromString(m_detectionPath).toUserOutput(),
m_detectedVersion);
QString response;
switch (m_status) {
case ValidPackage:
response = m_detectionPath.isEmpty()
? ( m_detectedVersion.isEmpty()
? tr("Path %1 exists.").arg(displayPackagePath)
: tr("Path %1 exists. Version %2 was found.")
.arg(displayPackagePath, m_detectedVersion) )
: tr("Path %1 is valid, %2 was found.")
.arg(displayPackagePath, displayDetectionPath);
.arg(displayPackagePath, displayDetectedPath);
break;
case ValidPackageMismatchedVersion: {
const QString versionWarning = m_versions.size() == 1 ?
tr("version %1 is recommended").arg(m_versions.first()) :
tr("versions %1 are recommended").arg(displayVersions);
response = tr("Path %1 is valid, %2 was found, but %3.")
.arg(displayPackagePath, displayDetectedPath, versionWarning);
break;
}
case ValidPathInvalidPackage:
response = tr("Path %1 exists, but does not contain %2.")
.arg(displayPackagePath, displayDetectionPath);
.arg(displayPackagePath, displayRequiredPath);
break;
case InvalidPath:
response = tr("Path %1 does not exist.").arg(displayPackagePath);
@@ -285,7 +322,7 @@ QString McuPackage::statusText() const
response = m_detectionPath.isEmpty()
? tr("Path is empty.")
: tr("Path is empty, %1 not found.")
.arg(displayDetectionPath);
.arg(displayRequiredPath);
break;
}
return response;
@@ -295,8 +332,9 @@ McuToolChainPackage::McuToolChainPackage(const QString &label,
const QString &defaultPath,
const QString &detectionPath,
const QString &settingsKey,
McuToolChainPackage::Type type)
: McuPackage(label, defaultPath, detectionPath, settingsKey)
McuToolChainPackage::Type type,
const McuPackageVersionDetector *versionDetector)
: McuPackage(label, defaultPath, detectionPath, settingsKey, versionDetector)
, m_type(type)
{
}
@@ -484,9 +522,9 @@ McuTarget::Platform McuTarget::platform() const
bool McuTarget::isValid() const
{
return !Utils::anyOf(packages(), [](McuPackage *package) {
return Utils::allOf(packages(), [](McuPackage *package) {
package->updateStatus();
return package->status() != McuPackage::ValidPackage;
return package->validStatus();
});
}
@@ -494,12 +532,18 @@ void McuTarget::printPackageProblems() const
{
for (auto package: packages()) {
package->updateStatus();
if (package->status() != McuPackage::ValidPackage)
printMessage(QString("Error creating kit for target %1, package %2: %3").arg(
if (!package->validStatus())
printMessage(tr("Error creating kit for target %1, package %2: %3").arg(
McuSupportOptions::kitName(this),
package->label(),
package->statusText()),
true);
if (package->status() == McuPackage::ValidPackageMismatchedVersion)
printMessage(tr("Warning creating kit for target %1, package %2: %3").arg(
McuSupportOptions::kitName(this),
package->label(),
package->statusText()),
false);
}
}
@@ -598,7 +642,7 @@ void McuSupportOptions::setQulDir(const FilePath &dir)
{
deletePackagesAndTargets();
qtForMCUsSdkPackage->updateStatus();
if (qtForMCUsSdkPackage->status() == McuPackage::Status::ValidPackage)
if (qtForMCUsSdkPackage->validStatus())
Sdk::targetsAndPackages(dir, &packages, &mcuTargets);
for (auto package : qAsConst(packages))
connect(package, &McuPackage::changed, this, &McuSupportOptions::changed);
@@ -858,7 +902,7 @@ void McuSupportOptions::createAutomaticKits()
const auto createKits = [qtForMCUsPackage]() {
if (qtForMCUsPackage->automaticKitCreationEnabled()) {
qtForMCUsPackage->updateStatus();
if (qtForMCUsPackage->status() != McuPackage::ValidPackage) {
if (!qtForMCUsPackage->validStatus()) {
switch (qtForMCUsPackage->status()) {
case McuPackage::ValidPathInvalidPackage: {
const QString displayPath = FilePath::fromString(qtForMCUsPackage->detectionPath())
@@ -900,7 +944,6 @@ void McuSupportOptions::createAutomaticKits()
if (existingKits(target).isEmpty()) {
if (target->isValid())
newKit(target, qtForMCUsPackage);
else
target->printPackageProblems();
}

View File

@@ -25,6 +25,8 @@
#pragma once
#include "mcusupportversiondetection.h"
#include <utils/id.h>
#include <QObject>
@@ -58,11 +60,13 @@ public:
EmptyPath,
InvalidPath,
ValidPathInvalidPackage,
ValidPackageMismatchedVersion,
ValidPackage
};
McuPackage(const QString &label, const QString &defaultPath, const QString &detectionPath,
const QString &settingsKey);
McuPackage(const QString &label, const QString &defaultPath,
const QString &detectionPath, const QString &settingsKey,
const McuPackageVersionDetector *versionDetector = nullptr);
virtual ~McuPackage() = default;
QString basePath() const;
@@ -74,6 +78,7 @@ public:
void updateStatus();
Status status() const;
bool validStatus() const;
void setDownloadUrl(const QString &url);
void setEnvironmentVariableName(const QString &name);
void setAddToPath(bool addToPath);
@@ -81,6 +86,7 @@ public:
void writeGeneralSettings() const;
void writeToSettings() const;
void setRelativePathModifier(const QString &path);
void setVersions(const QVector<QString> &versions);
bool automaticKitCreationEnabled() const;
void setAutomaticKitCreationEnabled(const bool enabled);
@@ -105,9 +111,12 @@ private:
const QString m_defaultPath;
const QString m_detectionPath;
const QString m_settingsKey;
const McuPackageVersionDetector *m_versionDetector;
QString m_path;
QString m_relativePathModifier; // relative path to m_path to be returned by path()
QString m_detectedVersion;
QVector<QString> m_versions;
QString m_downloadUrl;
QString m_environmentVariableName;
bool m_addToPath = false;
@@ -133,7 +142,9 @@ public:
const QString &defaultPath,
const QString &detectionPath,
const QString &settingsKey,
Type type);
Type type,
const McuPackageVersionDetector *versionDetector = nullptr
);
Type type() const;
bool isDesktopToolchain() const;

View File

@@ -185,7 +185,7 @@ void McuSupportOptionsWidget::updateStatus()
{
m_qtForMCUsSdkGroupBox->setVisible(cMakeAvailable);
const bool valid = cMakeAvailable &&
m_options.qtForMCUsSdkPackage->status() == McuPackage::ValidPackage;
m_options.qtForMCUsSdkPackage->validStatus();
const bool ready = valid && mcuTarget;
m_mcuTargetsGroupBox->setVisible(ready);
m_packagesGroupBox->setVisible(ready && !mcuTarget->packages().isEmpty());

View File

@@ -26,6 +26,7 @@
#include "mcusupportconstants.h"
#include "mcusupportoptions.h"
#include "mcusupportsdk.h"
#include "mcusupportversiondetection.h"
#include <baremetal/baremetalconstants.h>
#include <projectexplorer/toolchain.h>
@@ -107,12 +108,20 @@ static McuToolChainPackage *createArmGccPackage()
if (defaultPath.isEmpty())
defaultPath = QDir::homePath();
const QString detectionPath = Utils::HostOsInfo::withExecutableSuffix("bin/arm-none-eabi-g++");
const auto versionDetector = new McuPackageExecutableVersionDetector(
detectionPath,
{ "--version" },
"\\b(\\d+\\.\\d+\\.\\d+)\\b"
);
auto result = new McuToolChainPackage(
McuPackage::tr("GNU Arm Embedded Toolchain"),
defaultPath,
Utils::HostOsInfo::withExecutableSuffix("bin/arm-none-eabi-g++"),
detectionPath,
"GNUArmEmbeddedToolchain",
McuToolChainPackage::TypeArmGcc);
McuToolChainPackage::TypeArmGcc,
versionDetector);
result->setEnvironmentVariableName(envVar);
return result;
}
@@ -124,12 +133,19 @@ static McuToolChainPackage *createGhsToolchainPackage()
const QString defaultPath =
qEnvironmentVariableIsSet(envVar) ? qEnvironmentVariable(envVar) : QDir::homePath();
const auto versionDetector = new McuPackageExecutableVersionDetector(
Utils::HostOsInfo::withExecutableSuffix("as850"),
{"-V"},
"\\bv(\\d+\\.\\d+\\.\\d+)\\b"
);
auto result = new McuToolChainPackage(
"Green Hills Compiler",
defaultPath,
Utils::HostOsInfo::withExecutableSuffix("ccv850"),
"GHSToolchain",
McuToolChainPackage::TypeGHS);
McuToolChainPackage::TypeGHS,
versionDetector);
result->setEnvironmentVariableName(envVar);
return result;
}
@@ -154,12 +170,20 @@ static McuToolChainPackage *createIarToolChainPackage()
defaultPath = QDir::homePath();
}
const QString detectionPath = Utils::HostOsInfo::withExecutableSuffix("bin/iccarm");
const auto versionDetector = new McuPackageExecutableVersionDetector(
detectionPath,
{"--version"},
"\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b"
);
auto result = new McuToolChainPackage(
"IAR ARM Compiler",
defaultPath,
Utils::HostOsInfo::withExecutableSuffix("bin/iccarm"),
detectionPath,
"IARToolchain",
McuToolChainPackage::TypeIAR);
McuToolChainPackage::TypeIAR,
versionDetector);
result->setEnvironmentVariableName(envVar);
return result;
}
@@ -257,14 +281,30 @@ struct McuTargetDescription
QString platformVendor;
QVector<int> colorDepths;
QString toolchainId;
QVector<QString> toolchainVersions;
QString boardSdkEnvVar;
QString boardSdkName;
QString boardSdkDefaultPath;
QVector<QString> boardSdkVersions;
QString freeRTOSEnvVar;
QString freeRTOSBoardSdkSubDir;
TargetType type;
};
static McuPackageVersionDetector* generatePackageVersionDetector(QString envVar)
{
if (envVar.startsWith("EVK"))
return new McuPackageXmlVersionDetector("*_manifest_*.xml", "ksdk", "version", ".*");
if (envVar.startsWith("STM32"))
return new McuPackageXmlVersionDetector("package.xml", "PackDescription", "Release", "\\b(\\d+\\.\\d+\\.\\d+)\\b");
if (envVar.startsWith("RGL"))
return new McuPackageDirectoryVersionDetector("rgl_*_obj_*", "\\d+\\.\\d+\\.\\w+", false);
return nullptr;
}
static McuPackage *createBoardSdkPackage(const McuTargetDescription& desc)
{
const auto generateSdkName = [](const QString& envVar) {
@@ -291,11 +331,14 @@ static McuPackage *createBoardSdkPackage(const McuTargetDescription& desc)
return QDir::homePath();
}();
const auto versionDetector = generatePackageVersionDetector(desc.boardSdkEnvVar);
auto result = new McuPackage(
sdkName,
defaultPath,
{},
desc.boardSdkEnvVar);
desc.boardSdkEnvVar,
versionDetector);
result->setEnvironmentVariableName(desc.boardSdkEnvVar);
return result;
}
@@ -429,7 +472,10 @@ protected:
QVector<McuTarget *> mcuTargets;
McuToolChainPackage *tcPkg = tcPkgs.value(desc.toolchainId);
if (!tcPkg)
if (tcPkg) {
if (QVersionNumber::fromString(desc.qulVersion) >= QVersionNumber({1,8}))
tcPkg->setVersions(desc.toolchainVersions);
} else
tcPkg = createUnsupportedToolChainPackage();
for (int colorDepth : desc.colorDepths) {
QVector<McuPackage*> required3rdPartyPkgs;
@@ -451,6 +497,7 @@ protected:
boardSdkPkgs.insert(desc.boardSdkEnvVar, boardSdkPkg);
}
auto boardSdkPkg = boardSdkPkgs.value(desc.boardSdkEnvVar);
boardSdkPkg->setVersions(desc.boardSdkVersions);
boardSdkDefaultPath = boardSdkPkg->defaultPath();
required3rdPartyPkgs.append(boardSdkPkg);
}
@@ -537,6 +584,12 @@ static McuTargetDescription parseDescriptionJson(const QByteArray &data)
const QVariantList colorDepths = target.value("colorDepths").toArray().toVariantList();
const auto colorDepthsVector = Utils::transform<QVector<int> >(
colorDepths, [&](const QVariant &colorDepth) { return colorDepth.toInt(); });
const QVariantList toolchainVersions = toolchain.value("versions").toArray().toVariantList();
const auto toolchainVersionsVector = Utils::transform<QVector<QString> >(
toolchainVersions, [&](const QVariant &version) { return version.toString(); });
const QVariantList boardSdkVersions = boardSdk.value("versions").toArray().toVariantList();
const auto boardSdkVersionsVector = Utils::transform<QVector<QString> >(
boardSdkVersions, [&](const QVariant &version) { return version.toString(); });
return {
target.value("qulVersion").toString(),
@@ -545,9 +598,11 @@ static McuTargetDescription parseDescriptionJson(const QByteArray &data)
target.value("platformVendor").toString(),
colorDepthsVector,
toolchain.value("id").toString(),
toolchainVersionsVector,
boardSdk.value("envVar").toString(),
boardSdk.value("name").toString(),
boardSdk.value("defaultPath").toString(),
boardSdkVersionsVector,
freeRTOS.value("envVar").toString(),
freeRTOS.value("boardSdkSubDir").toString(),
boardSdk.empty() ? McuTargetDescription::TargetType::Desktop : McuTargetDescription::TargetType::MCU

View File

@@ -0,0 +1,135 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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.
**
****************************************************************************/
#include "mcusupportversiondetection.h"
#include <utils/fileutils.h>
#include <QDir>
#include <QRegularExpression>
#include <QProcess>
namespace McuSupport {
namespace Internal {
McuPackageVersionDetector::McuPackageVersionDetector()
{
}
McuPackageExecutableVersionDetector::McuPackageExecutableVersionDetector(
const QString &detectionPath,
const QStringList &detectionArgs,
const QString &detectionRegExp)
: McuPackageVersionDetector()
, m_detectionPath(detectionPath)
, m_detectionArgs(detectionArgs)
, m_detectionRegExp(detectionRegExp)
{
}
QString McuPackageExecutableVersionDetector::parseVersion(const QString &packagePath) const
{
if (m_detectionPath.isEmpty() || m_detectionRegExp.isEmpty())
return QString();
QString binaryPath = QDir::toNativeSeparators(packagePath + "/" + m_detectionPath);
if (!Utils::FilePath::fromString(binaryPath).exists())
return QString();
const QRegularExpression regExp(m_detectionRegExp);
const int execTimeout = 3000; // usually runs below 1s, but we want to be on the safe side
QProcess binaryProcess;
binaryProcess.start(binaryPath, m_detectionArgs);
if (!binaryProcess.waitForStarted())
return QString();
binaryProcess.waitForFinished(execTimeout);
if (binaryProcess.exitCode() == QProcess::ExitStatus::NormalExit) {
const QString processOutput = QString::fromUtf8(
binaryProcess.readAllStandardOutput().append(
binaryProcess.readAllStandardError()));
const QRegularExpressionMatch match = regExp.match(processOutput);
if (match.hasMatch())
return match.captured(regExp.captureCount());
}
// Fail gracefully: return empty string if execution failed or regexp did not match
return QString();
}
McuPackageXmlVersionDetector::McuPackageXmlVersionDetector(const QString &filePattern,
const QString &versionElement,
const QString &versionAttribute,
const QString &versionRegExp)
: m_filePattern(filePattern),
m_versionElement(versionElement),
m_versionAttribute(versionAttribute),
m_versionRegExp(versionRegExp)
{
}
QString McuPackageXmlVersionDetector::parseVersion(const QString &packagePath) const
{
const QRegularExpression regExp(m_versionRegExp);
const auto files = QDir(packagePath, m_filePattern).entryInfoList();
for (const auto &xmlFile: files) {
QFile sdkXmlFile = QFile(xmlFile.absoluteFilePath());
sdkXmlFile.open(QFile::OpenModeFlag::ReadOnly);
QXmlStreamReader xmlReader(&sdkXmlFile);
while (xmlReader.readNext()) {
if (xmlReader.name() == m_versionElement) {
const QString versionString = xmlReader.attributes().value(m_versionAttribute).toString();
const QRegularExpressionMatch match = regExp.match(versionString);
return match.hasMatch() ? match.captured(regExp.captureCount()) : versionString;
}
}
}
return QString();
}
McuPackageDirectoryVersionDetector::McuPackageDirectoryVersionDetector(const QString &filePattern,
const QString &versionRegExp,
const bool isFile)
: m_filePattern(filePattern),
m_versionRegExp(versionRegExp),
m_isFile(isFile)
{
}
QString McuPackageDirectoryVersionDetector::parseVersion(const QString &packagePath) const
{
const auto files = QDir(packagePath, m_filePattern)
.entryInfoList(m_isFile ? QDir::Filter::Files : QDir::Filter::Dirs);
for (const auto &entry: files) {
const QRegularExpression regExp(m_versionRegExp);
const QRegularExpressionMatch match = regExp.match(entry.fileName());
if (match.hasMatch())
return match.captured(regExp.captureCount());
}
return QString();
}
} // Internal
} // McuSupport

View File

@@ -0,0 +1,84 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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.
**
****************************************************************************/
#ifndef MCUSUPPORTVERSIONDETECTION_H
#define MCUSUPPORTVERSIONDETECTION_H
#include <QObject>
namespace McuSupport {
namespace Internal {
class McuPackageVersionDetector : public QObject {
Q_OBJECT
public:
McuPackageVersionDetector();
virtual ~McuPackageVersionDetector() = default;
virtual QString parseVersion(const QString &packagePath) const = 0;
};
// Get version from the output of an executable
class McuPackageExecutableVersionDetector : public McuPackageVersionDetector {
public:
McuPackageExecutableVersionDetector(const QString &detectionPath,
const QStringList &detectionArgs,
const QString &detectionRegExp);
virtual QString parseVersion(const QString &packagePath) const;
private:
const QString m_detectionPath;
const QStringList m_detectionArgs;
const QString m_detectionRegExp;
};
// Get version through parsing an XML file
class McuPackageXmlVersionDetector : public McuPackageVersionDetector {
public:
McuPackageXmlVersionDetector(const QString &filePattern,
const QString &elementName,
const QString &versionAttribute,
const QString &versionRegExp);
QString parseVersion(const QString &packagePath) const;
private:
const QString m_filePattern;
const QString m_versionElement;
const QString m_versionAttribute;
const QString m_versionRegExp;
};
// Get version from the filename of a given file/dir in the package directory
class McuPackageDirectoryVersionDetector : public McuPackageVersionDetector {
public:
McuPackageDirectoryVersionDetector(const QString &filePattern, const QString &versionRegExp, const bool isFile);
QString parseVersion(const QString &packagePath) const;
private:
const QString m_filePattern;
const QString m_versionRegExp;
const bool m_isFile;
};
} // Internal
} // McuSupport
#endif // MCUSUPPORTVERSIONDETECTION_H