// Copyright (c) 2012-2017 VideoStitch SAS // Copyright (c) 2018 stitchEm #include "versionHelper.hpp" #include "libvideostitch-base/logmanager.hpp" #include <QRegularExpression> namespace VideoStitch { namespace Helper { static const QString STABLE_VAHANAVR("stable-vahanaVR"); static const QString STABLE_STUDIO("stable-studio"); QString getStringFromChannel(Channel channel) { switch (channel) { case Channel::Unknown: return QStringLiteral("unknown"); case Channel::Alpha: return QStringLiteral("alpha"); case Channel::Beta: return QStringLiteral("beta"); case Channel::ReleaseCandidate: return QStringLiteral("RC"); case Channel::Stable: return QString(); } return getStringFromChannel(Channel::Unknown); } Channel getChannelFromString(const QString& str) { if (str.compare(getStringFromChannel(Channel::Alpha), Qt::CaseInsensitive) == 0) { return Channel::Alpha; } else if (str.compare(getStringFromChannel(Channel::Beta), Qt::CaseInsensitive) == 0) { return Channel::Beta; } else if (str.compare(getStringFromChannel(Channel::ReleaseCandidate), Qt::CaseInsensitive) == 0) { return Channel::ReleaseCandidate; } else if (str.compare(getStringFromChannel(Channel::Stable), Qt::CaseInsensitive) == 0) { return Channel::Stable; } else { return Channel::Unknown; } } bool getAppsVersionComponents(const QString& versionString, int& major, int& minor, int& patch, Channel& channel, int& channelVersion) { // APP VERSION TEMPLATE // v.<MAJOR>.<MINOR>.<PATCH>.<CHANNEL><CHANNEL_REV> // example v1.2.3.beta4 QRegularExpression versionExpression(".*v?\\d+\\.\\d+\\.\\d+\\.?(alpha|beta|RC)?\\d*"); if (!versionExpression.match(versionString).hasMatch()) { LogManager::getInstance()->writeToLogFile("Error: the current version doesn't respect the version template"); return false; } QStringList components = versionString.split("."); bool ok = false; QString majorString = components.takeFirst(); major = majorString.replace(QRegExp(".*v"), "").toInt(&ok); if (!ok) { LogManager::getInstance()->writeToLogFile( QString("Error while converting major version number to integer: %1").arg(majorString)); } const QString minorString = components.takeFirst(); minor = minorString.toInt(&ok); if (!ok) { LogManager::getInstance()->writeToLogFile( QString("Error while converting minor version number to integer: %1").arg(minorString)); } const QString patchString = components.takeFirst(); patch = patchString.left(patchString.indexOf("-")).toInt(&ok); if (!ok) { LogManager::getInstance()->writeToLogFile( QString("Error while converting patch number to integer: %1").arg(patchString)); } if (components.size() > 0) { QString chan = components.takeFirst(); chan = chan.left(chan.indexOf("-")); QString channelString; QString chanRev; foreach (QChar c, chan) { if (c.isDigit()) { chanRev.append(c); } else { channelString.append(c); } } channel = getChannelFromString(channelString); channelVersion = chanRev.toInt(); } else { channel = Channel::Stable; channelVersion = -1; } return true; } bool AppsVersion::parseVersionString(const QString& stringVersion) { return getAppsVersionComponents(stringVersion, majorVersion, minorVersion, patchVersion, channel, channelVersion); } AppsVersion::AppsVersion(const QString& stringVersion) : majorVersion(0), minorVersion(0), patchVersion(0), channel(Channel::Stable), channelVersion(-1) { if (!stringVersion.isEmpty()) { getAppsVersionComponents(stringVersion, majorVersion, minorVersion, patchVersion, channel, channelVersion); } } bool AppsVersion::isStableVersion() const { return channel == Channel::Stable || channel == Channel::ReleaseCandidate; } QString AppsVersion::toString() const { QString channelString = channel == Channel::Stable ? "" : QString(".%0%1").arg(getStringFromChannel(channel), QString::number(channelVersion)); return QString("v%0.%1.%2%3") .arg(QString::number(majorVersion), QString::number(minorVersion), QString::number(patchVersion), channelString); } bool AppsVersion::operator==(const AppsVersion& other) const { return majorVersion == other.majorVersion && minorVersion == other.minorVersion && patchVersion == other.patchVersion && channel == other.channel && channelVersion == other.channelVersion; } bool AppsVersion::operator!=(const AppsVersion& other) const { return !(*this == other); } bool AppsVersion::operator<(const AppsVersion& other) const { if (majorVersion < other.majorVersion) { return true; } if (majorVersion > other.majorVersion) { return false; } if (minorVersion < other.minorVersion) { return true; } if (minorVersion > other.minorVersion) { return false; } if (patchVersion < other.patchVersion) { return true; } if (patchVersion > other.patchVersion) { return false; } if (channel < other.channel) { return true; } if (channel > other.channel) { return false; } if (channelVersion < other.channelVersion) { return true; } if (channelVersion > other.channelVersion) { return false; } return false; } bool getAppsInfoComponents(const QString& infoString, QString& appName, AppsVersion& version, int& commitCount, QString& commitHash, QString& branchName, QDateTime& commitDate) { // Version template // <APP_NAME>-<VERSION>[-<COMMITS_COUNT>-<COMMIT_HASH>]-<GIT_BRANCH>.<COMMIT_DATE> // Release versions won't have commits count and commit hash QRegularExpression versionInfoExpression( R"((VahanaVR|Studio)-[0-9.a-zA-Z]+-?\d*-[a-zA-Z0-9]*-[a-zA-Z0-9-\/]+\.\d{4}-\d{2}-\d{2})"); if (!versionInfoExpression.match(infoString).hasMatch()) { LogManager::getInstance()->writeToLogFile("Error: the current version doesn't respect the version template (regex)"); return false; } QStringList components = infoString.split("-"); appName = components.takeFirst(); version.parseVersionString(components.takeFirst().mid(1)); // parse commit infos commitCount = 0; commitHash.clear(); branchName.clear(); branchName = components.join("-"); components = branchName.split("."); // parse timestamp if (components.size() > 1) { branchName = components.takeFirst(); commitDate = QDateTime::fromString(components.takeFirst(), "yyyy-MM-dd"); } bool isDevVersion = !branchName.endsWith(STABLE_STUDIO) && !branchName.endsWith(STABLE_VAHANAVR); if (isDevVersion) { components = branchName.split("-"); if (components.size() < 3) { LogManager::getInstance()->writeToLogFile("Error: the current version doesn't respect the version template (dev version branch name)"); return false; } commitCount = components.takeFirst().toInt(); commitHash = components.takeFirst(); branchName = components.join("-"); } return true; } AppsInfo::AppsInfo(const QString& stringAppInfo) : appName(QStringLiteral("")), version(), commitCount(0), commitHash((QStringLiteral(""))), branchName((QStringLiteral(""))), commitTimeStamp() { getAppsInfoComponents(stringAppInfo, appName, version, commitCount, commitHash, branchName, commitTimeStamp); } bool AppsInfo::isDevVersion() const { return branchName != STABLE_STUDIO && branchName != STABLE_VAHANAVR; } QString AppsInfo::toString() const { return QString("%0-%1").arg(appName, version.toString()) + (isDevVersion() ? QString("-%0-%1").arg(commitHash, branchName) : QString()); } } // namespace Helper } // namespace VideoStitch