Skip to content

Commit

Permalink
[projmgr] Minimum component version handling
Browse files Browse the repository at this point in the history
  • Loading branch information
grasci-arm authored Aug 23, 2022
1 parent 02307cf commit 00d5edb
Show file tree
Hide file tree
Showing 23 changed files with 498 additions and 152 deletions.
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

0 comments on commit 00d5edb

Please sign in to comment.