mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2026-11-12 04:23:53 +01:00
using structs and refactoring
This commit is contained in:
1 parent
e7a9e94374
commit
0fadbb8a3e
3 files changed
+180
-72
No files matched your search
@@ -2,36 +2,57 @@
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#pragma once
|
||||
|
||||
#include <iosfwd>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
namespace sls {
|
||||
|
||||
struct SemanticVersion {
|
||||
int major{0};
|
||||
int minor{0};
|
||||
int patch{0};
|
||||
std::string prerelease{};
|
||||
|
||||
/**
|
||||
* If empty, return {}
|
||||
* If 0.0.0, only prerelease is returned (eg. developer, 0.0.0, other non
|
||||
* semantic versioning) */
|
||||
std::string toString() const;
|
||||
bool operator==(const SemanticVersion &other) const;
|
||||
bool operator<=(const SemanticVersion &other) const;
|
||||
};
|
||||
|
||||
class Version {
|
||||
private:
|
||||
std::string version_;
|
||||
/** Note: "0.0.0" is considered not semantic versioning here */
|
||||
bool hasSemanticVersioning_{false};
|
||||
SemanticVersion version_{};
|
||||
std::string date_;
|
||||
inline static const std::string defaultVersion_[] = {"developer", "0.0.0"};
|
||||
SemanticVersion parseSemanticVersion(const std::string &version);
|
||||
|
||||
public:
|
||||
explicit Version(const std::string &s);
|
||||
|
||||
static bool parseSemanticVersion(const std::string &version, int &major,
|
||||
int &minor, int &patch,
|
||||
std::string &extra);
|
||||
|
||||
std::string toString() const;
|
||||
bool hasSemanticVersioning() const;
|
||||
|
||||
std::string getVersion() const;
|
||||
std::string getDate() const;
|
||||
std::string concise() const;
|
||||
int getMajorVersion() const;
|
||||
|
||||
// expects semantic versioning
|
||||
// throws if not semantic versioning
|
||||
SemanticVersion getSemanticVersion() const;
|
||||
int getMajorVersion() const;
|
||||
int getMinorVersion() const;
|
||||
int getPatchVersion() const;
|
||||
std::string getPrereleaseVersion() const;
|
||||
bool isBackwardCompatible(const Version &other) const;
|
||||
|
||||
bool operator!=(const Version &other) const;
|
||||
bool operator==(const Version &other) const;
|
||||
bool operator<=(const Version &other) const;
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const SemanticVersion &v);
|
||||
std::ostream &operator<<(std::ostream &out, const Version &v);
|
||||
} // namespace sls
|
||||
+111
-60
@@ -9,109 +9,160 @@
|
||||
|
||||
namespace sls {
|
||||
|
||||
bool Version::parseSemanticVersion(const std::string &version, int &major,
|
||||
int &minor, int &patch, std::string &extra) {
|
||||
char extraBuffer[256] = {'\0'};
|
||||
// Parse major.minor.patch and capture any optional trailing suffix.
|
||||
const int scanned = sscanf(version.c_str(), "%d.%d.%d%255s", &major, &minor,
|
||||
&patch, extraBuffer);
|
||||
std::string SemanticVersion::toString() const {
|
||||
std::ostringstream oss;
|
||||
oss << major << "." << minor << "." << patch;
|
||||
if (!prerelease.empty()) {
|
||||
oss << prerelease;
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
if (scanned == 3) {
|
||||
extra.clear();
|
||||
return true;
|
||||
bool SemanticVersion::operator==(const SemanticVersion &other) const {
|
||||
return major == other.major && minor == other.minor &&
|
||||
patch == other.patch && prerelease == other.prerelease;
|
||||
}
|
||||
|
||||
bool SemanticVersion::operator<=(const SemanticVersion &other) const {
|
||||
if (major != other.major)
|
||||
return major < other.major;
|
||||
if (minor != other.minor)
|
||||
return minor < other.minor;
|
||||
if (patch != other.patch)
|
||||
return patch < other.patch;
|
||||
return prerelease <= other.prerelease;
|
||||
}
|
||||
|
||||
SemanticVersion Version::parseSemanticVersion(const std::string &version) {
|
||||
SemanticVersion ver;
|
||||
|
||||
// assuming only released versions have semantic versioning
|
||||
if (version == "developer" || version == "0.0.0") {
|
||||
return ver;
|
||||
}
|
||||
if (scanned == 4) {
|
||||
extra = extraBuffer;
|
||||
return true;
|
||||
|
||||
char prereleaseBuffer[256] = {'\0'};
|
||||
// Parse major.minor.patch and capture any optional trailing suffix.
|
||||
const int scanned = sscanf(version.c_str(), "%d.%d.%d%255s", &ver.major,
|
||||
&ver.minor, &ver.patch, prereleaseBuffer);
|
||||
|
||||
if (scanned == 3 || scanned == 4) {
|
||||
hasSemanticVersioning_ = true;
|
||||
if (scanned == 4)
|
||||
ver.prerelease = prereleaseBuffer;
|
||||
else
|
||||
ver.prerelease.clear();
|
||||
}
|
||||
return false;
|
||||
return ver;
|
||||
}
|
||||
|
||||
Version::Version(const std::string &s) {
|
||||
auto list = split(s, ' ');
|
||||
|
||||
// only date from previous releases
|
||||
if (list.size() == 1) {
|
||||
date_ = list[0];
|
||||
}
|
||||
|
||||
// semantic versioning + date
|
||||
else {
|
||||
version_ = list[0];
|
||||
auto version = list[0];
|
||||
date_ = list[1];
|
||||
version_ = parseSemanticVersion(version);
|
||||
}
|
||||
}
|
||||
|
||||
bool Version::hasSemanticVersioning() const {
|
||||
|
||||
return (version_ != defaultVersion_[0]) && (version_ != defaultVersion_[1]);
|
||||
std::string Version::toString() const {
|
||||
std::ostringstream oss;
|
||||
oss << version_ << " " << getDate();
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string Version::getVersion() const { return version_; }
|
||||
bool Version::hasSemanticVersioning() const { return hasSemanticVersioning_; }
|
||||
|
||||
std::string Version::getVersion() const { return version_.toString(); }
|
||||
|
||||
std::string Version::getDate() const { return date_; }
|
||||
|
||||
std::string Version::concise() const {
|
||||
if (hasSemanticVersioning())
|
||||
return version_;
|
||||
if (hasSemanticVersioning_)
|
||||
return version_.toString();
|
||||
return date_;
|
||||
}
|
||||
|
||||
int Version::getMajorVersion() const {
|
||||
int major = 0, minor = 0, patch = 0;
|
||||
if (sscanf(version_.c_str(), "%d.%d.%d", &major, &minor, &patch) == 3) {
|
||||
return major;
|
||||
SemanticVersion Version::getSemanticVersion() const {
|
||||
if (!hasSemanticVersioning_) {
|
||||
throw sls::RuntimeError("No semantic versioning available for " +
|
||||
toString());
|
||||
}
|
||||
throw sls::RuntimeError("Could not get major version from " + version_);
|
||||
return version_;
|
||||
}
|
||||
|
||||
int Version::getMajorVersion() const {
|
||||
if (!hasSemanticVersioning_) {
|
||||
throw sls::RuntimeError("Could not get major version from " +
|
||||
toString());
|
||||
}
|
||||
return version_.major;
|
||||
}
|
||||
|
||||
int Version::getMinorVersion() const {
|
||||
if (!hasSemanticVersioning_) {
|
||||
throw sls::RuntimeError("Could not get minor version from " +
|
||||
toString());
|
||||
}
|
||||
return version_.minor;
|
||||
}
|
||||
|
||||
int Version::getPatchVersion() const {
|
||||
if (!hasSemanticVersioning_) {
|
||||
throw sls::RuntimeError("Could not get patch version from " +
|
||||
toString());
|
||||
}
|
||||
return version_.patch;
|
||||
}
|
||||
|
||||
std::string Version::getPrereleaseVersion() const {
|
||||
if (!hasSemanticVersioning_) {
|
||||
throw sls::RuntimeError("Could not get prerelease version from " +
|
||||
toString());
|
||||
}
|
||||
return version_.prerelease;
|
||||
}
|
||||
|
||||
bool Version::isBackwardCompatible(const Version &other) const {
|
||||
if (!hasSemanticVersioning_ || !other.hasSemanticVersioning()) {
|
||||
throw sls::RuntimeError("Cannot check backward compatibility without "
|
||||
"semantic versioning for " +
|
||||
toString() + " and " + other.toString());
|
||||
}
|
||||
return getMajorVersion() == other.getMajorVersion();
|
||||
}
|
||||
|
||||
bool Version::operator==(const Version &other) const {
|
||||
if (hasSemanticVersioning() && other.hasSemanticVersioning()) {
|
||||
return version_ == other.getSemanticVersion();
|
||||
}
|
||||
return date_ == other.getDate();
|
||||
}
|
||||
|
||||
bool Version::operator!=(const Version &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
bool Version::operator==(const Version &other) const {
|
||||
// both have semantic versioning
|
||||
if (hasSemanticVersioning() && other.hasSemanticVersioning()) {
|
||||
return version_ == other.getVersion();
|
||||
}
|
||||
// compare dates
|
||||
return date_ == other.getDate();
|
||||
}
|
||||
|
||||
bool Version::operator<=(const Version &other) const {
|
||||
// both have semantic versioning
|
||||
if (hasSemanticVersioning() && other.hasSemanticVersioning()) {
|
||||
int major = 0, minor = 0, patch = 0;
|
||||
int otherMajor = 0, otherMinor = 0, otherPatch = 0;
|
||||
std::string extra;
|
||||
std::string otherExtra;
|
||||
|
||||
if (Version::parseSemanticVersion(version_, major, minor, patch,
|
||||
extra) &&
|
||||
Version::parseSemanticVersion(other.getVersion(), otherMajor,
|
||||
otherMinor, otherPatch, otherExtra)) {
|
||||
if (major != otherMajor)
|
||||
return major < otherMajor;
|
||||
if (minor != otherMinor)
|
||||
return minor < otherMinor;
|
||||
if (patch != otherPatch)
|
||||
return patch < otherPatch;
|
||||
return extra <= otherExtra;
|
||||
}
|
||||
|
||||
LOG(logWARNING) << "Could not compare semantic versions: " << version_
|
||||
<< " and " << other.getVersion()
|
||||
<< ". Comparing dates instead.";
|
||||
return version_ <= other.getSemanticVersion();
|
||||
}
|
||||
// compare dates
|
||||
return date_ <= other.getDate();
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const SemanticVersion &v) {
|
||||
return out << v.toString();
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const Version &v) {
|
||||
std::ostringstream oss;
|
||||
oss << v.getVersion() << " " << v.getDate();
|
||||
return out << oss.str();
|
||||
return out << v.toString();
|
||||
}
|
||||
|
||||
} // namespace sls
|
||||
@@ -9,7 +9,9 @@ TEST_CASE("check if version is semantic", "[version]") {
|
||||
|
||||
auto [version_string, has_semantic_version] =
|
||||
GENERATE(std::make_tuple("developer 0x250512", false),
|
||||
std::make_tuple("0.0.0 0x250512", false));
|
||||
std::make_tuple("0.0.0 0x250512", false),
|
||||
std::make_tuple("10.1.1 0x250512", true),
|
||||
std::make_tuple("0x250512", false));
|
||||
|
||||
Version version(version_string);
|
||||
|
||||
@@ -24,7 +26,7 @@ TEST_CASE("semantic version ordering compares numerically", "[version]") {
|
||||
CHECK_FALSE(v10 <= v9);
|
||||
}
|
||||
|
||||
TEST_CASE("semantic version compares extra suffix lexicographically",
|
||||
TEST_CASE("semantic version compares prerelease lexicographically",
|
||||
"[version]") {
|
||||
Version rc("10.1.1.rc 0x250512");
|
||||
Version zz("10.1.1.zz 0x250512");
|
||||
@@ -33,6 +35,15 @@ TEST_CASE("semantic version compares extra suffix lexicographically",
|
||||
CHECK_FALSE(zz <= rc);
|
||||
}
|
||||
|
||||
TEST_CASE("semantic version compares prerelease with no prerelease",
|
||||
"[version]") {
|
||||
Version prerelease("10.1.1.rc 0x250512");
|
||||
Version release("10.1.1 0x250512");
|
||||
|
||||
CHECK_FALSE(prerelease <= release);
|
||||
CHECK(release <= prerelease);
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"semantic comparison falls back to date on malformed semantic version",
|
||||
"[version]") {
|
||||
@@ -43,7 +54,7 @@ TEST_CASE(
|
||||
CHECK_FALSE(valid <= malformed);
|
||||
}
|
||||
|
||||
TEST_CASE("semantic version compares extra suffix and without", "[version]") {
|
||||
TEST_CASE("semantic version compares prerelease and without", "[version]") {
|
||||
Version v1011rc("10.1.1.rc 0x250512");
|
||||
Version v1010("10.1.0 0x250512");
|
||||
|
||||
@@ -51,4 +62,29 @@ TEST_CASE("semantic version compares extra suffix and without", "[version]") {
|
||||
CHECK(v1010 <= v1011rc);
|
||||
}
|
||||
|
||||
TEST_CASE("semantic version", "[version]") {
|
||||
auto version = Version("10.1.1.rc 0x250512");
|
||||
CHECK(version.hasSemanticVersioning());
|
||||
CHECK(version.getDate() == "0x250512");
|
||||
CHECK(version.toString() == "10.1.1.rc 0x250512");
|
||||
auto semver = version.getSemanticVersion();
|
||||
CHECK(semver.toString() == "10.1.1.rc");
|
||||
CHECK(semver.major == 10);
|
||||
CHECK(semver.minor == 1);
|
||||
CHECK(semver.patch == 1);
|
||||
CHECK(semver.prerelease == "rc");
|
||||
|
||||
version = Version("0.0.0 0x250512");
|
||||
CHECK_FALSE(version.hasSemanticVersioning());
|
||||
CHECK(version.getDate() == "0x250512");
|
||||
CHECK(version.toString() == "0.0.0 0x250512");
|
||||
REQUIRE_THROWS(version.getSemanticVersion());
|
||||
|
||||
version = Version("0x250512");
|
||||
CHECK_FALSE(version.hasSemanticVersioning());
|
||||
CHECK(version.getDate() == "0x250512");
|
||||
CHECK(version.toString() == "0.0.0 0x250512");
|
||||
REQUIRE_THROWS(version.getSemanticVersion());
|
||||
}
|
||||
|
||||
} // namespace sls
|
||||
Reference in new issue
Block a user