diff --git a/libs/rtemodel/include/RteModel.h b/libs/rtemodel/include/RteModel.h index 21f54289c..d445a1c35 100644 --- a/libs/rtemodel/include/RteModel.h +++ b/libs/rtemodel/include/RteModel.h @@ -616,6 +616,13 @@ class RteGlobalModel : public RteModel */ void ClearModel() override; + /** + * @brief purges non-existing packs and optionally explicit packs; clears model and projects if at least one pack was removed + * @param purgeExplicit when true, remove all PackageState::PS_EXPLICIT_PATH packs + * @returns true if at least one pack has been removed + */ + bool PurgeModel(bool purgeExplicit); + /** * @brief setter for RteCallback object * @param callback given RteCallback object to set diff --git a/libs/rtemodel/include/RtePackage.h b/libs/rtemodel/include/RtePackage.h index bafacacf0..68e3f405d 100644 --- a/libs/rtemodel/include/RtePackage.h +++ b/libs/rtemodel/include/RtePackage.h @@ -1336,10 +1336,11 @@ class RtePackRegistry bool ErasePack(const std::string& pdscFile); /** - * @brief removes all non-existing packs + * @brief removes all non-existing packs and optionally explicitly specified packs + * @param purgeExplicit flag to remove all PackageState::PS_EXPLICIT_PATH packs * @return true if at least one pack was removed */ - bool PurgePacks(); + bool PurgePacks(bool purgeExplicit); /** * @brief get collection of loaded packs diff --git a/libs/rtemodel/src/RteKernel.cpp b/libs/rtemodel/src/RteKernel.cpp index db8dcaffb..c95f3586b 100644 --- a/libs/rtemodel/src/RteKernel.cpp +++ b/libs/rtemodel/src/RteKernel.cpp @@ -451,8 +451,6 @@ bool RteKernel::GetEffectivePdscFilesAsMap(map& pdscFiles, bool latest) const { - GetPackRegistry()->PurgePacks(); // remove non-existing files from the registry - map pdscMap; if(!GetEffectivePdscFilesAsMap(pdscMap, latest)) { return false; @@ -477,11 +475,7 @@ bool RteKernel::LoadAndInsertPacks(std::list& packs, std::listGetID(), packs); - if(!loadedPack || (loadedPack->GetPackageState() == PS_INSTALLED && pack->GetPackageState() == PS_EXPLICIT_PATH)) { - newPacks.push_back(pack); - } + newPacks.push_back(pack); } globalModel->InsertPacks(newPacks); diff --git a/libs/rtemodel/src/RteModel.cpp b/libs/rtemodel/src/RteModel.cpp index d982e378e..54e230288 100644 --- a/libs/rtemodel/src/RteModel.cpp +++ b/libs/rtemodel/src/RteModel.cpp @@ -392,17 +392,9 @@ void RteModel::InsertPack(RtePackage* package) } auto state = package->GetPackageState(); if(insertedPack->GetPackageState() == state) { - string pdscPath = RteFsUtils::MakePathCanonical(package->GetAbsolutePackagePath()); - if(pdscPath.find(m_rtePath) == 0) { // regular installed pack => error // duplicate, kept it in a temporary collection till validate; - m_packageDuplicates.push_back(package); - return; - } - string insertedPdscPath = RteFsUtils::MakePathCanonical(insertedPack->GetAbsolutePackagePath()); - if(insertedPdscPath.find(m_rtePath) == string::npos) { // inserted pack is also from outside => error - m_packageDuplicates.push_back(package); - return; - } + m_packageDuplicates.push_back(package); + return; } else if(state != PS_EXPLICIT_PATH) { return; // pack with explicit path must override installed pack } @@ -842,7 +834,14 @@ void RteGlobalModel::ClearModel() { ClearProjectTargets(); RteModel::ClearModel(); - m_packRegistry->PurgePacks(); // pack loading is expensive, only remove deleted +} + +bool RteGlobalModel::PurgeModel(bool purgeExplicit) { + if(m_packRegistry->PurgePacks(purgeExplicit)) { + Clear(); + return true; + } + return false; } diff --git a/libs/rtemodel/src/RtePackage.cpp b/libs/rtemodel/src/RtePackage.cpp index 323ac77e8..276caf916 100644 --- a/libs/rtemodel/src/RtePackage.cpp +++ b/libs/rtemodel/src/RtePackage.cpp @@ -1525,13 +1525,13 @@ bool RtePackRegistry::ErasePack(const std::string& pdscFile) return false; } -bool RtePackRegistry::PurgePacks() { +bool RtePackRegistry::PurgePacks(bool purgeExplicit) { ClearPdscMap(); // clear because packs can be added or removed after this call set toErase; // collect packs that no longer exist for(auto& [pdscFile, pack] : m_loadedPacks) { - if(!pack || !pack->Exists()) { + if(!pack || !pack->Exists() || (purgeExplicit && pack->GetPackageState() == PackageState::PS_EXPLICIT_PATH )) { toErase.insert(pdscFile); } } diff --git a/libs/rtemodel/test/src/RteModelTest.cpp b/libs/rtemodel/test/src/RteModelTest.cpp index bfefcc745..67bd397ca 100644 --- a/libs/rtemodel/test/src/RteModelTest.cpp +++ b/libs/rtemodel/test/src/RteModelTest.cpp @@ -40,14 +40,14 @@ TEST_F(RteModelTestConfig, PackRegistry) { EXPECT_TRUE(packRegistry->AddPack(pack)); EXPECT_FALSE(packRegistry->AddPack(pack)); // not second time EXPECT_EQ(packRegistry->GetPack("foo"), pack); - pack = new RtePackage(&testModel); + pack = new RtePackage(&testModel, PackageState::PS_EXPLICIT_PATH); pack->SetAttribute("name", "bar"); pack->SetRootFileName("foo"); EXPECT_TRUE(packRegistry->AddPack(pack, true)); EXPECT_EQ(packRegistry->GetPack("foo"), pack); EXPECT_EQ(packRegistry->GetLoadedPacks().size(), 1); - EXPECT_TRUE(packRegistry->PurgePacks()); + EXPECT_TRUE(packRegistry->PurgePacks(false)); // deleted because not exists EXPECT_EQ(packRegistry->GetPack("foo"), nullptr); EXPECT_FALSE(packRegistry->ErasePack("foo")); // already erased via Purge EXPECT_EQ(packRegistry->GetLoadedPacks().size(), 0); @@ -128,6 +128,13 @@ TEST_F(RteModelTestConfig, PackRegistryLoadPacks) { auto t1 = pack1->GetModificationTime(); EXPECT_NE(t, t1); EXPECT_EQ(pack1->GetFirstChild("dummy_child"), nullptr); // pack got loaded again => no added child + + // test RteGlobalModel::PurgeModel + pack1->SetPackageState(PackageState::PS_EXPLICIT_PATH); // simulate pack is explicit + auto globalModel = rteKernel.GetGlobalModel(); + + EXPECT_FALSE(globalModel->PurgeModel(false)); + EXPECT_TRUE(globalModel->PurgeModel(true)); } TEST(RteModelTest, LoadPacks) { diff --git a/tools/projmgr/src/ProjMgrRpcServer.cpp b/tools/projmgr/src/ProjMgrRpcServer.cpp index 56941e5b4..0170ef277 100644 --- a/tools/projmgr/src/ProjMgrRpcServer.cpp +++ b/tools/projmgr/src/ProjMgrRpcServer.cpp @@ -305,7 +305,10 @@ RpcArgs::SuccessResult RpcHandler::LoadPacks(void) { m_manager.Clear(); m_solutionLoaded = false; // clear project and global RTE data, packs stay loaded - ProjMgrKernel::Get()->GetGlobalModel()->Clear(); + auto globalModel = ProjMgrKernel::Get()->GetGlobalModel(); + globalModel->Clear(); + globalModel->PurgeModel(true); // clears also explicit and non-existing packs + m_worker.InitializeModel(); m_worker.SetLoadPacksPolicy(LoadPacksPolicy::ALL); result.success = m_worker.LoadAllRelevantPacks(); @@ -319,15 +322,30 @@ RpcArgs::SuccessResult RpcHandler::LoadPacks(void) { RpcArgs::SuccessResult RpcHandler::LoadSolution(const string& solution, const string& activeTarget) { m_bUseAllPacks = false; // loading solution will first use only listed packs m_packReferences.clear(); // will be updated + m_manager.Clear(); m_solutionLoaded = false; // assume not loaded yet - // clear only projects, global RTE data and packs stay loaded - ProjMgrKernel::Get()->GetGlobalModel()->ClearProjects(); + auto globalModel = ProjMgrKernel::Get()->GetGlobalModel(); + // remove non-existing and explicit packs + // clear model and projects if at least one pack is deleted + bool purged = globalModel->PurgeModel(true); + if(!purged) { + // only projects, global RTE data and packs stay loaded + globalModel->ClearProjects(); + } + RpcArgs::SuccessResult result = {false}; const auto csolutionFile = RteFsUtils::MakePathCanonical(solution); if(!regex_match(csolutionFile, regex(".*\\.csolution\\.(yml|yaml)"))) { result.message = solution + " is not a *.csolution.yml file"; return result; } + if(purged) { + // we need to add available packs to model again (the packs are already loaded) + m_worker.InitializeModel(); + m_worker.SetLoadPacksPolicy(LoadPacksPolicy::ALL); + result.success = m_worker.LoadAllRelevantPacks(); + m_worker.SetLoadPacksPolicy(LoadPacksPolicy::DEFAULT); + } // we disregard return value of m_manager.LoadSolution() here, because we tolerate some errors m_manager.LoadSolution(csolutionFile, activeTarget); map* contexts = nullptr; @@ -870,8 +888,15 @@ RpcArgs::ConvertSolutionResult RpcHandler::ConvertSolution(const string& solutio m_bUseAllPacks = false; // loading solution will first use only listed packs m_packReferences.clear(); // will be updated m_solutionLoaded = false; // assume not loaded - // clear only projects, RTE data and packs stay loaded - ProjMgrKernel::Get()->GetGlobalModel()->ClearProjects(); + m_manager.Clear(); + auto globalModel = ProjMgrKernel::Get()->GetGlobalModel(); + // remove non-existing and explicit packs + // clear model and projects if at least one pack is deleted + bool purged = globalModel->PurgeModel(true); + if(!purged) { + // only projects, global RTE data and packs stay loaded + globalModel->ClearProjects(); + } if(!m_manager.RunConvert(csolutionFile, activeTarget, updateRte) || !ProjMgrLogger::Get().GetErrors().empty()) { if(m_worker.HasVarDefineError()) { diff --git a/tools/projmgr/test/data/TestSolution/pack_path1.csolution.yml b/tools/projmgr/test/data/TestSolution/pack_path1.csolution.yml new file mode 100644 index 000000000..ec82e5662 --- /dev/null +++ b/tools/projmgr/test/data/TestSolution/pack_path1.csolution.yml @@ -0,0 +1,13 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/main/tools/projmgr/schemas/csolution.schema.json + +solution: + target-types: + - type: CM0 + device: RteTest_ARMCM0 + + packs: + - pack: ARM::RteTest_DFP + path: ../SolutionSpecificPack1 + + projects: + - project: pack_path.cproject.yml diff --git a/tools/projmgr/test/src/ProjMgrRpcTests.cpp b/tools/projmgr/test/src/ProjMgrRpcTests.cpp index c7114e741..dc48d64e9 100644 --- a/tools/projmgr/test/src/ProjMgrRpcTests.cpp +++ b/tools/projmgr/test/src/ProjMgrRpcTests.cpp @@ -33,10 +33,17 @@ class ProjMgrRpcTests : public ProjMgr, public ::testing::Test { string CreateLoadRequests(const string& solution, const string& activeTarget = RteUtils::EMPTY_STRING, - const vector& contextList = RteUtils::EMPTY_STRING_VECTOR + const vector& contextList = RteUtils::EMPTY_STRING_VECTOR, + bool loadPacks = true ); + + string FormatPackInfoRequests(const string& solution, const string& context, bool loadPacks); + + vector RunPackInfoRequests(const string& solution, const string& context, bool loadPacks); + bool CompareRpcResponse(const json& response, const string& ref); + int m_id = 0; }; string ProjMgrRpcTests::FormatRequest(const int id, const string& method, const json& params = json()) { @@ -50,15 +57,21 @@ string ProjMgrRpcTests::FormatRequest(const int id, const string& method, const return request.dump(); } -string ProjMgrRpcTests::CreateLoadRequests(const string& solution, const string& activeTarget, const vector& contextList) +string ProjMgrRpcTests::CreateLoadRequests(const string& solution, const string& activeTarget, const vector& contextList, bool loadPacks) { - string loadSolutionRequest; + + string requests; + if(loadPacks) { + m_id = 0; + requests = FormatRequest(++m_id, "LoadPacks"); + } if(!solution.empty()) { + string loadSolutionRequest; auto csolutionPath = testinput_folder + solution; - loadSolutionRequest = FormatRequest(2, "LoadSolution", json({{ "solution", csolutionPath }, { "activeTarget", activeTarget }})); + loadSolutionRequest = FormatRequest(++m_id, "LoadSolution", json({{ "solution", csolutionPath }, { "activeTarget", activeTarget }})); if(!contextList.empty()) { YAML::Node cbuildset; - cbuildset["cbuild-set"]["generated-by"] = "ProjMrgUnitTests"; + cbuildset["cbuild-set"]["generated-by"] = "ProjMgrUnitTests"; for(const auto& context : contextList) { cbuildset["cbuild-set"]["contexts"].push_back(map{ { "context", context } }); } @@ -70,8 +83,24 @@ string ProjMgrRpcTests::CreateLoadRequests(const string& solution, const string& cbuildsetFile << cbuildset << std::endl; cbuildsetFile.close(); } + requests += loadSolutionRequest; } - return FormatRequest(1, "LoadPacks") + loadSolutionRequest; + return requests; +} + +string ProjMgrRpcTests::FormatPackInfoRequests(const string& solution, const string& context, bool loadPacks) { + vector contextList = { + context + }; + auto requests = CreateLoadRequests(solution, "", contextList, loadPacks); + requests += FormatRequest(++m_id, "GetUsedItems", json({{ "context", context }})); + requests += FormatRequest(++m_id, "GetPacksInfo", json({{ "context", context }, {"all", false}})); + requests += FormatRequest(++m_id, "GetPacksInfo", json({{ "context", context }, {"all", true}})); + return requests; +} + +vector ProjMgrRpcTests::RunPackInfoRequests(const string& solution, const string& context, bool loadPacks = true) { + return RunRpcMethods( FormatPackInfoRequests(solution, context, loadPacks)); } bool ProjMgrRpcTests::CompareRpcResponse(const json& response, const string& ref) { @@ -92,6 +121,7 @@ vector ProjMgrRpcTests::RunRpcMethods(const string& strIn) { while(getline(iss, line)) { responses.push_back(json::parse(line)); } + m_id = 0; return responses; } @@ -1122,7 +1152,7 @@ TEST_F(ProjMgrRpcTests, PackReferenceMissing) { requests += FormatRequest(3, "GetUsedItems", json({{ "context", context }})); const auto& responses = RunRpcMethods(requests); EXPECT_TRUE(responses[2]["result"]["success"]); - auto packs = responses[2]["result"]["packs"]; + auto packs = responses[2]["result"]["packs"]; // Verify missing field for unresolved packs for(const auto& pack : packs) { if(!pack.contains("resolvedPack")) { @@ -1135,16 +1165,8 @@ TEST_F(ProjMgrRpcTests, PackReferenceMissing) { TEST_F(ProjMgrRpcTests, RpcGetPacksInfoSimple) { string context = "selectable+CM0"; - vector contextList = { - context - }; - auto requests = CreateLoadRequests("/Validation/dependencies.csolution.yml", "", contextList); - requests += FormatRequest(3, "GetUsedItems", json({{ "context", context }})); - requests += FormatRequest(4, "GetPacksInfo", json({{ "context", context }, {"all", false}})); - requests += FormatRequest(5, "GetPacksInfo", json({{ "context", context }, {"all", true}})); - - const auto& responses = RunRpcMethods(requests); + const auto& responses = RunPackInfoRequests("/Validation/dependencies.csolution.yml", context); EXPECT_TRUE(responses[2]["result"]["success"]); auto packs = responses[2]["result"]["packs"]; @@ -1174,16 +1196,7 @@ TEST_F(ProjMgrRpcTests, RpcGetPacksInfoSimple) { TEST_F(ProjMgrRpcTests, RpcGetPacksInfo) { string context = "test1.Release+CM0"; - vector contextList = { - context - }; - - auto requests = CreateLoadRequests("/TestSolution/test_pack_requirements.csolution.yml", "", contextList); - requests += FormatRequest(3, "GetUsedItems", json({{ "context", context }})); - requests += FormatRequest(4, "GetPacksInfo", json({{ "context", context }, {"all", false}})); - requests += FormatRequest(5, "GetPacksInfo", json({{ "context", context }, {"all", true}})); - - const auto& responses = RunRpcMethods(requests); + const auto& responses = RunPackInfoRequests("/TestSolution/test_pack_requirements.csolution.yml", context); EXPECT_TRUE(responses[2]["result"]["success"]); auto packs = responses[2]["result"]["packs"]; @@ -1203,17 +1216,65 @@ TEST_F(ProjMgrRpcTests, RpcGetPacksInfo) { EXPECT_FALSE(packInfos[7].contains("used")); } -TEST_F(ProjMgrRpcTests, RpcGetPacksInfoMissing) { - string context = "project+Miss"; - vector contextList = { - context - }; - auto requests = CreateLoadRequests("/TestSolution/PackMissing/missing_pack.csolution.yml", "", contextList); - requests += FormatRequest(3, "GetUsedItems", json({{ "context", context }})); - requests += FormatRequest(4, "GetPacksInfo", json({{ "context", context }, {"all", false}})); +TEST_F(ProjMgrRpcTests, RpcGetPacksInfoPackPath) { + string context = "pack_path+CM0"; - const auto& responses = RunRpcMethods(requests); + // first solution + auto requests = FormatPackInfoRequests("/TestSolution/pack_path.csolution.yml", context, true); + // second solution, same pack in a different directory + requests += FormatPackInfoRequests("/TestSolution/pack_path1.csolution.yml", context, false); + + auto responses = RunRpcMethods(requests); + + // first solution + auto expectedPackPath = testinput_folder + "/SolutionSpecificPack"; + auto expectedDoc = testinput_folder + "/SolutionSpecificPack" + "/Doc/overview.md"; + + EXPECT_TRUE(responses[2]["result"]["success"]); + auto packs = responses[2]["result"]["packs"]; + EXPECT_EQ(packs[0]["pack"], "ARM::RteTest_DFP"); + EXPECT_EQ(packs[0]["resolvedPack"], "ARM::RteTest_DFP"); + EXPECT_EQ(packs[0]["path"], expectedPackPath); + EXPECT_FALSE(packs[0].contains("upgrade")); + + EXPECT_TRUE(responses[3]["result"]["success"]); // get pack infos + auto packInfos = responses[3]["result"]["packs"]; + EXPECT_EQ(packInfos.size(), 1); + EXPECT_EQ(packInfos[0]["id"], "ARM::RteTest_DFP@0.2.0"); + EXPECT_EQ(packInfos[0]["doc"], expectedDoc); + EXPECT_TRUE(packInfos[0]["used"]); + + packInfos = responses[4]["result"]["packs"]; + EXPECT_EQ(packInfos.size(), 8); + +// second solution + + expectedPackPath = testinput_folder + "/SolutionSpecificPack1"; + expectedDoc = testinput_folder + "/SolutionSpecificPack1" + "/Doc/overview.md"; + + EXPECT_TRUE(responses[6]["result"]["success"]); + packs = responses[6]["result"]["packs"]; + EXPECT_EQ(packs[0]["pack"], "ARM::RteTest_DFP"); + EXPECT_EQ(packs[0]["resolvedPack"], "ARM::RteTest_DFP"); + EXPECT_EQ(packs[0]["path"], expectedPackPath); + EXPECT_FALSE(packs[0].contains("upgrade")); + + EXPECT_TRUE(responses[7]["result"]["success"]); // get pack infos + packInfos = responses[7]["result"]["packs"]; + EXPECT_EQ(packInfos.size(), 1); + EXPECT_EQ(packInfos[0]["id"], "ARM::RteTest_DFP@0.2.0"); + EXPECT_EQ(packInfos[0]["doc"], expectedDoc); + EXPECT_TRUE(packInfos[0]["used"]); + + packInfos = responses[8]["result"]["packs"]; + EXPECT_EQ(packInfos.size(), 8); +} + + +TEST_F(ProjMgrRpcTests, RpcGetPacksInfoMissing) { + string context = "project+Miss"; + const auto& responses = RunPackInfoRequests("/TestSolution/PackMissing/missing_pack.csolution.yml", context); EXPECT_TRUE(responses[2]["result"]["success"]); auto packs = responses[2]["result"]["packs"]; @@ -1230,8 +1291,6 @@ TEST_F(ProjMgrRpcTests, RpcGetPacksInfoMissing) { EXPECT_EQ(packs[3]["pack"], "ARM::RteTest_DFP"); EXPECT_EQ(packs[3]["resolvedPack"], "ARM::RteTest_DFP@0.2.0"); - - EXPECT_TRUE(responses[3]["result"]["success"]); // get pack infos auto packInfos = responses[3]["result"]["packs"]; EXPECT_EQ(packInfos.size(), 4); @@ -1242,20 +1301,9 @@ TEST_F(ProjMgrRpcTests, RpcGetPacksInfoMissing) { EXPECT_EQ(packInfos[3]["id"], "ARM::RteTest_DFP@0.2.0"); } - - TEST_F(ProjMgrRpcTests, RpcGetPacksNotLatest) { string context = "test1.DebugOldDfp+CM0"; - vector contextList = { - context - }; - - auto requests = CreateLoadRequests("/TestSolution/test_pack_requirements.csolution.yml", "", contextList); - requests += FormatRequest(3, "GetUsedItems", json({{ "context", context }})); - requests += FormatRequest(4, "GetPacksInfo", json({{ "context", context }, {"all", false}})); - requests += FormatRequest(5, "GetPacksInfo", json({{ "context", context }, {"all", true}})); - - const auto& responses = RunRpcMethods(requests); + const auto& responses = RunPackInfoRequests("/TestSolution/test_pack_requirements.csolution.yml", context); EXPECT_TRUE(responses[2]["result"]["success"]); auto packs = responses[2]["result"]["packs"]; @@ -1293,16 +1341,7 @@ TEST_F(ProjMgrRpcTests, RpcGetPacksNotLatest) { TEST_F(ProjMgrRpcTests, RpcGetPacksInfoLayer) { string context = "packs.CompatibleLayers+RteTest_ARMCM3"; - vector contextList = { - context - }; - - auto requests = CreateLoadRequests("/TestLayers/packs.csolution.yml", "", contextList); - requests += FormatRequest(3, "GetUsedItems", json({{ "context", context }})); - requests += FormatRequest(4, "GetPacksInfo", json({{ "context", context }, {"all", false}})); - requests += FormatRequest(5, "GetPacksInfo", json({{ "context", context }, {"all", true}})); - - const auto& responses = RunRpcMethods(requests); + const auto& responses = RunPackInfoRequests("/TestLayers/packs.csolution.yml", context); EXPECT_TRUE(responses[2]["result"]["success"]); auto packs = responses[2]["result"]["packs"]; @@ -1329,15 +1368,7 @@ TEST_F(ProjMgrRpcTests, RpcGetPacksInfoLayer) { TEST_F(ProjMgrRpcTests, RpcGetPacksInfoLocal) { string context = "incompatible.Debug+CM0"; - vector contextList = { - context - }; - - auto requests = CreateLoadRequests("/TestSolution/PackRequirements/incompatible.csolution.yml", "", contextList); - requests += FormatRequest(3, "GetUsedItems", json({{ "context", context }})); - requests += FormatRequest(4, "GetPacksInfo", json({{ "context", context }, {"all", false}})); - - const auto& responses = RunRpcMethods(requests); + const auto& responses = RunPackInfoRequests("/TestSolution/PackRequirements/incompatible.csolution.yml", context); EXPECT_TRUE(responses[2]["result"]["success"]); auto packs = responses[2]["result"]["packs"]; diff --git a/tools/projmgr/test/src/ProjMgrTestEnv.cpp b/tools/projmgr/test/src/ProjMgrTestEnv.cpp index e32099f58..e06d6b75c 100644 --- a/tools/projmgr/test/src/ProjMgrTestEnv.cpp +++ b/tools/projmgr/test/src/ProjMgrTestEnv.cpp @@ -125,6 +125,15 @@ void ProjMgrTestEnv::SetUp() { } RteFsUtils::CreateDirectories(destPackPath); fs::copy(fs::path(srcPackPath), fs::path(destPackPath), fs::copy_options::recursive, ec); + + destPackPath = testinput_folder + "/SolutionSpecificPack1"; + if (RteFsUtils::Exists(destPackPath)) { + RteFsUtils::RemoveDir(destPackPath); + } + RteFsUtils::CreateDirectories(destPackPath); + fs::copy(fs::path(srcPackPath), fs::path(destPackPath), fs::copy_options::recursive, ec); + + srcPackPath = testcmsispack_folder + "/ARM/RteTest/0.1.0"; destPackPath = testinput_folder + "/SolutionSpecificPack2"; if (RteFsUtils::Exists(destPackPath)) { @@ -243,7 +252,7 @@ std::map ProjMgrTestEnv::GetEffe rteKernel.SetCmsisPackRoot(GetCmsisPackRoot()); std::list pdscFiles; std::list packs; - rteKernel.GetEffectivePdscFiles(pdscFiles, bLatestsOnly); + rteKernel.GetEffectivePdscFiles(pdscFiles, bLatestsOnly); rteKernel.LoadAndInsertPacks(packs, pdscFiles); for (const auto& pack : packs) { pdscMap[pack->GetID()] = pack->GetPackageFileName();