Version type

This commit is contained in:
Eism 2022-12-06 09:44:01 +02:00
parent ae0909a195
commit 890c425831
7 changed files with 423 additions and 1 deletions

View file

@ -21,7 +21,7 @@ set(MSCORE_UNSTABLE TRUE) # Mark as unstable
set(MSCORE_RELEASE_CHANNEL "devel")
if (NOT MUSESCORE_VERSION_LABEL)
SET(MUSESCORE_VERSION_LABEL "Development")
SET(MUSESCORE_VERSION_LABEL "dev")
endif (NOT MUSESCORE_VERSION_LABEL)
SET(MUSESCORE_NAME_VERSION "${MUSESCORE_NAME} ${MUSESCORE_VERSION_MAJOR}")

View file

@ -82,6 +82,8 @@ set(MODULE_SRC
${CMAKE_CURRENT_LIST_DIR}/types/translatablestring.h
${CMAKE_CURRENT_LIST_DIR}/types/mnemonicstring.cpp
${CMAKE_CURRENT_LIST_DIR}/types/mnemonicstring.h
${CMAKE_CURRENT_LIST_DIR}/types/version.cpp
${CMAKE_CURRENT_LIST_DIR}/types/version.h
${CMAKE_CURRENT_LIST_DIR}/io/ioenums.h
${CMAKE_CURRENT_LIST_DIR}/io/path.cpp

View file

@ -39,6 +39,7 @@ set(MODULE_TEST_SRC
${CMAKE_CURRENT_LIST_DIR}/allocator_tests.cpp
${CMAKE_CURRENT_LIST_DIR}/mnemonicstring_tests.cpp
${CMAKE_CURRENT_LIST_DIR}/containers_tests.cpp
${CMAKE_CURRENT_LIST_DIR}/version_tests.cpp
)
include(${PROJECT_SOURCE_DIR}/src/framework/testing/gtest.cmake)

View file

@ -0,0 +1,140 @@
/*
* SPDX-License-Identifier: GPL-3.0-only
* MuseScore-CLA-applies
*
* MuseScore
* Music Composition & Notation
*
* Copyright (C) 2021 MuseScore BVBA and others
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <gtest/gtest.h>
#include "types/version.h"
using namespace mu::framework;
class Global_Types_VersionTests : public ::testing::Test
{
public:
};
TEST_F(Global_Types_VersionTests, Compare_Major)
{
Version v1(u"1.0.0");
Version v2(u"2.0.0");
EXPECT_TRUE(v1 < v2);
}
TEST_F(Global_Types_VersionTests, Compare_Minor)
{
Version v1(u"1.0.0");
Version v2(u"1.1.0");
EXPECT_TRUE(v1 < v2);
}
TEST_F(Global_Types_VersionTests, Compare_Patch)
{
Version v1(u"1.0.0");
Version v2(u"1.0.1");
EXPECT_TRUE(v1 < v2);
}
TEST_F(Global_Types_VersionTests, Compare_Alpha_Alpha)
{
Version v1(u"1.0.0-alpha.1");
Version v2(u"1.0.0-alpha.2");
EXPECT_TRUE(v1 < v2);
}
TEST_F(Global_Types_VersionTests, Compare_Alpha_Beta)
{
Version v1(u"1.0.0-alpha");
Version v2(u"1.0.0-beta");
EXPECT_TRUE(v1 < v2);
}
TEST_F(Global_Types_VersionTests, Compare_Alpha_RC)
{
Version v1(u"1.0.0-alpha");
Version v2(u"1.0.0-rc");
EXPECT_TRUE(v1 < v2);
}
TEST_F(Global_Types_VersionTests, Compare_Alpha_Release)
{
Version v1(u"1.0.0-alpha");
Version v2(u"1.0.0");
EXPECT_TRUE(v1 < v2);
}
TEST_F(Global_Types_VersionTests, Compare_Beta_Beta)
{
Version v1(u"1.0.0-beta.1");
Version v2(u"1.0.0-beta.2");
EXPECT_TRUE(v1 < v2);
}
TEST_F(Global_Types_VersionTests, Compare_Beta_RC)
{
Version v1(u"1.0.0-beta");
Version v2(u"1.0.0-rc");
EXPECT_TRUE(v1 < v2);
}
TEST_F(Global_Types_VersionTests, Compare_Beta_Release)
{
Version v1(u"1.0.0-beta");
Version v2(u"1.0.0");
EXPECT_TRUE(v1 < v2);
}
TEST_F(Global_Types_VersionTests, Compare_RC_RC)
{
Version v1(u"1.0.0-rc.1");
Version v2(u"1.0.0-rc.2");
EXPECT_TRUE(v1 < v2);
}
TEST_F(Global_Types_VersionTests, Compare_RC_Release)
{
Version v1(u"1.0.0-rc");
Version v2(u"1.0.0");
EXPECT_TRUE(v1 < v2);
}
TEST_F(Global_Types_VersionTests, Compare_Equal)
{
Version v1(u"1.0");
Version v2(u"1");
EXPECT_TRUE(v1 == v2);
v1 = Version(u"1.0.0-rc");
v2 = Version(u"1.0.0-rc");
EXPECT_TRUE(v1 == v2);
}

View file

@ -389,6 +389,8 @@ class StringList : public std::vector<String>
{
public:
StringList() = default;
StringList(std::initializer_list<String> l)
: std::vector<String>(l) {}
StringList& operator <<(const String& s) { return append(s); }
StringList& append(const String& s) { push_back(s); return *this; }

View file

@ -0,0 +1,220 @@
/*
* SPDX-License-Identifier: GPL-3.0-only
* MuseScore-CLA-applies
*
* MuseScore
* Music Composition & Notation
*
* Copyright (C) 2021 MuseScore BVBA and others
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "version.h"
#include "log.h"
static const mu::Char SUFFIX_DELIMITER = '-';
using namespace mu::framework;
static std::array<int, 3> parseVersion(const mu::String& versionString, bool& ok)
{
std::array<int, 3> result { 0, 0, 0 };
if (versionString.isEmpty()) {
ok = false;
return result;
}
size_t componentIdx = 0;
int curNum = 0;
for (size_t i = 0; i < versionString.size(); ++i) {
char ch = versionString[i];
if (ch == '.' || ch == '\0') {
result.at(componentIdx++) = curNum;
curNum = 0;
} else if ('0' <= ch && ch <= '9') {
curNum = curNum * 10 + (ch - '0');
} else {
ok = false;
return result;
}
}
result.at(componentIdx) = curNum;
ok = true;
return result;
}
static std::pair<mu::String, int> parseVersionSuffix(const mu::String& suffix, bool& ok)
{
if (suffix.isEmpty()) {
ok = false;
return std::make_pair(mu::String(), 0);
}
mu::StringList suffixComponents = suffix.split('.');
ok = true;
return std::make_pair(suffixComponents.front(), (suffixComponents.size() > 1 ? suffixComponents[1].toInt() : 0));
}
Version::Version(int major, int minor, int patch, const String& suffix, int suffixVersion)
: m_major(major), m_minor(minor), m_patch(patch), m_suffix(suffix), m_suffixVersion(suffixVersion)
{
}
Version::Version(const mu::String& versionStr)
{
String version = versionStr.left(versionStr.indexOf(SUFFIX_DELIMITER));
bool ok = true;
std::array<int, 3> versionComponents = parseVersion(version, ok);
if (!ok) {
return;
}
m_major = versionComponents[0];
m_minor = versionComponents[1];
m_patch = versionComponents[2];
if (!versionStr.contains(SUFFIX_DELIMITER)) {
return;
}
setSuffix(versionStr.right(versionStr.size() - versionStr.indexOf(SUFFIX_DELIMITER) - 1));
}
int Version::major() const
{
return m_major;
}
int Version::minor() const
{
return m_minor;
}
int Version::patch() const
{
return m_patch;
}
mu::String Version::suffix() const
{
return m_suffix;
}
int Version::suffixVersion() const
{
return m_suffixVersion;
}
void Version::setSuffix(const String& suffix)
{
bool ok = true;
std::pair<String, int> versionSuffix = parseVersionSuffix(suffix, ok);
if (!ok) {
return;
}
m_suffix = versionSuffix.first;
m_suffixVersion = versionSuffix.second;
}
mu::String Version::toString()
{
String res = String(u"%1.%2.%3").arg(m_major, m_minor, m_patch);
if (!m_suffix.isEmpty()) {
res.append(SUFFIX_DELIMITER);
res.append(m_suffix + (m_suffixVersion > 0 ? u"." + String::number(m_suffixVersion) : u""));
}
return res;
}
bool Version::operator <(const Version& other) const
{
if (m_major > other.major()) {
return false;
} else if (m_major == other.major()) {
if (m_minor > other.minor()) {
return false;
} else if (m_minor == other.minor()) {
if (m_patch > other.patch()) {
return false;
} else if (m_patch == other.patch()) {
if (m_suffix.isEmpty()) {
return false;
}
if (other.suffix().isEmpty()) {
return true;
}
static mu::StringList suffixes {
u"dev",
u"alpha",
u"beta",
u"rc"
};
auto currentIt = std::find_if(suffixes.cbegin(), suffixes.cend(), [suffix=m_suffix](const String& s) {
return s.startsWith(suffix);
});
auto updateIt = std::find_if(suffixes.cbegin(), suffixes.cend(), [suffix=other.suffix()](const String& s) {
return s.startsWith(suffix);
});
if (currentIt == suffixes.cend() || updateIt == suffixes.cend()) {
LOGE() << "Invalid version suffix; current " << m_suffix << ", update " << other.suffix();
return true;
}
if (currentIt < updateIt) {
return true;
}
if (currentIt == updateIt) {
return m_suffixVersion < other.suffixVersion();
}
return false;
}
}
}
return true;
}
bool Version::operator ==(const Version& other) const
{
return m_major == other.major()
&& m_minor == other.minor()
&& m_patch == other.patch()
&& m_suffix == other.suffix()
&& m_suffixVersion == other.suffixVersion();
}
bool Version::operator <=(const Version& other) const
{
if (operator ==(other)) {
return true;
}
return operator <(other);
}

View file

@ -0,0 +1,57 @@
/*
* SPDX-License-Identifier: GPL-3.0-only
* MuseScore-CLA-applies
*
* MuseScore
* Music Composition & Notation
*
* Copyright (C) 2021 MuseScore BVBA and others
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef MU_FRAMEWORK_VERSION_H
#define MU_FRAMEWORK_VERSION_H
#include "types/string.h"
namespace mu::framework {
class Version
{
public:
Version(int major, int minor = 0, int patch = 0, const String& suffix = String(), int suffixVersion = 0);
Version(const String& versionStr);
int major() const;
int minor() const;
int patch() const;
String suffix() const;
int suffixVersion() const;
void setSuffix(const String& suffix);
String toString();
bool operator <(const Version& other) const;
bool operator ==(const Version& other) const;
bool operator <=(const Version& other) const;
private:
int m_major = 0;
int m_minor = 0;
int m_patch = 0;
String m_suffix;
int m_suffixVersion = 0;
};
}
#endif // MU_FRAMEWORK_VERSION_H