diff --git a/libs/rtemodel/include/RteItem.h b/libs/rtemodel/include/RteItem.h index a7fcd1352..75a1366d7 100644 --- a/libs/rtemodel/include/RteItem.h +++ b/libs/rtemodel/include/RteItem.h @@ -341,14 +341,14 @@ class RteItem : public XmlTreeItem virtual const std::string& GetID() const; /** - * @brief get unique component ID: "Vendor::Class&Bundle:Group:Sub&Variant@1.2.3(condition)[pack]" + * @brief get unique component ID: "Vendor::Class&Bundle:Group:Sub&Variant\@1.2.3(condition)[pack]" * @return component unique ID */ virtual std::string GetComponentUniqueID() const; /** - * @brief get full component ID: "Vendor::Class&Bundle:Group:Sub&Variant@1.2.3" - * @param withVersion true to append version as "@1.2.3" + * @brief get full component ID: "Vendor::Class&Bundle:Group:Sub&Variant\@1.2.3" + * @param withVersion true to append version as "\@1.2.3" * @return full component ID */ virtual std::string GetComponentID(bool withVersion) const; diff --git a/libs/rtemodel/include/RtePackage.h b/libs/rtemodel/include/RtePackage.h index a13e18f83..60f7124bf 100644 --- a/libs/rtemodel/include/RtePackage.h +++ b/libs/rtemodel/include/RtePackage.h @@ -133,6 +133,13 @@ class RtePackage : public RteRootItem */ static std::string NameFromId(const std::string& id); + /** + * @brief helper static method to construct pack ID from supplied path + * @param path pack absolute or relative path + * @return pack ID string + */ + static std::string PackIdFromPath(const std::string& path); + /** * @brief helper static method to compare pack IDs. * Alpha-numeric comparison for vendor and name. @@ -462,6 +469,16 @@ class RtePackage : public RteRootItem */ static std::string GetPackageIDfromAttributes(const XmlItem& attr, bool withVersion = true); + /** + * @brief get fully specified package identifier composed from individual strings + * @param vendor pack vendor + * @param name pack name + * @param version pack version + * @return string package identifier + */ + static std::string ComposePackageID(const std::string& vendor, const std::string& name, const std::string& version); + + /** * @brief get URL to download this pack from * @param withVersion flag to return url with this version, otherwise without @@ -484,6 +501,12 @@ class RtePackage : public RteRootItem */ RteItem* GetDefaultLicenseSet() const; + /** + * @brief get relative path to default license file agreement + * @return text of element if any + */ + const std::string& GetPackLicenseFile() const { return GetChildText("license");} + /** * @brief get condition with specified ID * @param id condition ID to search for diff --git a/libs/rtemodel/include/RteProject.h b/libs/rtemodel/include/RteProject.h index 9a2ee47fa..35a47990d 100644 --- a/libs/rtemodel/include/RteProject.h +++ b/libs/rtemodel/include/RteProject.h @@ -31,6 +31,123 @@ class RteGenerator; class RteTarget; class CprjTargetElement; +/** + * @brief class to represent aggregated license info +*/ +class RteLicenseInfo :public RteItem +{ +public: + /** + * @brief default constructor + * @param parent + */ + RteLicenseInfo(RteItem* parent = nullptr); + + /** + * @brief add component ID to the internal collection + * @param componentID component ID string + */ + void AddComponentId(const std::string& componentID) { m_componentIDs.insert(componentID); } + + /** + * @brief add pack ID to the internal collection + * @param packID pack ID string + */ + void AddPackId(const std::string& packID) { m_packIDs.insert(packID); } + + + /** + * @brief return collection of component IDs associated with the license + * @return set of component IDs + */ + const std::set& GetComponentIDs() const { return m_componentIDs; } + + /** + * @brief return collection of pack IDs associated with the license + * @return set of pack IDs + */ + const std::set& GetPackIDs() const { return m_packIDs; }; + + /** + * @brief return collection package IDs associated with the license + * @return pack ID string + */ + std::string GetPackageID(bool withVersion = true) const override { return GetAttribute("pack"); }; + + /** + * @brief convert info content to yml-like text + * @return yml formatted text + */ + std::string ToString(unsigned indent = 0); + + /** + * @brief construct license title + * @param license pointer to RteItem representing element + * @return license ID string : spdx or combination of title and type + */ + static std::string ConstructLicenseTitle(const RteItem* license); + + /** + * @brief construct license internal ID + * @param license pointer to RteItem representing element + * @return license ID string : spdx or combination of title, type and pack ID + */ + static std::string ConstructLicenseID(const RteItem* license); + +protected: + std::set m_componentIDs; + std::set m_packIDs; +}; + +class RteLicenseInfoCollection +{ +public: + /** + * @brief default constructor + */ + RteLicenseInfoCollection() {}; + + /** + * @brief virtual destructor + */ + virtual ~RteLicenseInfoCollection(); + + /** + * @brief clear internal structures + */ + void Clear(); + + /** + * @brief add license info to the collection + * @param item pointer to RteItem (RteComponent, RteApi, RtePackage) + */ + void AddLicenseInfo(RteItem* item); + + /** + * @brief convert collection content to yml-like text + * @return yml formatted text + */ + std::string ToString(); + +protected: + /** + * @brief Ensure collection contains RteLicenseInfo object for specified object + * @param item RteItem* object to add + * @param license RteItem* pointing to license element, may be NULL + * @return pointer to RteLicenseInfo object + */ + RteLicenseInfo* EnsureLicensInfo(RteItem* item, RteItem* licenseElement); + + /** + * @brief Ensure collection contains RteLicenseInfo object for specified ID + * @param licId internal license ID + * @return reference to RteLicenseInfo object + */ + RteLicenseInfo* EnsureLicensInfo(const std::string& licId); + + std::map m_LicensInfos; +}; + /** * @brief class representing project consuming CMSIS RTE data */ @@ -431,7 +548,12 @@ class RteProject : public RteRootItem */ const RteFileInfo* GetFileInfo(const std::string& groupName, const std::string& file, const std::string& target) const; -public: + /** + * @brief collect license info used in project + * @param collection of license infos + */ + void CollectLicenseInfos(RteLicenseInfoCollection& licenseInfos) const; + /** * @brief update CMSIS RTE data such as components, boards, gpdsc information, project files in project. * @return true if CMSIS RTE data is updated otherwise false diff --git a/libs/rtemodel/src/RteKernel.cpp b/libs/rtemodel/src/RteKernel.cpp index a0a148251..df8eacb9d 100644 --- a/libs/rtemodel/src/RteKernel.cpp +++ b/libs/rtemodel/src/RteKernel.cpp @@ -78,7 +78,7 @@ RteCallback* RteKernel::GetRteCallback() const return m_rteCallback ? m_rteCallback : RteCallback::GetGlobal(); } -void RteKernel::SetRteCallback(RteCallback* callback) +void RteKernel::SetRteCallback(RteCallback* callback) { m_rteCallback = callback; GetGlobalModel()->SetCallback(m_rteCallback); @@ -342,10 +342,9 @@ string RteKernel::GetInstalledPdscFile(const XmlItem& attributes, const string& string path(rtePath); path += '/' + vendor + '/' + name; - string installedVersion = RteFsUtils::GetInstalledPackVersion(path, versionRange); if (!installedVersion.empty()) { - packId = vendor + '.' + name + '.' + installedVersion; + packId = RtePackage::ComposePackageID(vendor, name, installedVersion); return path + '/' + installedVersion + '/' + vendor + '.' + name + ".pdsc"; } diff --git a/libs/rtemodel/src/RtePackage.cpp b/libs/rtemodel/src/RtePackage.cpp index c71c17355..225132a1f 100644 --- a/libs/rtemodel/src/RtePackage.cpp +++ b/libs/rtemodel/src/RtePackage.cpp @@ -23,8 +23,11 @@ #include "RteGenerator.h" #include "RteBoard.h" +#include "RteConstants.h" + #include "XMLTree.h" +#include using namespace std; @@ -144,51 +147,18 @@ string RtePackage::GetDisplayName() const string RtePackage::CommonIdFromId(const string& id) { - string::size_type pos = 0; - pos = id.find('.'); - if (pos == string::npos) - return id; - pos++; - pos = id.find('.', pos); - if (pos == string::npos) - return id; - return id.substr(0, pos); + return RteUtils::GetPrefix(id, RteConstants::PREFIX_PACK_VERSION_CHAR); } string RtePackage::DisplayNameFromId(const string& id) { - string displayName; - string::size_type vendorPos = 0; - string::size_type namePos = 0; - vendorPos = id.find('.'); - if (vendorPos == string::npos) - return id; - displayName = id.substr(0, vendorPos); - vendorPos++; - namePos = id.find('.', vendorPos); - if (namePos == string::npos) - return id; - displayName += "::"; - displayName += id.substr(vendorPos, namePos - vendorPos); - return displayName; - + return CommonIdFromId(id); } string RtePackage::VersionFromId(const string& id) { - string version; - string::size_type pos = 0; - pos = id.find('.'); - if (pos == string::npos) - return version; - pos++; - pos = id.find('.', pos); - if (pos == string::npos) - return version; - pos++; - version = id.substr(pos); - return VersionCmp::RemoveVersionMeta(version); + return VersionCmp::RemoveVersionMeta(RteUtils::GetSuffix(id, RteConstants::PREFIX_PACK_VERSION_CHAR)); } string RtePackage::ReleaseVersionFromId(const string& id) @@ -231,24 +201,13 @@ string RtePackage::ReleaseIdFromId(const string& id) string version = ReleaseVersionFromId(id); if (version.empty()) return id; - string releaseId = CommonIdFromId(id); - releaseId += "."; - releaseId += version; - return releaseId; + return CommonIdFromId(id) + RteConstants::PREFIX_PACK_VERSION + version; } string RtePackage::VendorFromId(const string& id) { - string vendor; - - string::size_type pos = 0; - pos = id.find('.'); - if (pos == string::npos) - return vendor; - vendor = id.substr(0, pos); - return vendor; - + return RteUtils::RemoveSuffixByString(id, RteConstants::SUFFIX_PACK_VENDOR); } string RtePackage::NameFromId(const string& id) @@ -256,18 +215,48 @@ string RtePackage::NameFromId(const string& id) string name; string::size_type pos = 0; string::size_type posEnd = 0; - pos = id.find('.'); + pos = id.find(RteConstants::SUFFIX_PACK_VENDOR); if (pos == string::npos) { return name; } - pos++; - posEnd = id.find('.', pos); + pos+= strlen(RteConstants::SUFFIX_PACK_VENDOR); + posEnd = id.find(RteConstants::PREFIX_PACK_VERSION_CHAR, pos); if (posEnd == string::npos) { return id.substr(pos); } return id.substr(pos, posEnd - pos); } +std::string RtePackage::PackIdFromPath(const std::string& path) +{ + string baseName = RteUtils::ExtractFileBaseName(path); + list segments; + RteUtils::SplitString(segments, baseName, '.'); + string commonID; + string version; + unsigned i = 0; + for (string s : segments) { + if (i == 0) { + commonID = s; + } else if (i == 1) { + commonID += RteConstants::SUFFIX_PACK_VENDOR + s; + } else if (i == 2) { + version = RteConstants::PREFIX_PACK_VERSION + s; + } else { + version += '.' + s; + } + i++; + } + if (version.empty()) { + // try upper directory + string dir = RteUtils::ExtractFileName(RteUtils::ExtractFilePath(path, false)); + if (!dir.empty() && isdigit(dir.at(0))) { + version = RteConstants::PREFIX_PACK_VERSION + dir; + } + } + return commonID + version; +} + int RtePackage::ComparePackageIDs(const string& a, const string& b) { string commonA = RtePackage::CommonIdFromId(a); @@ -643,7 +632,7 @@ RteItem* RtePackage::CreateItem(const std::string& tag) } else if (tag == "conditions") { m_conditions = new RteConditionContainer(this); return m_conditions; - } else if (tag == "liceseSets") { + } else if (tag == "licenseSets") { m_licenseSets = new RteItem(this); return m_licenseSets; } else if (tag == "releases") { @@ -750,24 +739,24 @@ string RtePackage::GetPackageID(bool withVersion) const return GetCommonID(); } - string RtePackage::GetPackageIDfromAttributes(const XmlItem& attr, bool withVersion) { - string id = attr.GetAttribute("vendor"); - if (!id.empty()) - id += "."; - id += attr.GetAttribute("name"); + const auto& vendor = attr.GetAttribute("vendor"); + const string version = withVersion ? + VersionCmp::RemoveVersionMeta(attr.GetAttribute("version")) : EMPTY_STRING; - if (withVersion) { - const string& version = attr.GetAttribute("version"); - if (!version.empty()) { - id += "."; - id += VersionCmp::RemoveVersionMeta(version); - } - } - return id; + return ComposePackageID(vendor, attr.GetAttribute("name"), version); } +string RtePackage::ComposePackageID(const string& vendor, const string& name, const string& version) { + const vector> elements = { + {"", vendor}, + {vendor.empty() ? "" : + RteConstants::SUFFIX_PACK_VENDOR, name}, + {RteConstants::PREFIX_PACK_VERSION, version}, + }; + return RteUtils::ConstructID(elements); +}; string RtePackage::GetPackagePath(bool withVersion) const { diff --git a/libs/rtemodel/src/RteProject.cpp b/libs/rtemodel/src/RteProject.cpp index 954961bc7..aaa1c99aa 100644 --- a/libs/rtemodel/src/RteProject.cpp +++ b/libs/rtemodel/src/RteProject.cpp @@ -23,10 +23,135 @@ #include "RteFsUtils.h" #include "XMLTree.h" +#include using namespace std; const std::string RteProject::DEFAULT_RTE_FOLDER = "RTE"; + +RteLicenseInfo::RteLicenseInfo(RteItem* parent) : + RteItem("license", parent) +{ +} + +std::string RteLicenseInfo::ToString(unsigned indent) +{ + stringstream ss; + ss << RteUtils::GetIndent(indent) << "- license: " << ConstructLicenseTitle(this) << endl; + indent += 2; + const string& license_agreement = GetAttribute("agreement"); + if (!license_agreement.empty()) { + ss << RteUtils::GetIndent(indent) << "license-agreement: " << license_agreement << endl; + } + ss << RteUtils::GetIndent(indent) << "packs:" << endl; + for (auto& packId : m_packIDs) { + ss << RteUtils::GetIndent(indent) << "- pack: " << packId << endl; + } + if (!m_componentIDs.empty()) { + ss << RteUtils::GetIndent(indent) << "components:" << endl; + for (auto& compId : m_componentIDs) { + ss << RteUtils::GetIndent(indent) << "- component: " << compId << endl; + } + } + return ss.str(); +} + +std::string RteLicenseInfo::ConstructLicenseTitle(const RteItem* license) +{ + string name = license->GetAttribute("spdx"); + if (name.empty()) { + name = license->GetAttribute("title"); + if (!name.empty()) { + name = " " + name; + } else { + name = ""; + } + } + return name; +} + +std::string RteLicenseInfo::ConstructLicenseID(const RteItem* license) +{ + string id = license->GetAttribute("spdx"); + if (id.empty()) { + id = ConstructLicenseTitle(license) + "(" + license->GetPackageID()+ ")"; + } + return id; +} + +RteLicenseInfoCollection::~RteLicenseInfoCollection() +{ + Clear(); +} + +void RteLicenseInfoCollection::Clear() +{ + for (auto [_, ptr] : m_LicensInfos) { + delete ptr; + } + m_LicensInfos.clear(); +} + +std::string RteLicenseInfoCollection::ToString() +{ + stringstream ss; + ss << "licenses:" << endl; + for (auto& [key, info] : m_LicensInfos) { + ss << info->ToString(2) << endl; + } + return ss.str(); +} + + +void RteLicenseInfoCollection::AddLicenseInfo(RteItem* item) +{ + if (!item) { + return; + } + RteItem* licenseSet = item->GetLicenseSet(); + if (licenseSet) { + for (RteItem* license : licenseSet->GetChildren()) { + EnsureLicensInfo(item, license); + } + } else { + EnsureLicensInfo(item, nullptr); + } +} + +RteLicenseInfo* RteLicenseInfoCollection::EnsureLicensInfo(RteItem* item, RteItem* license) +{ + RtePackage* pack = item->GetPackage(); + string licId = license? RteLicenseInfo::ConstructLicenseID(license) : RteLicenseInfo::ConstructLicenseID(pack); + + auto it = m_LicensInfos.find(licId); + RteLicenseInfo* info = nullptr;; + if (it == m_LicensInfos.end()) { + info = new RteLicenseInfo(); + m_LicensInfos[licId] = info; + string licFile; + if (license) { + info->SetAttributes(*license); + if(!info->HasAttribute("spdx")) { + licFile = license->GetName(); + } + } else { + info->AddAttribute("pack", pack->GetID()); + licFile = pack->GetChildText("license"); + } + if (!licFile.empty()) { + info->AddAttribute("agreement", "%CMSIS_PACK_ROOT%/" + pack->GetPackagePath(true) + licFile); + } + } else { + info = it->second; + } + info->AddPackId(pack->GetID()); + if (dynamic_cast(item)) { + info->AddComponentId(item->GetComponentID(true)); + } + return info; +} + + //////////////////////////// RteProject::RteProject() : RteRootItem(nullptr), @@ -538,6 +663,9 @@ void RteProject::UpdateConfigFileBackups(RteFileInstance* fi, RteFile* f) { if (!ShouldUpdateRte()) return; + if (!f || !fi) { + return; + } string src = f->GetOriginalAbsolutePath(); string absPath = RteFsUtils::AbsolutePath(fi->GetAbsolutePath()).generic_string(); @@ -2460,4 +2588,27 @@ const RteFileInfo* RteProject::GetFileInfo(const string& groupName, const string return NULL; } +void RteProject::CollectLicenseInfos(RteLicenseInfoCollection& licenseInfos) const +{ + //collect all components, APIs, DFPs and BSPs + set components; + set packs; + for (auto [targetName, t] : GetTargets()) { + packs.insert(t->GetDevicePackage()); + packs.insert(t->GetBoardPackage()); + for (auto [_c, ci] : m_components) { + RteComponent* c = ci->GetResolvedComponent(targetName); + if (c) { + components.insert(c); + } + } + } + for (auto c : components) { + licenseInfos.AddLicenseInfo(c); + } + for (auto p : packs) { + licenseInfos.AddLicenseInfo(p); + } +} + // End of RteProject.cpp diff --git a/libs/rtemodel/test/src/RteConditionTest.cpp b/libs/rtemodel/test/src/RteConditionTest.cpp index b20b5d972..2f06acdc1 100644 --- a/libs/rtemodel/test/src/RteConditionTest.cpp +++ b/libs/rtemodel/test/src/RteConditionTest.cpp @@ -64,7 +64,7 @@ TEST_F(RteConditionTest, MissingIgnoredFulfilledSelectable) { ASSERT_NE(depSolver, nullptr); EXPECT_EQ(depSolver->GetConditionResult(), RteItem::FULFILLED); - RtePackageInstanceInfo packInfo(nullptr, "ARM.RteTest.0.1.0"); + RtePackageInstanceInfo packInfo(nullptr, "ARM::RteTest@0.1.0"); RtePackage* pack = rteModel->GetPackage(packInfo); ASSERT_NE(pack, nullptr); RteCondition* denyDependency = pack->GetCondition("DenyDependency"); diff --git a/libs/rtemodel/test/src/RteExampleTest.cpp b/libs/rtemodel/test/src/RteExampleTest.cpp index 222fb14a0..d022e1fa2 100644 --- a/libs/rtemodel/test/src/RteExampleTest.cpp +++ b/libs/rtemodel/test/src/RteExampleTest.cpp @@ -57,7 +57,7 @@ void RteExampleTest::TearDown() { TEST_F(RteExampleTest, TestExamplePaths) { - const string testPackID = "ARM.RteTest.0.1.0"; + const string testPackID = "ARM::RteTest@0.1.0"; // Expected results const int exampleCountExp = 2; diff --git a/libs/rtemodel/test/src/RteItemTest.cpp b/libs/rtemodel/test/src/RteItemTest.cpp index f8a2f9670..b735011bd 100644 --- a/libs/rtemodel/test/src/RteItemTest.cpp +++ b/libs/rtemodel/test/src/RteItemTest.cpp @@ -8,6 +8,7 @@ #include "RteItem.h" #include "RteCondition.h" +#include "RtePackage.h" #include using namespace std; @@ -89,5 +90,38 @@ TEST(RteItemTest, ComponentAttributesFromId) { EXPECT_EQ("Class:Group&Variant", item.GetComponentID(true)); } +TEST(RteItemTest, PackageID) { + + RteItem pack; + pack.AddAttribute("name", "Name"); + pack.AddAttribute("vendor", "Vendor"); + pack.AddAttribute("version", "1.2.3-alpha+build"); + + string id = RtePackage::GetPackageIDfromAttributes(pack, true); + EXPECT_EQ(id, "Vendor::Name@1.2.3-alpha"); + + string commonId = RtePackage::CommonIdFromId(id); + EXPECT_EQ(commonId,"Vendor::Name"); + EXPECT_EQ(commonId, RtePackage::CommonIdFromId(commonId)); + EXPECT_EQ(commonId, RtePackage::GetPackageIDfromAttributes(pack, false)); + + EXPECT_EQ(RtePackage::VendorFromId(id), "Vendor"); + EXPECT_EQ(RtePackage::VendorFromId(commonId), "Vendor"); + + EXPECT_EQ(RtePackage::NameFromId(id), "Name"); + EXPECT_EQ(RtePackage::NameFromId(commonId), "Name"); + + EXPECT_EQ(RtePackage::VersionFromId("Vendor::Name@1.2.3-alpha+build"), "1.2.3-alpha"); + EXPECT_EQ(RtePackage::VersionFromId(id), "1.2.3-alpha"); + EXPECT_TRUE(RtePackage::VersionFromId(commonId).empty()); + + EXPECT_EQ(RtePackage::ReleaseVersionFromId(id), "1.2.3"); + EXPECT_EQ(RtePackage::ReleaseIdFromId(id), "Vendor::Name@1.2.3"); + + EXPECT_EQ(RtePackage::PackIdFromPath("Vendor.Name.1.2.3-alpha.pdsc"), id); + EXPECT_EQ(RtePackage::PackIdFromPath("Vendor.Name.pdsc"), commonId); + EXPECT_EQ(RtePackage::PackIdFromPath("Vendor/Name/1.2.3-alpha/Vendor.Name.pdsc"), id); + EXPECT_EQ(RtePackage::PackIdFromPath(".Web/Vendor.Name.pdsc"), commonId); +} // end of RteItemTest.cpp diff --git a/libs/rtemodel/test/src/RteModelTest.cpp b/libs/rtemodel/test/src/RteModelTest.cpp index 3c8a0d3ac..c253e042e 100644 --- a/libs/rtemodel/test/src/RteModelTest.cpp +++ b/libs/rtemodel/test/src/RteModelTest.cpp @@ -66,7 +66,7 @@ TEST(RteModelTest, LoadPacks) { RtePackageInfo pi(pack); EXPECT_TRUE(pi.HasAttribute("description")); EXPECT_EQ(pi.GetDescription(), pack->GetDescription()); - EXPECT_EQ(pi.GetID(), "ARM.RteTestBoard.0.1.0"); + EXPECT_EQ(pi.GetID(), "ARM::RteTestBoard@0.1.0"); board = rteModel->FindBoard("RteTest NoMCU board"); ASSERT_NE(board, nullptr); @@ -83,21 +83,21 @@ TEST(RteModelTest, LoadPacks) { {"Csub", "Missing"}, {"Cversion","0.9.9"}, {"condition","Missing"}}); - RtePackageInstanceInfo packInfo(nullptr, "ARM.RteTest.0.1.0"); + RtePackageInstanceInfo packInfo(nullptr, "ARM::RteTest@0.1.0"); item.SetPackageAttributes(packInfo); list components; RteComponent* c = rteModel->FindComponents(item, components); EXPECT_EQ(components.size(), 1); EXPECT_TRUE(c != nullptr); components.clear(); - packInfo.SetPackId("ARM.RteTest"); + packInfo.SetPackId("ARM::RteTest"); item.SetPackageAttributes(packInfo); c = rteModel->FindComponents(item, components); EXPECT_EQ(components.size(), 1); EXPECT_TRUE(c != nullptr); components.clear(); - packInfo.SetPackId("ARM.RteTest"); + packInfo.SetPackId("ARM::RteTest"); item.SetPackageAttributes(packInfo); item.RemoveAttribute("Csub"); item.RemoveAttribute("Cversion"); @@ -131,7 +131,7 @@ TEST(RteModelTest, LoadPacks) { components.clear(); item.SetAttribute("Cbundle", "BundleTwo"); - packInfo.SetPackId("ARM.RteTest.1.0"); + packInfo.SetPackId("ARM::RteTest@1.0"); item.SetPackageAttributes(packInfo); c = rteModel->FindComponents(item, components); EXPECT_EQ(components.size(), 0); @@ -282,6 +282,13 @@ TEST_F(RteModelPrjTest, LoadCprj) { RteCprjProject* loadedCprjProject = rteKernel.LoadCprj(RteTestM3_cprj); ASSERT_NE(loadedCprjProject, nullptr); + RteLicenseInfoCollection licences; + loadedCprjProject->CollectLicenseInfos(licences); + string licenseText = licences.ToString(); + + string licRefFile = prjsDir + RteTestM3 + "/license_info_ref.txt"; + EXPECT_TRUE(RteFsUtils::CmpFileMem(licRefFile, licenseText)); + // check if active project is set RteCprjProject* activeCprjProject = rteKernel.GetActiveCprjProject(); ASSERT_NE(activeCprjProject, nullptr); diff --git a/libs/rteutils/include/RteConstants.h b/libs/rteutils/include/RteConstants.h index c62cbb143..f0fda5142 100644 --- a/libs/rteutils/include/RteConstants.h +++ b/libs/rteutils/include/RteConstants.h @@ -72,6 +72,7 @@ class RteConstants static constexpr const char PREFIX_CVERSION_CHAR = *PREFIX_CVERSION; static constexpr const char* SUFFIX_PACK_VENDOR = "::"; static constexpr const char* PREFIX_PACK_VERSION = "@"; + static constexpr const char PREFIX_PACK_VERSION_CHAR = '@'; }; diff --git a/libs/rteutils/include/RteUtils.h b/libs/rteutils/include/RteUtils.h index e3b1e2d7e..722032263 100644 --- a/libs/rteutils/include/RteUtils.h +++ b/libs/rteutils/include/RteUtils.h @@ -33,13 +33,6 @@ class RteUtils RteUtils() {}; // private constructor to forbid instantiation of a utility class public: - /** - * @brief determine Pack ID specific to Pack Manager - * @param path must have the following convention: - * [path][\\].....(pack|pdsc) - * @return Pack ID specific to Pack Manager - */ - static std::string GetPackID(const std::string &path); /** * @brief determine prefix of a string * @param s string containing the prefix @@ -100,19 +93,6 @@ class RteUtils */ static bool EqualNoCase(const std::string& a, const std::string& b); - /** - * @brief extract vendor name from package ID - * @param packageId package ID - * @return vendor name - */ - static std::string VendorFromPackageId(const std::string &packageId); - /** - * @brief determine package name from package ID - * @param packageId package ID - * @return package name from package ID - */ - static std::string NameFromPackageId(const std::string &packageId); - /** * @brief construct an ID string from a vector of key-value pairs * @param elements vector with key-value pairs diff --git a/libs/rteutils/src/RteUtils.cpp b/libs/rteutils/src/RteUtils.cpp index 21fe912f3..bf2018a59 100644 --- a/libs/rteutils/src/RteUtils.cpp +++ b/libs/rteutils/src/RteUtils.cpp @@ -531,32 +531,6 @@ std::string RteUtils::Trim(const std::string& str) { return str.substr(begin, range); } - -string RteUtils::GetPackID(const string &path) { - string res; - size_t pos = path.find_last_of('/') + 1; // string::npos + 1 = 0 in case of file name without path - size_t pos2 = path.find_last_of('.'); - if (pos2 != string::npos) { - res = path.substr(pos, pos2 - pos); // res := vendor.name.majv.minv.minv2 - if (res.find('.') != string::npos) - res.replace(res.find('.'), 1, "::"); - if (res.find('.') != string::npos) - res.replace(res.find('.'), 1, "::"); - } - return res; -} - -string RteUtils::VendorFromPackageId(const std::string &packageId) { - // assumed packageId format is conform - return std::string(packageId.substr(0, packageId.find_first_of('.'))); -} - -string RteUtils::NameFromPackageId(const std::string &packageId) { - // assumed packageId format is conform - size_t pos = packageId.find_first_of("."); - return std::string(packageId.substr(pos + 1, packageId.find('.', pos+1) - pos - 1)); -} - string RteUtils::ConstructID(const std::vector>& elements) { string id; for (const auto& element : elements) { diff --git a/libs/rteutils/test/src/RteUtilsTest.cpp b/libs/rteutils/test/src/RteUtilsTest.cpp index 244e389b3..040781389 100644 --- a/libs/rteutils/test/src/RteUtilsTest.cpp +++ b/libs/rteutils/test/src/RteUtilsTest.cpp @@ -69,6 +69,26 @@ TEST(RteUtilsTest, GetSuffix) { EXPECT_EQ(RteUtils::GetSuffix("prefix-suffix", '-'), "suffix"); } +TEST(RteUtilsTest, RemoveSuffixByString) { + + EXPECT_EQ(RteUtils::RemoveSuffixByString("prefix:suffix"), "prefix"); + EXPECT_TRUE(RteUtils::RemoveSuffixByString("prefix:suffix", "-").empty()); + EXPECT_EQ(RteUtils::RemoveSuffixByString("prefix::suffix", "::"), "prefix"); + + EXPECT_TRUE(RteUtils::RemoveSuffixByString("prefix-suffix").empty()); + EXPECT_EQ(RteUtils::RemoveSuffixByString("prefix-suffix", "-"), "prefix"); +} + +TEST(RteUtilsTest, RemovePrefixByString) { + + EXPECT_EQ(RteUtils::RemovePrefixByString("prefix:suffix"), "suffix"); + EXPECT_EQ(RteUtils::RemovePrefixByString("prefix:suffix", "-"), "prefix:suffix"); + EXPECT_EQ(RteUtils::RemovePrefixByString("prefix::suffix", "::"), "suffix"); + + EXPECT_EQ(RteUtils::RemovePrefixByString("prefix-suffix"), "prefix-suffix"); + EXPECT_EQ(RteUtils::RemovePrefixByString("prefix-suffix", "-"), "suffix"); +} + TEST(RteUtilsTest, ExtractFileExtension) { EXPECT_TRUE(RteUtils::ExtractFileExtension("myfile").empty()); @@ -302,30 +322,6 @@ TEST(RteUtilsTest, GetFullVendorString) EXPECT_EQ("Silicon Labs:21", DeviceVendor::GetFullVendorString("EnergyMicro::97")); } -TEST(RteUtilsTest, VendorFromPackageId) -{ - string packageId, vendor; - packageId = "Vendor.Name.version"; - vendor = RteUtils::VendorFromPackageId(packageId); - EXPECT_EQ(vendor, "Vendor"); - - packageId = "VendorNameversion"; - vendor = RteUtils::VendorFromPackageId(packageId); - EXPECT_EQ(false, (0 == vendor.compare("vendor")) ? true : false); -} - -TEST(RteUtilsTest, NameFromPackageId) -{ - string packageId, name; - packageId = "Vendor.Name.Version"; - name = RteUtils::NameFromPackageId(packageId); - EXPECT_EQ(name, "Name"); - - packageId = "VendorNameversion"; - name = RteUtils::NameFromPackageId(packageId); - EXPECT_EQ(false, (0 == name.compare("Name")) ? true : false); -} - TEST(RteUtils, AppendFileVersion) { EXPECT_EQ("./foo/bar.ext.base@1.2.0", RteUtils::AppendFileBaseVersion("./foo/bar.ext", "1.2.0")); diff --git a/libs/rteutils/test/src/VersionCmpTests.cpp b/libs/rteutils/test/src/VersionCmpTests.cpp index 1df03b55b..667d16200 100644 --- a/libs/rteutils/test/src/VersionCmpTests.cpp +++ b/libs/rteutils/test/src/VersionCmpTests.cpp @@ -36,6 +36,10 @@ TEST(VersionCmpTest, VersionCompare) { EXPECT_EQ( 2, VersionCmp::Compare("6.6.0", "6.5.0")); EXPECT_EQ( 3, VersionCmp::Compare("7.5.0", "6.5.0")); EXPECT_EQ(-1, VersionCmp::Compare("6.5.0-", "6.5.0-a", true)); + EXPECT_EQ(0, VersionCmp::Compare("6.5.0-a+b", "6.5.0-a+B", true)); + + EXPECT_EQ(VersionCmp::RemoveVersionMeta("1.2.3-a+b"), "1.2.3-a"); + EXPECT_EQ(VersionCmp::RemoveVersionMeta("1.2.3+b"), "1.2.3"); /*Ideally It should fail as the input given is not compliant to Semantic versioning*/ diff --git a/test/packs/ARM/RteTest/0.1.0/ARM.RteTest.pdsc b/test/packs/ARM/RteTest/0.1.0/ARM.RteTest.pdsc index c87b7b100..1269f9eba 100644 --- a/test/packs/ARM/RteTest/0.1.0/ARM.RteTest.pdsc +++ b/test/packs/ARM/RteTest/0.1.0/ARM.RteTest.pdsc @@ -8,6 +8,19 @@ Testing pack reader and RTE model features. Some PackChk warnings are expected: missing version of config file + + + + + + + + + + + + + @@ -78,13 +91,13 @@ - + RteTest Exclusive API - + RteTes Non-Exclusive API @@ -94,7 +107,7 @@ - + Test bundle one https://arm-software.github.io/CMSIS_5/Pack/html/pdsc_components_pg.html#Component_Bundle @@ -153,7 +166,7 @@ - + Adding PreInclude on component level #define COMPONENT_LEVEL 1 diff --git a/test/packs/ARM/RteTest/0.1.0/licenses/ProprietaryLicense.txt b/test/packs/ARM/RteTest/0.1.0/licenses/ProprietaryLicense.txt new file mode 100644 index 000000000..d5bf5363a --- /dev/null +++ b/test/packs/ARM/RteTest/0.1.0/licenses/ProprietaryLicense.txt @@ -0,0 +1,5 @@ +Proprietary License to test licenseSets pdsc element: + +https://open-cmsis-pack.github.io/Open-CMSIS-Pack-Spec/main/html/pdsc_licenseSets_pg.html + +in fact, all files in this repo are under apache-2.0. license \ No newline at end of file diff --git a/test/packs/ARM/RteTest/0.1.0/licenses/apache2.0.txt b/test/packs/ARM/RteTest/0.1.0/licenses/apache2.0.txt new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/test/packs/ARM/RteTest/0.1.0/licenses/apache2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/test/packs/ARM/RteTest/0.1.0/licenses/licenseBsd.txt b/test/packs/ARM/RteTest/0.1.0/licenses/licenseBsd.txt new file mode 100644 index 000000000..b9b433660 --- /dev/null +++ b/test/packs/ARM/RteTest/0.1.0/licenses/licenseBsd.txt @@ -0,0 +1,6 @@ +Copyright 2023 Arm Ltd. +The 3-Clause BSD License + +File to test licenseSets pdsc element: +https://open-cmsis-pack.github.io/Open-CMSIS-Pack-Spec/main/html/pdsc_licenseSets_pg.html +in fact, all files in this repo are under apache-2.0. license \ No newline at end of file diff --git a/test/packs/ARM/RteTest/0.1.0/licenses/licenseMit.txt b/test/packs/ARM/RteTest/0.1.0/licenses/licenseMit.txt new file mode 100644 index 000000000..ef145973a --- /dev/null +++ b/test/packs/ARM/RteTest/0.1.0/licenses/licenseMit.txt @@ -0,0 +1,6 @@ +Copyright 2023 Arm Ltd. +MIT License + +File to test licenseSets pdsc element: +https://open-cmsis-pack.github.io/Open-CMSIS-Pack-Spec/main/html/pdsc_licenseSets_pg.html +in fact, all files in this repo are under apache-2.0. license \ No newline at end of file diff --git a/test/packs/ARM/RteTest_DFP/0.2.0/ARM.RteTest_DFP.pdsc b/test/packs/ARM/RteTest_DFP/0.2.0/ARM.RteTest_DFP.pdsc index 31170d352..a6c08d9de 100644 --- a/test/packs/ARM/RteTest_DFP/0.2.0/ARM.RteTest_DFP.pdsc +++ b/test/packs/ARM/RteTest_DFP/0.2.0/ARM.RteTest_DFP.pdsc @@ -4,7 +4,7 @@ RteTest_DFP RTE test of DFP pack, extraction from ARM.CMSIS ARM - + Doc/license.txt http://www.keil.com/pack/ diff --git a/test/packs/ARM/RteTest_DFP/0.2.0/Doc/license.txt b/test/packs/ARM/RteTest_DFP/0.2.0/Doc/license.txt new file mode 100644 index 000000000..d09e3581f --- /dev/null +++ b/test/packs/ARM/RteTest_DFP/0.2.0/Doc/license.txt @@ -0,0 +1 @@ +dummy license to test license sets behavior \ No newline at end of file diff --git a/test/projects/RteTestM3/license_info_ref.txt b/test/projects/RteTestM3/license_info_ref.txt new file mode 100644 index 000000000..620dc9f83 --- /dev/null +++ b/test/projects/RteTestM3/license_info_ref.txt @@ -0,0 +1,37 @@ +licenses: + - license: Proprietary Test License + license-agreement: %CMSIS_PACK_ROOT%/ARM/RteTest/0.1.0/licenses/ProprietaryLicense.txt + packs: + - pack: ARM::RteTest@0.1.0 + components: + - component: ARM::RteTest:ComponentLevel@0.0.1 + + - license: + license-agreement: %CMSIS_PACK_ROOT%/ARM/RteTest_DFP/0.2.0/Doc/license.txt + packs: + - pack: ARM::RteTest_DFP@0.2.0 + components: + - component: ::RteTest:CORE(API) + - component: ARM::Device:Startup&RteTest Startup@2.0.3 + - component: ARM::RteTest:CORE@0.1.1 + + - license: BSD-3-Clause + packs: + - pack: ARM::RteTest@0.1.0 + components: + - component: ARM::RteTest:Dependency:Variant@0.9.9 + - component: ARM::RteTest:G_A@1.0.0 + - component: ARM::RteTest:GlobalFile@0.0.3 + - component: ARM::RteTest:GlobalLevel@0.0.2 + - component: ARM::RteTest:LocalFile@0.0.3 + + - license: MIT + packs: + - pack: ARM::RteTest@0.1.0 + components: + - component: ARM::RteTest:Dependency:Variant@0.9.9 + - component: ARM::RteTest:G_A@1.0.0 + - component: ARM::RteTest:GlobalFile@0.0.3 + - component: ARM::RteTest:GlobalLevel@0.0.2 + - component: ARM::RteTest:LocalFile@0.0.3 + diff --git a/test/projects/RteTestM4/regions_RteTest_ARMCM4_FP_ref.h b/test/projects/RteTestM4/regions_RteTest_ARMCM4_FP_ref.h index 4a763b09d..ce18c11bd 100644 --- a/test/projects/RteTestM4/regions_RteTest_ARMCM4_FP_ref.h +++ b/test/projects/RteTestM4/regions_RteTest_ARMCM4_FP_ref.h @@ -4,7 +4,7 @@ //-------- <<< Use Configuration Wizard in Context Menu >>> -------------------- -// Device pack: ARM.RteTest_DFP.0.2.0 +// Device pack: ARM::RteTest_DFP@0.2.0 // Device pack used to generate this file // ROM Configuration diff --git a/test/projects/RteTestM4/regions_RteTest_CM4_board_ref.h b/test/projects/RteTestM4/regions_RteTest_CM4_board_ref.h index 401ac202a..9d5fab89a 100644 --- a/test/projects/RteTestM4/regions_RteTest_CM4_board_ref.h +++ b/test/projects/RteTestM4/regions_RteTest_CM4_board_ref.h @@ -4,10 +4,10 @@ //-------- <<< Use Configuration Wizard in Context Menu >>> -------------------- -// Board pack: ARM.RteTestBoard.0.1.0 +// Board pack: ARM::RteTestBoard@0.1.0 // Board pack used to generate this file -// Device pack: ARM.RteTest_DFP.0.2.0 +// Device pack: ARM::RteTest_DFP@0.2.0 // Device pack used to generate this file // ROM Configuration diff --git a/tools/buildmgr/cbuild/src/CbuildLayer.cpp b/tools/buildmgr/cbuild/src/CbuildLayer.cpp index 93ca1aa29..4f9eb31cd 100644 --- a/tools/buildmgr/cbuild/src/CbuildLayer.cpp +++ b/tools/buildmgr/cbuild/src/CbuildLayer.cpp @@ -95,7 +95,7 @@ bool CbuildLayer::Extract(const CbuildLayerArgs& args) { set cprjPackIDList; const auto cprjPacks = m_cprj->packages->GetChildren(); for (auto cprjPack : cprjPacks) { - cprjPackIDList.insert(cprjPack->GetAttribute("vendor") + '.' + cprjPack->GetAttribute("name") + "." + cprjPack->GetAttribute("version")); + cprjPackIDList.insert(RtePackage::GetPackageIDfromAttributes(*cprjPack)); } // Set absolute output path @@ -148,11 +148,11 @@ bool CbuildLayer::Extract(const CbuildLayerArgs& args) { XMLTreeElement* packagesElement = rootElement->CreateElement("packages"); for (auto layerPack : m_layerPackages[layerName]) { const bool fixedVersion = cprjPackIDList.find(layerPack) != cprjPackIDList.end(); - if (!fixedVersion) layerPack = layerPack.substr(0, layerPack.find('.', layerPack.find('.')+1)); + if (!fixedVersion) { + layerPack = RtePackage::CommonIdFromId(layerPack); + } for (auto cprjPack : cprjPacks) { - string cprjPackID = cprjPack->GetAttribute("vendor") + '.' + cprjPack->GetAttribute("name"); - const string& cprjPackVersion = cprjPack->GetAttribute("version"); - if (fixedVersion) cprjPackID += '.' + cprjPackVersion; + string cprjPackID = RtePackage::GetPackageIDfromAttributes(*cprjPack, fixedVersion); if (layerPack == cprjPackID) { CopyElement(packagesElement, cprjPack); break; @@ -658,7 +658,7 @@ bool CbuildLayer::Remove(const CbuildLayerArgs& args) { set cprjPackIDList; auto cprjPacks = m_cprj->packages->GetChildren(); for (auto cprjPack : cprjPacks) { - cprjPackIDList.insert(cprjPack->GetAttribute("vendor") + '.' + cprjPack->GetAttribute("name") + "." + cprjPack->GetAttribute("version")); + cprjPackIDList.insert(RtePackage::GetPackageIDfromAttributes(*cprjPack)); } // Iterate over list of layers @@ -691,11 +691,9 @@ bool CbuildLayer::Remove(const CbuildLayerArgs& args) { bool fixedVersion = cprjPackIDList.find(packTobeRemoved) != cprjPackIDList.end(); cprjPacks = m_cprj->packages->GetChildren(); for (auto cprjPack : cprjPacks) { - string cprjPackID = cprjPack->GetAttribute("vendor") + '.' + cprjPack->GetAttribute("name"); - const string& cprjPackVersion = cprjPack->GetAttribute("version"); - if (fixedVersion) cprjPackID += '.' + cprjPackVersion; + string cprjPackID = RtePackage::GetPackageIDfromAttributes(*cprjPack, fixedVersion); if ((fixedVersion && (packTobeRemoved == cprjPackID)) || - (!fixedVersion && (packTobeRemoved.find(cprjPackID) != string::npos) && cprjPackVersion.empty())) { + (!fixedVersion && (packTobeRemoved.find(cprjPackID) != string::npos))) { m_cprj->packages->RemoveChild(cprjPack, true); } } diff --git a/tools/buildmgr/cbuild/src/CbuildModel.cpp b/tools/buildmgr/cbuild/src/CbuildModel.cpp index 0462fc04c..08f1b7ae3 100644 --- a/tools/buildmgr/cbuild/src/CbuildModel.cpp +++ b/tools/buildmgr/cbuild/src/CbuildModel.cpp @@ -1456,18 +1456,7 @@ bool CbuildModel::EvalAccessSequence() { if (!GetAccessSequence(offsetContext, sequence, packStr, '(', ')')) { return false; } - string packInfoStr = packStr; - if (packInfoStr.find("::") != string::npos) { - vendor = RteUtils::RemoveSuffixByString(packInfoStr, "::"); - packInfoStr = RteUtils::RemovePrefixByString(packInfoStr, "::"); - name = RteUtils::GetPrefix(packInfoStr, '@'); - } - else { - vendor = RteUtils::GetPrefix(packInfoStr, '@'); - } - version = RteUtils::GetSuffix(packInfoStr, '@'); - - string packId = vendor + "." + name + (version.empty() ? "" : "." + version); + string packId = packStr; auto packages = m_cprjTarget->GetModel()->GetPackages(); for (const auto& pack : packages) { if (pack.second->GetPackageID(false) == packId || pack.second->GetPackageID() == packId) { diff --git a/tools/projmgr/include/ProjMgrUtils.h b/tools/projmgr/include/ProjMgrUtils.h index d056556b6..0ad97913c 100644 --- a/tools/projmgr/include/ProjMgrUtils.h +++ b/tools/projmgr/include/ProjMgrUtils.h @@ -169,14 +169,6 @@ class ProjMgrUtils { static constexpr const char* GCC_LIB_SUFFIX = ".a"; static constexpr const char* IAR_LIB_SUFFIX = ".a"; - /** - * @brief get fully specified package identifier - * @param rte package - * @return string package identifier - */ - static std::string GetPackageID(const RteItem* pack); - static std::string GetPackageID(const std::string& vendor, const std::string& name, const std::string& version); - /** * @brief read gpdsc file * @param path to gpdsc file diff --git a/tools/projmgr/src/ProjMgrUtils.cpp b/tools/projmgr/src/ProjMgrUtils.cpp index c983cd545..ea3d6d83f 100644 --- a/tools/projmgr/src/ProjMgrUtils.cpp +++ b/tools/projmgr/src/ProjMgrUtils.cpp @@ -19,29 +19,6 @@ using namespace std; -string ProjMgrUtils::GetPackageID(const RteItem* pack) { - if (!pack) { - return RteUtils::EMPTY_STRING; - } - const auto& vendor = pack->GetVendorString().empty() ? "" : pack->GetVendorString() + RteConstants::SUFFIX_PACK_VENDOR; - const vector> elements = { - {"", vendor}, - {"", pack->GetName()}, - {RteConstants::PREFIX_PACK_VERSION, pack->GetVersionString()}, - }; - return RteUtils::ConstructID(elements); -} - -string ProjMgrUtils::GetPackageID(const string& packVendor, const string& packName, const string& packVersion) { - const auto& vendor = packVendor + RteConstants::SUFFIX_PACK_VENDOR; - const vector> elements = { - {"", vendor}, - {"", packName}, - {RteConstants::PREFIX_PACK_VERSION, packVersion}, - }; - return RteUtils::ConstructID(elements); -} - RtePackage* ProjMgrUtils::ReadGpdscFile(const string& gpdsc, bool& valid) { fs::path path(gpdsc); error_code ec; diff --git a/tools/projmgr/src/ProjMgrWorker.cpp b/tools/projmgr/src/ProjMgrWorker.cpp index 8094d49ea..a47851204 100644 --- a/tools/projmgr/src/ProjMgrWorker.cpp +++ b/tools/projmgr/src/ProjMgrWorker.cpp @@ -989,7 +989,7 @@ bool ProjMgrWorker::ProcessDevice(ContextItem& context) { } const auto& boardPackage = matchedBoard->GetPackage(); - context.packages.insert({ ProjMgrUtils::GetPackageID(boardPackage), boardPackage }); + context.packages.insert({ boardPackage->GetID(), boardPackage }); context.targetAttributes["Bname"] = matchedBoard->GetName(); context.targetAttributes["Bvendor"] = matchedBoard->GetVendorName(); context.targetAttributes["Brevision"] = matchedBoard->GetRevision(); @@ -1115,7 +1115,7 @@ bool ProjMgrWorker::ProcessDevice(ContextItem& context) { } } - context.packages.insert({ ProjMgrUtils::GetPackageID(matchedDevice->GetPackage()), matchedDevice->GetPackage() }); + context.packages.insert({ matchedDevice->GetPackageID(true), matchedDevice->GetPackage() }); return true; } @@ -1288,12 +1288,12 @@ bool ProjMgrWorker::ProcessComponents(ContextItem& context) { // Insert matched component into context list context.components.insert({ componentId, { matchedComponentInstance, &item, generatorId } }); const auto& componentPackage = matchedComponent->GetPackage(); - context.packages.insert({ ProjMgrUtils::GetPackageID(componentPackage), componentPackage }); + context.packages.insert({ componentPackage->GetID(), componentPackage }); if (matchedComponent->HasApi(context.rteActiveTarget)) { const auto& api = matchedComponent->GetApi(context.rteActiveTarget, false); if (api) { const auto& apiPackage = api->GetPackage(); - context.packages.insert({ ProjMgrUtils::GetPackageID(apiPackage), apiPackage }); + context.packages.insert({ apiPackage->GetID(), apiPackage }); } } } @@ -2687,7 +2687,7 @@ bool ProjMgrWorker::ListPacks(vector&packs, bool missingPacks, const str GetRequiredPdscFiles(context, m_packRoot, errMsgs); // Get missing packs identifiers for (const auto& pack : context.missingPacks) { - packsSet.insert(ProjMgrUtils::GetPackageID(pack.vendor, pack.name, pack.version)); + packsSet.insert(RtePackage::ComposePackageID(pack.vendor, pack.name, pack.version)); } if (!missingPacks) { if (context.packRequirements.size() > 0) { @@ -2713,7 +2713,7 @@ bool ProjMgrWorker::ListPacks(vector&packs, bool missingPacks, const str // Load packs and get loaded packs identifiers m_kernel->LoadAndInsertPacks(m_loadedPacks, pdscFiles); for (const auto& pack : m_loadedPacks) { - packsSet.insert(ProjMgrUtils::GetPackageID(pack) + " (" + pack->GetPackageFileName() + ")"); + packsSet.insert(pack->GetID() + " (" + pack->GetPackageFileName() + ")"); } } if (errMsgs.size() > 0) { @@ -2747,7 +2747,7 @@ bool ProjMgrWorker::ListBoards(vector& boards, const string& filter) { const string& boardVendor = board->GetVendorName(); const string& boardName = board->GetName(); const string& boardRevision = board->GetRevision(); - const string& boardPack = ProjMgrUtils::GetPackageID(board->GetPackage()); + const string& boardPack = board->GetPackageID(true); boardsSet.insert(boardVendor + "::" + boardName + (!boardRevision.empty() ? ":" + boardRevision : "") + " (" + boardPack + ")"); } } @@ -2781,7 +2781,7 @@ bool ProjMgrWorker::ListDevices(vector& devices, const string& filter) { for (const auto& deviceItem : filteredModelDevices) { const string& deviceVendor = deviceItem->GetVendorName(); const string& deviceName = deviceItem->GetFullDeviceName(); - const string& devicePack = ProjMgrUtils::GetPackageID(deviceItem->GetPackage()); + const string& devicePack = deviceItem->GetPackageID(); if (deviceItem->GetProcessorCount() > 1) { const auto& processors = deviceItem->GetProcessors(); for (const auto& processor : processors) { @@ -2857,7 +2857,7 @@ bool ProjMgrWorker::ListComponents(vector& components, const string& fil componentIdsVec = filteredIds; } for (const auto& componentId : componentIdsVec) { - components.push_back(componentId + " (" + ProjMgrUtils::GetPackageID(componentMap[componentId]->GetPackage()) + ")"); + components.push_back(componentId + " (" + componentMap[componentId]->GetPackageID() + ")"); } return true; } diff --git a/tools/projmgr/src/ProjMgrYamlEmitter.cpp b/tools/projmgr/src/ProjMgrYamlEmitter.cpp index 5899f7198..ac39f1ddf 100644 --- a/tools/projmgr/src/ProjMgrYamlEmitter.cpp +++ b/tools/projmgr/src/ProjMgrYamlEmitter.cpp @@ -156,7 +156,7 @@ void ProjMgrYamlCbuild::SetComponentsNode(YAML::Node node, const ContextItem* co YAML::Node componentNode; SetNodeValue(componentNode[YAML_COMPONENT], componentId); SetNodeValue(componentNode[YAML_CONDITION], rteComponent->GetConditionID()); - SetNodeValue(componentNode[YAML_FROM_PACK], ProjMgrUtils::GetPackageID(rteComponent->GetPackage())); + SetNodeValue(componentNode[YAML_FROM_PACK], rteComponent->GetPackageID()); SetNodeValue(componentNode[YAML_SELECTED_BY], componentItem->component); const string& rteDir = rteComponent->GetAttribute("rtedir"); if (!rteDir.empty()) { @@ -296,7 +296,7 @@ void ProjMgrYamlCbuild::SetConstructedFilesNode(YAML::Node node, const ContextIt } } // constructed RTE_Components.h - const auto& rteComponents = context->rteActiveProject->GetProjectPath() + + const auto& rteComponents = context->rteActiveProject->GetProjectPath() + context->rteActiveProject->GetRteComponentsH(context->rteActiveTarget->GetName(), ""); YAML::Node rteComponentsNode; SetNodeValue(rteComponentsNode[YAML_FILE], FormatPath(rteComponents, context->directories.cprj)); diff --git a/tools/projmgr/test/src/ProjMgrUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUnitTests.cpp index 59f34e47f..96b5fe90f 100644 --- a/tools/projmgr/test/src/ProjMgrUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUnitTests.cpp @@ -2702,11 +2702,11 @@ TEST_F(ProjMgrUnitTests, Convert_ValidationResults_Filtering) { vector> testData = { {"recursive", 1, "\ warning csolution: RTE Model reports:\n\ -ARM.RteTestRecursive.0.1.0: condition 'Recursive': error #503: direct or indirect recursion detected\n\ +ARM::RteTestRecursive@0.1.0: condition 'Recursive': error #503: direct or indirect recursion detected\n\ error csolution: no component was found with identifier 'RteTest:Check:Recursive'\n"}, {"missing-condition", 0, "\ warning csolution: RTE Model reports:\n\ -ARM.RteTestMissingCondition.0.1.0: component 'ARM::RteTest:Check:MissingCondition@0.9.9(MissingCondition)[]': error #501: error(s) in component definition:\n\ +ARM::RteTestMissingCondition@0.1.0: component 'ARM::RteTest:Check:MissingCondition@0.9.9(MissingCondition)[]': error #501: error(s) in component definition:\n\ condition 'MissingCondition' not found\n"}, }; diff --git a/tools/projmgr/test/src/ProjMgrUtilsUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUtilsUnitTests.cpp index f81cf8cce..d159c51bf 100644 --- a/tools/projmgr/test/src/ProjMgrUtilsUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUtilsUnitTests.cpp @@ -29,7 +29,7 @@ TEST_F(ProjMgrUtilsUnitTests, GetPackageID) { }; RteItem item(attributes); item.SetTag("require"); - EXPECT_EQ("Vendor::Name@8.8.8", GetPackageID(&item)); + EXPECT_EQ("Vendor::Name@8.8.8", item.GetPackageID()); } TEST_F(ProjMgrUtilsUnitTests, ReadGpdscFile) { diff --git a/tools/projmgr/test/src/ProjMgrWorkerUnitTests.cpp b/tools/projmgr/test/src/ProjMgrWorkerUnitTests.cpp index 9178d6bda..4323c6f32 100644 --- a/tools/projmgr/test/src/ProjMgrWorkerUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrWorkerUnitTests.cpp @@ -497,7 +497,7 @@ TEST_F(ProjMgrWorkerUnitTests, LoadDuplicatePacks) { EXPECT_TRUE(LoadPacks(context)); // Check if only one pack is loaded ASSERT_EQ(1, m_loadedPacks.size()); - EXPECT_EQ("ARM.RteTest_DFP.0.2.0", (*m_loadedPacks.begin())->GetPackageID()); + EXPECT_EQ("ARM::RteTest_DFP@0.2.0", (*m_loadedPacks.begin())->GetPackageID()); } TEST_F(ProjMgrWorkerUnitTests, LoadDuplicatePacksFromDifferentPaths) { @@ -515,7 +515,7 @@ TEST_F(ProjMgrWorkerUnitTests, LoadDuplicatePacksFromDifferentPaths) { // Check if only one pack is loaded ASSERT_EQ(1, m_loadedPacks.size()); - EXPECT_EQ("ARM.RteTest_DFP.0.2.0", (*m_loadedPacks.begin())->GetPackageID()); + EXPECT_EQ("ARM::RteTest_DFP@0.2.0", (*m_loadedPacks.begin())->GetPackageID()); // Check that warning is issued EXPECT_FALSE(m_model->Validate()); @@ -531,7 +531,7 @@ TEST_F(ProjMgrWorkerUnitTests, LoadRequiredPacks) { EXPECT_TRUE(LoadPacks(context)); // Check if only one pack is loaded ASSERT_EQ(1, m_loadedPacks.size()); - EXPECT_EQ("ARM.RteTest_DFP.0.2.0", (*m_loadedPacks.begin())->GetPackageID()); + EXPECT_EQ("ARM::RteTest_DFP@0.2.0", (*m_loadedPacks.begin())->GetPackageID()); } TEST_F(ProjMgrWorkerUnitTests, LoadExactPackVersion) { @@ -541,7 +541,7 @@ TEST_F(ProjMgrWorkerUnitTests, LoadExactPackVersion) { EXPECT_TRUE(LoadPacks(context)); // Check if only one pack is loaded ASSERT_EQ(1, m_loadedPacks.size()); - EXPECT_EQ("ARM.RteTest_DFP.0.1.1", (*m_loadedPacks.begin())->GetPackageID()); + EXPECT_EQ("ARM::RteTest_DFP@0.1.1", (*m_loadedPacks.begin())->GetPackageID()); } TEST_F(ProjMgrWorkerUnitTests, LoadPacksNoPackage) { @@ -560,7 +560,7 @@ TEST_F(ProjMgrWorkerUnitTests, LoadFilteredPack_1) { EXPECT_TRUE(LoadPacks(context)); // Check if only one pack is loaded ASSERT_EQ(1, m_loadedPacks.size()); - EXPECT_EQ("ARM.RteTestGenerator.0.1.0", (*m_loadedPacks.begin())->GetPackageID()); + EXPECT_EQ("ARM::RteTestGenerator@0.1.0", (*m_loadedPacks.begin())->GetPackageID()); } TEST_F(ProjMgrWorkerUnitTests, LoadFilteredPack_2) { @@ -582,7 +582,7 @@ TEST_F(ProjMgrWorkerUnitTests, LoadFilteredPack_3) { ContextItem context; EXPECT_TRUE(LoadPacks(context)); ASSERT_EQ(1, m_loadedPacks.size()); - EXPECT_EQ("ARM.RteTest_DFP.0.2.0", (*m_loadedPacks.begin())->GetPackageID()); + EXPECT_EQ("ARM::RteTest_DFP@0.2.0", (*m_loadedPacks.begin())->GetPackageID()); } TEST_F(ProjMgrWorkerUnitTests, LoadFilteredPack_4) { @@ -604,7 +604,7 @@ TEST_F(ProjMgrWorkerUnitTests, LoadFilteredPack_5) { ContextItem context; EXPECT_TRUE(LoadPacks(context)); ASSERT_EQ(1, m_loadedPacks.size()); - EXPECT_EQ("ARM.RteTest_DFP.0.2.0", (*m_loadedPacks.begin())->GetPackageID()); + EXPECT_EQ("ARM::RteTest_DFP@0.2.0", (*m_loadedPacks.begin())->GetPackageID()); } TEST_F(ProjMgrWorkerUnitTests, LoadPack_Filter_Unknown) {