Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[projmgr] Minimum component version handling (#276) #431

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion libs/rtemodel/src/RteCprjProject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ void RteCprjProject::ApplySelectedComponentsToCprjFile() {
item = new RteItem(cprjComponents);
item->SetTag("component");
item->AddAttributes(ci->GetAttributes(), true); // take over attributes
if (ci->GetVersionMatchMode(GetActiveTargetName()) != VersionCmp::FIXED_VERSION) {
if (ci->GetVersionMatchMode(GetActiveTargetName()) != VersionCmp::MatchMode::FIXED_VERSION) {
item->RemoveAttribute("Cversion"); // specify version only if fixed
}
item->RemoveAttribute("condition"); // remove generally attribute "condition"
Expand Down
14 changes: 7 additions & 7 deletions libs/rtemodel/src/RteInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ RteInstanceTargetInfo::RteInstanceTargetInfo() :
m_bExcluded(false),
m_bIncludeInLib(false),
m_instanceCount(1),
m_VersionMatchMode(VersionCmp::LATEST_VERSION)
m_VersionMatchMode(VersionCmp::MatchMode::LATEST_VERSION)
{
};

Expand All @@ -48,7 +48,7 @@ RteInstanceTargetInfo::RteInstanceTargetInfo(const map<string, string>& attribut
m_bExcluded(false),
m_bIncludeInLib(false),
m_instanceCount(1),
m_VersionMatchMode(VersionCmp::LATEST_VERSION)
m_VersionMatchMode(VersionCmp::MatchMode::LATEST_VERSION)
{
ProcessAttributes();
}
Expand Down Expand Up @@ -106,7 +106,7 @@ bool RteInstanceTargetInfo::SetVersionMatchMode(VersionCmp::MatchMode mode)
if (m_VersionMatchMode == mode)
return false;
m_VersionMatchMode = mode;
if (mode == VersionCmp::LATEST_VERSION)
if (mode == VersionCmp::MatchMode::LATEST_VERSION)
RemoveAttribute("versionMatchMode");
else {
string sMode = VersionCmp::MatchModeToString(mode);
Expand Down Expand Up @@ -309,7 +309,7 @@ const string& RteItemInstance::GetFirstTargetName() const

bool RteItemInstance::SetUseLatestVersion(bool bUseLatest, const string& targetName)
{
VersionCmp::MatchMode mode = bUseLatest ? VersionCmp::LATEST_VERSION : VersionCmp::FIXED_VERSION;
VersionCmp::MatchMode mode = bUseLatest ? VersionCmp::MatchMode::LATEST_VERSION : VersionCmp::MatchMode::FIXED_VERSION;
RteInstanceTargetInfo* ti = GetTargetInfo(targetName);
if (ti) {
return ti->SetVersionMatchMode(mode);
Expand Down Expand Up @@ -407,7 +407,7 @@ VersionCmp::MatchMode RteItemInstance::GetVersionMatchMode(const string& targetN
RteInstanceTargetInfo* info = GetTargetInfo(targetName);
if (info)
return info->GetVersionMatchMode();
return VersionCmp::LATEST_VERSION;
return VersionCmp::MatchMode::LATEST_VERSION;
}

RteInstanceTargetInfo* RteItemInstance::AddTargetInfo(const string& targetName, const string& copyFrom)
Expand Down Expand Up @@ -1025,11 +1025,11 @@ bool RtePackageInstanceInfo::ResolvePack(const string& targetName)
if (!IsUsedByTarget(targetName))
return true;
VersionCmp::MatchMode mode = GetVersionMatchMode(targetName);
if (mode == VersionCmp::EXCLUDED_VERSION)
if (mode == VersionCmp::MatchMode::EXCLUDED_VERSION)
return true;
RtePackage* pack = NULL;
RteModel* model = GetModel();
if (mode == VersionCmp::FIXED_VERSION) {
if (mode == VersionCmp::MatchMode::FIXED_VERSION) {
pack = model->GetPackage(GetPackageID(true));
} else {
pack = model->GetLatestPackage(GetPackageID(false));
Expand Down
12 changes: 6 additions & 6 deletions libs/rtemodel/src/RtePackage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1181,7 +1181,7 @@ bool RtePackageFilter::IsPackageFiltered(const string& packId) const

RtePackageAggregate::RtePackageAggregate(RteItem* parent) :
RteItem(parent),
m_mode(VersionCmp::EXCLUDED_VERSION)
m_mode(VersionCmp::MatchMode::EXCLUDED_VERSION)
{
}

Expand Down Expand Up @@ -1264,7 +1264,7 @@ void RtePackageAggregate::SetPackageSelected(const string& id, bool bSelected)
return;
if (bSelected) {
m_selectedPackages.insert(id);
m_mode = VersionCmp::FIXED_VERSION;
m_mode = VersionCmp::MatchMode::FIXED_VERSION;
} else {
auto it = m_selectedPackages.find(id);
if (it != m_selectedPackages.end())
Expand All @@ -1275,10 +1275,10 @@ void RtePackageAggregate::SetPackageSelected(const string& id, bool bSelected)
void RtePackageAggregate::SetVersionMatchMode(VersionCmp::MatchMode mode)
{
m_mode = mode;
if (m_mode == VersionCmp::FIXED_VERSION) {
if (m_mode == VersionCmp::MatchMode::FIXED_VERSION) {
string version = RtePackage::VersionFromId(GetLatestPackageID());
if (version.empty()) {
m_mode = VersionCmp::LATEST_VERSION; // missing latest pack, cannot set to FIXED version
m_mode = VersionCmp::MatchMode::LATEST_VERSION; // missing latest pack, cannot set to FIXED version
} else if (m_selectedPackages.empty()) {
SetPackageSelected(GetLatestPackageID(), true);
}
Expand All @@ -1290,9 +1290,9 @@ void RtePackageAggregate::AdjustVersionMatchMode()
if (IsUsed()) {
string version = RtePackage::VersionFromId(GetLatestPackageID());
if (version.empty())
SetVersionMatchMode(VersionCmp::LATEST_VERSION);
SetVersionMatchMode(VersionCmp::MatchMode::LATEST_VERSION);
else
SetVersionMatchMode(VersionCmp::FIXED_VERSION); // ensure selection not empty
SetVersionMatchMode(VersionCmp::MatchMode::FIXED_VERSION); // ensure selection not empty
}
}

Expand Down
12 changes: 6 additions & 6 deletions libs/rtemodel/src/RteProject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,9 +338,9 @@ RteComponentInstance* RteProject::AddCprjComponent(RteItem* item, RteTarget* tar
info->SetInstanceCount(instanceCount);
const string& version = item->GetAttribute("Cversion");
if (version.empty()) {
info->SetVersionMatchMode(VersionCmp::LATEST_VERSION);
info->SetVersionMatchMode(VersionCmp::MatchMode::LATEST_VERSION);
} else {
info->SetVersionMatchMode(VersionCmp::FIXED_VERSION);
info->SetVersionMatchMode(VersionCmp::MatchMode::FIXED_VERSION);
}
if (item->GetAttribute("instances").empty())
instanceCount = -1;
Expand Down Expand Up @@ -953,7 +953,7 @@ RtePackageInstanceInfo* RteProject::GetLatestPackageInfo(const string& packId) c
string RteProject::GetEffectivePackageID(const string& packId, const string& targetName) const
{
RtePackageInstanceInfo* pi = GetPackageInfo(packId);
if (pi && pi->GetVersionMatchMode(targetName) == VersionCmp::FIXED_VERSION) {
if (pi && pi->GetVersionMatchMode(targetName) == VersionCmp::MatchMode::FIXED_VERSION) {
return pi->GetPackageID(true);
}
string commonId = RtePackage::CommonIdFromId(packId);
Expand Down Expand Up @@ -1256,7 +1256,7 @@ RteItem::ConditionResult RteProject::ResolveComponents(bool bFindReplacementForA
RteComponentAggregate* a = NULL;
set<RteComponentAggregate*> aggregates;
RteAttributes componentAttributes = *ci; // copy attributes
if (ci->GetVersionMatchMode(activeTargetName) != VersionCmp::FIXED_VERSION)
if (ci->GetVersionMatchMode(activeTargetName) != VersionCmp::MatchMode::FIXED_VERSION)
{
// make search wider : remove bundle and version
componentAttributes.RemoveAttribute("Cbundle");
Expand Down Expand Up @@ -1669,7 +1669,7 @@ void RteProject::PropagateFilteredPackagesToTargetModel(const string& targetName
}

VersionCmp::MatchMode mode = pi->GetVersionMatchMode(targetName);
if (mode == VersionCmp::FIXED_VERSION) {
if (mode == VersionCmp::MatchMode::FIXED_VERSION) {
const string& id = itpi->first;
fixedPacks[id] = *pi;
} else {
Expand Down Expand Up @@ -1929,7 +1929,7 @@ bool RteProject::Validate()
if (!pi->IsUsedByTarget(targetName))
continue;
VersionCmp::MatchMode mode = pi->GetVersionMatchMode(targetName);
string packId = pi->GetPackageID(mode == VersionCmp::FIXED_VERSION);
string packId = pi->GetPackageID(mode == VersionCmp::MatchMode::FIXED_VERSION);
const string& url = pi->GetURL();
//if(!IsPackageUsed( packId, targetName, mode == VersionCmp::FIXED_VERSION))
// continue;
Expand Down
6 changes: 3 additions & 3 deletions libs/rtemodel/src/RteTarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1445,7 +1445,7 @@ RteComponent* RteTarget::ResolveComponent(RteComponentInstance* ci) const

VersionCmp::MatchMode mode = ci->GetVersionMatchMode(GetName());
RteComponent* c = NULL;
if (mode == VersionCmp::FIXED_VERSION) {
if (mode == VersionCmp::MatchMode::FIXED_VERSION) {
c = GetComponent(ci->GetComponentID(true));
} else {
c = GetLatestComponent(ci);
Expand All @@ -1457,7 +1457,7 @@ RteComponent* RteTarget::ResolveComponent(RteComponentInstance* ci) const
// try to find a component with a bundle
RteComponentAggregate* a = m_classes->FindComponentAggregate(ci);
if (a) {
if (mode == VersionCmp::FIXED_VERSION)
if (mode == VersionCmp::MatchMode::FIXED_VERSION)
c = a->GetComponent(ci->GetCvariantName(), ci->GetVersionString());
else
c = a->GetLatestComponent(ci->GetCvariantName());
Expand All @@ -1477,7 +1477,7 @@ RteComponent* RteTarget::GetPotentialComponent(RteComponentInstance* ci) const

VersionCmp::MatchMode mode = ci->GetVersionMatchMode(GetName());
RteComponent* c = NULL;
if (mode == VersionCmp::FIXED_VERSION) {
if (mode == VersionCmp::MatchMode::FIXED_VERSION) {
c = GetPotentialComponent(ci->GetComponentID(true));
} else {
c = GetLatestPotentialComponent(ci->GetComponentID(false));
Expand Down
6 changes: 6 additions & 0 deletions libs/rteutils/include/RteUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,12 @@ class RteUtils
* @return true if string has hexadecimal prefix
*/
static bool HasHexPrefix(const std::string& s);
/**
* @brief determine first occurrence of a digit in a string
* @param s string containing the numerals
* @return index of first digit found, else string::npos
*/
static std::string::size_type FindFirstDigit(const std::string& s);
/**
* @brief convert string to a value of type unsigned long
* @param s string to be converted
Expand Down
34 changes: 27 additions & 7 deletions libs/rteutils/include/VersionCmp.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
/******************************************************************************/

#include <string>
#include <set>

class VersionCmp
{
Expand All @@ -24,13 +25,16 @@ class VersionCmp

public:

enum MatchMode {
ANY_VERSION, // any installed version is accepted
FIXED_VERSION, // fixed version is accepted
LATEST_VERSION,// use the latest version
EXCLUDED_VERSION // exclude specified version
enum class MatchMode {
ANY_VERSION, // any installed version is accepted
FIXED_VERSION, // fixed version is accepted
LATEST_VERSION, // use the latest version
EXCLUDED_VERSION, // exclude specified version
HIGHER_OR_EQUAL // higher or equal version
};

static constexpr const char* PREFIX_VERSION = "@";
static constexpr const char* HIGHER_OR_EQUAL_OPERATOR = ">=";

public:
/**
Expand Down Expand Up @@ -59,14 +63,30 @@ class VersionCmp
* @param mode mode specification: "fixed" | "latest" | "excluded"
* @return mode constant
*/
static MatchMode MatchModeFromString(const std::string& mode);
static MatchMode MatchModeFromString(const std::string& mode);
/**
* @brief compare version string to return mode constant
* @param version filter version string e.g: @1.2.3, @>=1.2.3
* @return mode constant
*/
static MatchMode MatchModeFromVersionString(const std::string& version);
/**
* @brief compare mode with constant to return string
* @param mode mode constant
* @return mode string: "fixed" | "latest" | "excluded"
*/
static std::string MatchModeToString(VersionCmp::MatchMode mode);

/**
* @brief get matched version from available versions
* @param filter version filter or version range e.g: @>=1.2.3, 1.2.3:1.4.0
* @param availableVersions list of available versions
* @return matching version string, based on filter
* also, in case of multiple matches, latest matching version
* has precedence over other versions
*/
static const std::string GetMatchingVersion(
const std::string& filter,
const std::set<std::string> availableVersions);

// helper compare class for map containers (version compare operators)
class Less
Expand Down
4 changes: 4 additions & 0 deletions libs/rteutils/src/RteUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,10 @@ bool RteUtils::HasHexPrefix(const string& s)
return s.length() > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X');
}

string::size_type RteUtils::FindFirstDigit(const std::string& s) {
return s.find_first_of("0123456789");
}

unsigned long RteUtils::ToUL(const string& s) {
if (s.empty()) {
return (0x0L);
Expand Down
81 changes: 72 additions & 9 deletions libs/rteutils/src/VersionCmp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,37 +189,100 @@ string VersionCmp::RemoveVersionMeta(const string& v) {
return v;
}


VersionCmp::MatchMode VersionCmp::MatchModeFromString(const std::string& mode)
{
if (mode == "fixed")
return FIXED_VERSION;
return MatchMode::FIXED_VERSION;
else if (mode == "latest")
return LATEST_VERSION;
return MatchMode::LATEST_VERSION;
else if (mode == "excluded")
return EXCLUDED_VERSION;
return MatchMode::EXCLUDED_VERSION;
// all other cases
return ANY_VERSION;
return MatchMode::ANY_VERSION;
}

VersionCmp::MatchMode VersionCmp::MatchModeFromVersionString(const std::string& version)
{
string op, filter;
VersionCmp::MatchMode mode = MatchMode::LATEST_VERSION;
filter = RteUtils::GetSuffix(version, '@');
if (filter.empty())
return mode;
auto pos = RteUtils::FindFirstDigit(filter);
if (pos == std::string::npos)
return mode;
op = filter.substr(0, pos);
if (op.empty())
mode = MatchMode::FIXED_VERSION;
else if (op == HIGHER_OR_EQUAL_OPERATOR)
mode = MatchMode::HIGHER_OR_EQUAL;
return mode;
}

std::string VersionCmp::MatchModeToString(VersionCmp::MatchMode mode)
{
string s;
switch (mode) {
case FIXED_VERSION:
case MatchMode::FIXED_VERSION:
s = "fixed";
break;
case LATEST_VERSION:
case MatchMode::LATEST_VERSION:
case MatchMode::HIGHER_OR_EQUAL:
s = "latest";
break;
case ANY_VERSION:
case MatchMode::ANY_VERSION:
break; // no string
case EXCLUDED_VERSION:
case MatchMode::EXCLUDED_VERSION:
s = "excluded";
break;
}
return s;
}

const std::string VersionCmp::GetMatchingVersion(const std::string& filter, const std::set<std::string> availableVersions) {
string matchedVersion;
if (std::string::npos == filter.find('@')) {
// version range
vector<std::string> matchedVersions;
for (auto& version : availableVersions) {
if (0 == RangeCompare(version, filter)) {
matchedVersions.push_back(version);
}
}
auto itr = std::max_element(matchedVersions.begin(), matchedVersions.end(),
[](const auto& a, const auto& b) {
return (VersionCmp::Compare(a, b) < 0);
});
if (itr != matchedVersions.end()) {
matchedVersion = *itr;
}
}
else {
VersionCmp::MatchMode mode = VersionCmp::MatchModeFromVersionString(filter);
string filterVersion = RteUtils::RemovePrefixByString(filter, PREFIX_VERSION);
if (mode == MatchMode::HIGHER_OR_EQUAL) {
filterVersion = RteUtils::RemovePrefixByString(filterVersion, HIGHER_OR_EQUAL_OPERATOR);
}
for (auto& version : availableVersions) {
int result = VersionCmp::Compare(version, filterVersion, false);
switch (mode) {
case MatchMode::FIXED_VERSION:
if (result == 0)
return version;
break;
case MatchMode::LATEST_VERSION:
case MatchMode::HIGHER_OR_EQUAL:
if (result > 0 || result == 0) {
matchedVersion = version;
filterVersion = matchedVersion;
}
break;
default: // never happening
break;
}
}
}
return matchedVersion;
}

// End of VersionCmp.cpp
2 changes: 1 addition & 1 deletion libs/rteutils/test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
SET(TEST_SOURCE_FILES src/RteUtilsTest.cpp)
SET(TEST_SOURCE_FILES src/RteUtilsTest.cpp src/VersionCmpTests.cpp)

add_executable(RteUtilsUnitTests ${TEST_SOURCE_FILES})

Expand Down
Loading