Skip to content

Commit

Permalink
fix(daemon): rewrite package version parsing logic
Browse files Browse the repository at this point in the history
  • Loading branch information
LordTermor committed May 24, 2024
1 parent c72244c commit e063c2d
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 40 deletions.
68 changes: 30 additions & 38 deletions daemon/core/domain/value_objects/PackageVersion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@
*/
#include "PackageVersion.h"

#include "core/domain/entities/Package.h"
#include "scn/tuple_return/tuple_return.h"
#include "utilities/Error.h"

#include <optional>
#include <scn/scn.h>
#include <scn/tuple_return.h>
Expand Down Expand Up @@ -114,15 +110,13 @@ std::strong_ordering PackageVersion::compare(const PackageVersion& lh,
const PackageVersion& rh) {
std::strong_ordering ret = std::strong_ordering::equal;

if (!(lh.epoch || rh.epoch)) {
ret = rpmvercmp(std::to_string(*lh.epoch), std::to_string(*rh.epoch));
}
ret = rpmvercmp(std::string(lh.epoch), std::string(rh.epoch));

if (ret == 0) {
ret = rpmvercmp(lh.version, rh.version);
if (ret == std::strong_ordering::equal) {
ret = rpmvercmp(std::string(lh.version), std::string(rh.version));

if (ret == 0 && lh.release.length() > 0 && rh.release.length() > 0) {
ret = rpmvercmp(lh.release, rh.release);
if (ret == std::strong_ordering::equal && lh.release && rh.release) {
ret = rpmvercmp(std::string(*lh.release), std::string(*rh.release));
}
}

Expand All @@ -131,46 +125,44 @@ std::strong_ordering PackageVersion::compare(const PackageVersion& lh,

PackageVersion::ParseResult
PackageVersion::from_string(std::string_view version_str) {
auto [scan_ok, version, epoch_int, release] =
scn::scan_tuple<std::string, int, std::string>(
version_str, "{:[:alnum:.]}\:{}-{:[:alnum:.]}");
std::optional<int> epoch = std::nullopt;

if (!scan_ok) {
if (!scn::scan(version_str, "{:[:alnum:.]}-{}", version, release)) {
return bxt::make_error<ParsingError>(
ParsingError::ErrorCode::InvalidFormat);
}
std::string epoch;
std::string version;
std::optional<std::string> release;
size_t pos = 0;

size_t epoch_end = version_str.find(':');
if (epoch_end != std::string::npos) {
epoch = version_str.substr(0, epoch_end);
pos = epoch_end + 1;
} else {
epoch = epoch_int;
}

static constexpr auto version_validator = [](const char& ch) {
return std::isalnum(ch) || ch == '.';
};

if (!std::ranges::all_of(version, version_validator)) {
return bxt::make_error<ParsingError>(
ParsingError::ErrorCode::InvalidVersion);
epoch = "0";
}

if (!std::ranges::all_of(release, version_validator)) {
size_t release_start = version_str.rfind('-');
if (release_start != std::string::npos && release_start > pos) {
version = version_str.substr(pos, release_start - pos);
release = version_str.substr(release_start + 1);
} else if (pos < version_str.length()) {
version = version_str.substr(pos);
release = std::nullopt;
} else {
return bxt::make_error<ParsingError>(
ParsingError::ErrorCode::InvalidReleaseTag);
ParsingError::ErrorCode::InvalidFormat);
}

return PackageVersion {version, epoch, release};
return PackageVersion {
.version = version, .epoch = epoch, .release = release};
}

std::string PackageVersion::string() const {
std::string format = "{1}";

if (epoch) { format = "{0}:" + format; }
if (std::string(epoch) != "0") { format = "{0}:" + format; }

if (release.length() > 0) { format = format + "-{2}"; }
if (release) { format = format + "-{2}"; }

return fmt::format(fmt::runtime(format), epoch.value_or(0),
std::string(version), release);
return fmt::format(fmt::runtime(format), std::string(epoch),
std::string(version), release.value_or(Name("0")));
}

} // namespace bxt::Core::Domain
4 changes: 2 additions & 2 deletions daemon/core/domain/value_objects/PackageVersion.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ struct PackageVersion {
std::string string() const;

Name version;
std::optional<int> epoch = {};
std::string release;
Name epoch;
std::optional<Name> release = {};
};

} // namespace bxt::Core::Domain

0 comments on commit e063c2d

Please sign in to comment.