From 0a879a658fd6d1ffb3ec88fbb8043f655620eaed Mon Sep 17 00:00:00 2001 From: grasci <86058054+grasci-arm@users.noreply.github.com> Date: Fri, 10 Nov 2023 09:27:20 +0000 Subject: [PATCH 1/3] [projmgr] Extend list generators in verbose mode --- tools/projmgr/include/ProjMgrExtGenerator.h | 7 +++ tools/projmgr/include/ProjMgrParser.h | 2 + tools/projmgr/schemas/common.schema.json | 1 + tools/projmgr/src/ProjMgrExtGenerator.cpp | 3 + tools/projmgr/src/ProjMgrWorker.cpp | 27 ++++++++- tools/projmgr/src/ProjMgrYamlParser.cpp | 1 + tools/projmgr/templates/global.generator.yml | 3 +- .../ExternalGenerator/global.generator.yml | 1 + tools/projmgr/test/src/ProjMgrUnitTests.cpp | 59 +++++++++++++++++++ 9 files changed, 100 insertions(+), 4 deletions(-) diff --git a/tools/projmgr/include/ProjMgrExtGenerator.h b/tools/projmgr/include/ProjMgrExtGenerator.h index 4ba0f5646..96cd02784 100644 --- a/tools/projmgr/include/ProjMgrExtGenerator.h +++ b/tools/projmgr/include/ProjMgrExtGenerator.h @@ -91,6 +91,13 @@ class ProjMgrExtGenerator { */ const std::string& GetGlobalGenRunCmd(const std::string& generatorId); + /** + * @brief get generator description + * @param generatorId generator identifier + * @return string with generator description + */ + const std::string& GetGlobalDescription(const std::string& generatorId); + /** * @brief add generator to the list of used generators of a given context * @param generatorId generator identifier diff --git a/tools/projmgr/include/ProjMgrParser.h b/tools/projmgr/include/ProjMgrParser.h index d5ca6143e..3124679d3 100644 --- a/tools/projmgr/include/ProjMgrParser.h +++ b/tools/projmgr/include/ProjMgrParser.h @@ -424,12 +424,14 @@ struct CbuildSetItem { /** * @brief global generator item containing * generator id, + * generator description, * download url, * bridge program, * path for generated files */ struct GlobalGeneratorItem { std::string id; + std::string description; std::string downloadUrl; std::string run; std::string path; diff --git a/tools/projmgr/schemas/common.schema.json b/tools/projmgr/schemas/common.schema.json index 39dbb5815..ca0802954 100644 --- a/tools/projmgr/schemas/common.schema.json +++ b/tools/projmgr/schemas/common.schema.json @@ -1136,6 +1136,7 @@ "type": "object", "properties": { "id": { "type": "string", "description": "Generator identifier" }, + "description": { "type": "string", "description": "Generator description" }, "download-url": { "type": "string", "description": "URL for downloading generator tool" }, "run": { "type": "string", "description": "Related bridge program" }, "path": { "type": "string", "description": "Specifies the directory for generated files" } diff --git a/tools/projmgr/src/ProjMgrExtGenerator.cpp b/tools/projmgr/src/ProjMgrExtGenerator.cpp index 49ca2cee9..9a986c560 100644 --- a/tools/projmgr/src/ProjMgrExtGenerator.cpp +++ b/tools/projmgr/src/ProjMgrExtGenerator.cpp @@ -72,6 +72,9 @@ const string& ProjMgrExtGenerator::GetGlobalGenRunCmd(const string& generatorId) return(m_globalGenerators[generatorId].run); } +const string& ProjMgrExtGenerator::GetGlobalDescription(const string& generatorId) { + return(m_globalGenerators[generatorId].description); +} void ProjMgrExtGenerator::AddUsedGenerator(const string& generatorId, const string& genDir, const string& contextId) { m_usedGenerators[generatorId][genDir].push_back(contextId); diff --git a/tools/projmgr/src/ProjMgrWorker.cpp b/tools/projmgr/src/ProjMgrWorker.cpp index 99765e3e2..ebe18c97a 100644 --- a/tools/projmgr/src/ProjMgrWorker.cpp +++ b/tools/projmgr/src/ProjMgrWorker.cpp @@ -3321,17 +3321,38 @@ bool ProjMgrWorker::ListContexts(vector& contexts, const string& filter, bool ProjMgrWorker::ListGenerators(vector& generators) { set generatorsSet; + GeneratorContextVecMap generatorsMap; + StrMap generatorsDescription; for (const auto& selectedContext : m_selectedContexts) { ContextItem& context = m_contexts[selectedContext]; if (!ProcessContext(context, false, true, false)) { return false; } for (const auto& [id, generator] : context.generators) { - generatorsSet.insert(id + " (" + generator->GetDescription() + ")"); + for (const auto& [_, item] : context.gpdscs) { + if (item.generator == id) { + const string workingDir = fs::path(context.cproject->directory).append(item.workingDir).generic_string(); + generatorsMap[id][workingDir].push_back(context.name); + generatorsDescription[id] = generator->GetDescription(); + break; + } + } } } - for (const auto& [id, _] : m_extGenerator->GetUsedGenerators()) { - generatorsSet.insert(id + " (Global Registered Generator)"); + GeneratorContextVecMap extGeneratorsMap(m_extGenerator->GetUsedGenerators()); + generatorsMap.insert(extGeneratorsMap.begin(), extGeneratorsMap.end()); + for (const auto& [id, dirs] : generatorsMap) { + string generatorEntry = id + " (" + (m_extGenerator->IsGlobalGenerator(id) ? + m_extGenerator->GetGlobalDescription(id) : generatorsDescription[id]) + ")"; + if (m_verbose) { + for (const auto& [dir, contexts] : dirs) { + generatorEntry += "\n base-dir: " + RteFsUtils::RelativePath(dir, m_parser->GetCsolution().directory); + for (const auto& context : contexts) { + generatorEntry += "\n context: " + context; + } + } + } + generatorsSet.insert(generatorEntry); } generators.assign(generatorsSet.begin(), generatorsSet.end()); return true; diff --git a/tools/projmgr/src/ProjMgrYamlParser.cpp b/tools/projmgr/src/ProjMgrYamlParser.cpp index 55f59e5d1..e3e20d7bb 100644 --- a/tools/projmgr/src/ProjMgrYamlParser.cpp +++ b/tools/projmgr/src/ProjMgrYamlParser.cpp @@ -269,6 +269,7 @@ bool ProjMgrYamlParser::ParseGlobalGenerator(const string& input, GlobalGeneratorItem generator; map generatorChildren = { {YAML_ID, generator.id}, + {YAML_DESCRIPTION, generator.description}, {YAML_DOWNLOAD_URL, generator.downloadUrl}, {YAML_RUN, generator.run}, }; diff --git a/tools/projmgr/templates/global.generator.yml b/tools/projmgr/templates/global.generator.yml index 4b6750f8c..0274310a6 100644 --- a/tools/projmgr/templates/global.generator.yml +++ b/tools/projmgr/templates/global.generator.yml @@ -1,5 +1,6 @@ generator: - id: CubeMX + description: Global Registered Generator download-url: https://www.st.com/en/development-tools/stm32cubemx.html#st-get-software run: ../bin/cbridge - path: $SolutionDir()$/STM32CubeMX/$Dname$ + path: $SolutionDir()$/STM32CubeMX/$TargetType$ diff --git a/tools/projmgr/test/data/ExternalGenerator/global.generator.yml b/tools/projmgr/test/data/ExternalGenerator/global.generator.yml index 29b6c54fc..71f1e910b 100644 --- a/tools/projmgr/test/data/ExternalGenerator/global.generator.yml +++ b/tools/projmgr/test/data/ExternalGenerator/global.generator.yml @@ -1,5 +1,6 @@ generator: - id: RteTestExternalGenerator + description: Global Registered Generator download-url: https://raw.githubusercontent.com/Open-CMSIS-Pack run: ./bridge.sh path: $SolutionDir()$/generated/$TargetType$ diff --git a/tools/projmgr/test/src/ProjMgrUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUnitTests.cpp index f77fc28bb..1436d67ab 100644 --- a/tools/projmgr/test/src/ProjMgrUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUnitTests.cpp @@ -4312,6 +4312,65 @@ TEST_F(ProjMgrUnitTests, ExternalGenerator_NoCgenFile) { RteFsUtils::RemoveFile(dstGlobalGenerator); } +TEST_F(ProjMgrUnitTests, ExternalGeneratorListVerbose) { + const string& srcGlobalGenerator = testinput_folder + "/ExternalGenerator/global.generator.yml"; + const string& dstGlobalGenerator = testcmsiscompiler_folder + "/global.generator.yml"; + RteFsUtils::CopyCheckFile(srcGlobalGenerator, dstGlobalGenerator, false); + StdStreamRedirect streamRedirect; + + char* argv[5]; + const string& csolution = testinput_folder + "/ExternalGenerator/extgen.csolution.yml"; + argv[1] = (char*)csolution.c_str(); + argv[2] = (char*)"list"; + argv[3] = (char*)"generators"; + argv[4] = (char*)"-v"; + EXPECT_EQ(0, RunProjMgr(5, argv, 0)); + + const string expected = "\ +RteTestExternalGenerator (Global Registered Generator)\n\ + base-dir: generated/CM0\n\ + context: ns.Debug+CM0\n\ + context: ns.Release+CM0\n\ + context: s.Debug+CM0\n\ + context: s.Release+CM0\n\ + base-dir: generated/MultiCore\n\ + context: core0.Debug+MultiCore\n\ + context: core0.Release+MultiCore\n\ + context: core1.Debug+MultiCore\n\ + context: core1.Release+MultiCore\n\ + base-dir: single/generated\n\ + context: single-core.Debug+CM0\n\ + context: single-core.Release+CM0\n\ +"; + auto outStr = streamRedirect.GetOutString(); + EXPECT_TRUE(outStr.find(expected) != string::npos); + + RteFsUtils::RemoveFile(dstGlobalGenerator); +} + +TEST_F(ProjMgrUnitTests, ClassicGeneratorListVerbose) { + StdStreamRedirect streamRedirect; + + char* argv[5]; + const string& csolution = testinput_folder + "/TestGenerator/test-gpdsc-multiple-generators.csolution.yml"; + argv[1] = (char*)"list"; + argv[2] = (char*)"generators"; + argv[3] = (char*)csolution.c_str(); + argv[4] = (char*)"-v"; + EXPECT_EQ(0, RunProjMgr(5, argv, 0)); + + const string expected = "\ +RteTestGeneratorIdentifier (RteTest Generator Description)\n\ + base-dir: GeneratedFiles/RteTestGeneratorIdentifier\n\ + context: test-gpdsc-multiple-generators.Debug+CM0\n\ +RteTestGeneratorWithKey (RteTest Generator with Key Description)\n\ + base-dir: GeneratedFiles/RteTestGeneratorWithKey\n\ + context: test-gpdsc-multiple-generators.Debug+CM0\n\ +"; + auto outStr = streamRedirect.GetOutString(); + EXPECT_TRUE(outStr.find(expected) != string::npos); +} + TEST_F(ProjMgrUnitTests, DeviceAttributes) { const map> projects = { {"fpu", {"+fpu-dp","+fpu-sp", "+no-fpu"}}, From 963c1149fad76caa5d0b59af171743c1ae2a09a6 Mon Sep 17 00:00:00 2001 From: grasci <86058054+grasci-arm@users.noreply.github.com> Date: Tue, 14 Nov 2023 08:43:05 +0000 Subject: [PATCH 2/3] Remove option --context-replacement arg --- tools/projmgr/include/ProjMgr.h | 1 - tools/projmgr/include/ProjMgrUtils.h | 12 -- tools/projmgr/include/ProjMgrWorker.h | 1 - tools/projmgr/src/ProjMgr.cpp | 35 +++--- tools/projmgr/src/ProjMgrUtils.cpp | 104 ----------------- tools/projmgr/src/ProjMgrWorker.cpp | 24 +--- tools/projmgr/test/src/ProjMgrUnitTests.cpp | 25 ----- .../test/src/ProjMgrUtilsUnitTests.cpp | 106 ------------------ 8 files changed, 18 insertions(+), 290 deletions(-) diff --git a/tools/projmgr/include/ProjMgr.h b/tools/projmgr/include/ProjMgr.h index 4439de9dd..13690968f 100644 --- a/tools/projmgr/include/ProjMgr.h +++ b/tools/projmgr/include/ProjMgr.h @@ -93,7 +93,6 @@ class ProjMgr { std::string m_csolutionFile; std::string m_cdefaultFile; std::vector m_context; - std::string m_contextReplacement; std::string m_filter; std::string m_codeGenerator; std::string m_command; diff --git a/tools/projmgr/include/ProjMgrUtils.h b/tools/projmgr/include/ProjMgrUtils.h index 3e17a62b3..5ed343775 100644 --- a/tools/projmgr/include/ProjMgrUtils.h +++ b/tools/projmgr/include/ProjMgrUtils.h @@ -349,18 +349,6 @@ class ProjMgrUtils { const std::vector& allAvailableContexts, const std::vector& contextFilters); - /** - * @brief replace list of contexts - * @param selectedContexts list of matched contexts - * @param allContexts list of all available contexts - * @param contextReplace filter criteria - * @return Error object with error message (if any) - */ - static Error ReplaceContexts( - std::vector& selectedContexts, - const std::vector& allContexts, - const std::string& contextReplace); - /** * @brief get equivalent device attribute * @param key device attribute rte key diff --git a/tools/projmgr/include/ProjMgrWorker.h b/tools/projmgr/include/ProjMgrWorker.h index 5dce55a0b..604299414 100644 --- a/tools/projmgr/include/ProjMgrWorker.h +++ b/tools/projmgr/include/ProjMgrWorker.h @@ -584,7 +584,6 @@ class ProjMgrWorker { */ bool ParseContextSelection( const std::vector& contextSelection, - const std::string& contextReplace = RteUtils::EMPTY_STRING, const bool checkCbuildSet = false); /** diff --git a/tools/projmgr/src/ProjMgr.cpp b/tools/projmgr/src/ProjMgr.cpp index 26e6c8099..dc8a86c35 100644 --- a/tools/projmgr/src/ProjMgr.cpp +++ b/tools/projmgr/src/ProjMgr.cpp @@ -38,7 +38,6 @@ Commands:\n\ update-rte Create/update configuration files and validate solution\n\n\ Options:\n\ -c, --context arg [...] Input context names [][.][+]\n\ - --context-replacement arg Input context replacement name [][.][+]\n\ -d, --debug Enable debug messages\n\ -D, --dry-run Enable dry-run\n\ -e, --export arg Set suffix for exporting .cprj retaining only specified versions\n\ @@ -127,7 +126,6 @@ int ProjMgr::RunProjMgr(int argc, char **argv, char** envp) { cxxopts::Option solution("s,solution", "Input csolution.yml file", cxxopts::value()); cxxopts::Option context("c,context", "Input context names [][.][+]", cxxopts::value>()); - cxxopts::Option contextReplacement("context-replacement", "Input context replacement name [][.][+]", cxxopts::value()); cxxopts::Option filter("f,filter", "Filter words", cxxopts::value()); cxxopts::Option help("h,help", "Print usage"); cxxopts::Option generator("g,generator", "Code generator identifier", cxxopts::value()); @@ -159,16 +157,16 @@ int ProjMgr::RunProjMgr(int argc, char **argv, char** envp) { {"list components", { true, {context, debug, filter, load, schemaCheck, toolchain, verbose}}}, {"list dependencies", { false, {context, debug, filter, load, schemaCheck, toolchain, verbose}}}, {"list contexts", { false, {debug, filter, schemaCheck, verbose, ymlOrder}}}, - {"list generators", { false, {context, contextReplacement, debug, load, schemaCheck, toolchain, verbose}}}, - {"list layers", { false, {context, contextReplacement, debug, load, clayerSearchPath, schemaCheck, toolchain, verbose}}}, - {"list toolchains", { false, {context, contextReplacement, debug, toolchain, verbose}}}, + {"list generators", { false, {context, debug, load, schemaCheck, toolchain, verbose}}}, + {"list layers", { false, {context, debug, load, clayerSearchPath, schemaCheck, toolchain, verbose}}}, + {"list toolchains", { false, {context, debug, toolchain, verbose}}}, {"list environment", { true, {}}}, }; try { options.add_options("", { {"positional", "", cxxopts::value>()}, - solution, context, contextReplacement, contextSet, filter, generator, + solution, context, contextSet, filter, generator, load, clayerSearchPath, missing, schemaCheck, noUpdateRte, output, help, version, verbose, debug, dryRun, exportSuffix, toolchain, ymlOrder }); @@ -226,9 +224,6 @@ int ProjMgr::RunProjMgr(int argc, char **argv, char** envp) { if (parseResult.count("context")) { manager.m_context = parseResult["context"].as>(); } - if (parseResult.count("context-replacement")) { - manager.m_contextReplacement = parseResult["context-replacement"].as(); - } if (parseResult.count("filter")) { manager.m_filter = parseResult["filter"].as(); } @@ -455,7 +450,7 @@ bool ProjMgr::RunConfigure(bool printConfig) { bool checkCbuildSet = (m_context.size() == 0) && m_contextSet; // Parse context selection - if (!m_worker.ParseContextSelection(m_context, m_contextReplacement, checkCbuildSet)) { + if (!m_worker.ParseContextSelection(m_context, checkCbuildSet)) { return false; } // Get context pointers @@ -562,7 +557,7 @@ bool ProjMgr::RunListPacks(void) { } } // Parse context selection - if (!m_worker.ParseContextSelection(m_context, m_contextReplacement)) { + if (!m_worker.ParseContextSelection(m_context)) { return false; } vector packs; @@ -581,7 +576,7 @@ bool ProjMgr::RunListBoards(void) { } } // Parse context selection - if (!m_worker.ParseContextSelection(m_context, m_contextReplacement)) { + if (!m_worker.ParseContextSelection(m_context)) { return false; } vector boards; @@ -603,7 +598,7 @@ bool ProjMgr::RunListDevices(void) { } } // Parse context selection - if (!m_worker.ParseContextSelection(m_context, m_contextReplacement)) { + if (!m_worker.ParseContextSelection(m_context)) { return false; } vector devices; @@ -625,7 +620,7 @@ bool ProjMgr::RunListComponents(void) { } } // Parse context selection - if (!m_worker.ParseContextSelection(m_context, m_contextReplacement)) { + if (!m_worker.ParseContextSelection(m_context)) { return false; } vector components; @@ -647,7 +642,7 @@ bool ProjMgr::RunListConfigs() { } } // Parse context selection - if (!m_worker.ParseContextSelection(m_context, m_contextReplacement)) { + if (!m_worker.ParseContextSelection(m_context)) { return false; } vector configFiles; @@ -667,7 +662,7 @@ bool ProjMgr::RunListDependencies(void) { return false; } // Parse context selection - if (!m_worker.ParseContextSelection(m_context, m_contextReplacement)) { + if (!m_worker.ParseContextSelection(m_context)) { return false; } vector dependencies; @@ -703,7 +698,7 @@ bool ProjMgr::RunListGenerators(void) { return false; } // Parse context selection - if (!m_worker.ParseContextSelection(m_context, m_contextReplacement)) { + if (!m_worker.ParseContextSelection(m_context)) { return false; } // Get generators @@ -725,7 +720,7 @@ bool ProjMgr::RunListLayers(void) { } } // Parse context selection - if (!m_worker.ParseContextSelection(m_context, m_contextReplacement)) { + if (!m_worker.ParseContextSelection(m_context)) { return false; } // Get layers @@ -750,7 +745,7 @@ bool ProjMgr::RunCodeGenerator(void) { return false; } // Parse context selection - if (!m_worker.ParseContextSelection(m_context, m_contextReplacement)) { + if (!m_worker.ParseContextSelection(m_context)) { return false; } if (m_extGenerator.IsGlobalGenerator(m_codeGenerator)) { @@ -775,7 +770,7 @@ bool ProjMgr::RunListToolchains(void) { } } // Parse context selection - if (!m_worker.ParseContextSelection(m_context, m_contextReplacement)) { + if (!m_worker.ParseContextSelection(m_context)) { return false; } vector toolchains; diff --git a/tools/projmgr/src/ProjMgrUtils.cpp b/tools/projmgr/src/ProjMgrUtils.cpp index 1e9d786d5..4f85f043d 100644 --- a/tools/projmgr/src/ProjMgrUtils.cpp +++ b/tools/projmgr/src/ProjMgrUtils.cpp @@ -326,110 +326,6 @@ ProjMgrUtils::Error ProjMgrUtils::GetSelectedContexts(vector& selectedCo return error; } -ProjMgrUtils::Error ProjMgrUtils::ReplaceContexts(vector& selectedContexts, - const vector& allContexts, const string& contextReplace) -{ - Error error; - if (contextReplace == RteUtils::EMPTY_STRING) { - return error; - } - - // validate if the replace filter is valid - auto replaceContexts = GetFilteredContexts(allContexts, contextReplace); - if (replaceContexts.size() == 0) { - error.m_errMsg = "invalid context replacement name. \"" + contextReplace + "\" was not found.\n"; - selectedContexts.clear(); - return error; - } - - // no replacement needed when replacement contexts list - // is exactly same as selected contexts list - if (selectedContexts.size() == replaceContexts.size()) { - set sortedSelectedContexts(selectedContexts.begin(), selectedContexts.end()); - set sortedReplaceContexts(replaceContexts.begin(), replaceContexts.end()); - if (sortedSelectedContexts == sortedReplaceContexts) { - // no replacement needed - return error; - } - } - - // validate if replace filter requests more contexts than selected contexts - if (selectedContexts.size() < replaceContexts.size()) { - error.m_errMsg = "invalid replacement request. Replacement contexts are more than the selected contexts"; - selectedContexts.clear(); - return error; - } - - ContextName replaceFilter; - ProjMgrUtils::ParseContextEntry(contextReplace, replaceFilter); - - // validate if the replace filter has contexts which are not matching with selected context list - bool found = false; - for (auto& selectedContext : selectedContexts) { - ContextName context; - ProjMgrUtils::ParseContextEntry(selectedContext, context); - if (replaceFilter.project.empty() || - WildCards::Match(replaceFilter.project, context.project)) { - found = true; - break; - } - } - if (!found) { - error.m_errMsg = "no suitable replacement found for context replacement \"" + contextReplace + "\""; - selectedContexts.clear(); - return error; - } - - if (replaceFilter.project.empty()) { - replaceFilter.project = "*"; - } - - // get a list of contexts needs to be replaced - vector filteredContexts; - ContextName repContextItem, selContextItem; - for (string& selectedContext : selectedContexts) { - ProjMgrUtils::ParseContextEntry(selectedContext, selContextItem); - for (const string& contextItr : replaceContexts) { - if ((!replaceFilter.project.empty()) && (!WildCards::Match(replaceFilter.project, selContextItem.project))) { - // if 'project name' does not match the replace filter push it into the results and iterate further - ProjMgrUtils::PushBackUniquely(filteredContexts, selectedContext); - continue; - } - - ProjMgrUtils::ParseContextEntry(contextItr, repContextItem); - // construct context name for replacement - string replaceContext = selContextItem.project; - if (!repContextItem.build.empty()) { - replaceContext += "." + repContextItem.build; - } - replaceContext += "+" + repContextItem.target; - - if (find(allContexts.begin(), allContexts.end(), replaceContext) != allContexts.end()) { - // if 'replaceContext' is valid push it into the results - ProjMgrUtils::PushBackUniquely(filteredContexts, replaceContext); - } - } - } - - if (filteredContexts.size() == 0) { - // no match found - error.m_errMsg = "no suitable replacements found for context replacement \"" + contextReplace + "\""; - selectedContexts.clear(); - return error; - } - - if (selectedContexts.size() != filteredContexts.size()) { - // incompatible change - error.m_errMsg = "incompatible replacements found for \"" + contextReplace + "\""; - selectedContexts.clear(); - return error; - } - - // update selected contexts with the filtered ones - selectedContexts = filteredContexts; - return error; -} - vector ProjMgrUtils::GetFilteredContexts( const vector& allContexts, const string& contextFilter) { diff --git a/tools/projmgr/src/ProjMgrWorker.cpp b/tools/projmgr/src/ProjMgrWorker.cpp index ebe18c97a..5aeee71fd 100644 --- a/tools/projmgr/src/ProjMgrWorker.cpp +++ b/tools/projmgr/src/ProjMgrWorker.cpp @@ -3673,8 +3673,9 @@ bool ProjMgrWorker::ProcessSequencesRelatives(ContextItem& context, BuildType& b return true; } -bool ProjMgrWorker::ParseContextSelection(const vector& contextSelection, - const string& contextReplace, const bool checkCbuildSet) { +bool ProjMgrWorker::ParseContextSelection( + const vector& contextSelection, const bool checkCbuildSet) +{ vector contexts; ListContexts(contexts); @@ -3698,25 +3699,6 @@ bool ProjMgrWorker::ParseContextSelection(const vector& contextSelection return false; } } - auto selectedContexts = m_selectedContexts; - if (contextReplace != RteUtils::EMPTY_STRING) { - const auto& replaceError = ProjMgrUtils::ReplaceContexts(m_selectedContexts, contexts, contextReplace); - if (replaceError) { - ProjMgrLogger::Error(replaceError.m_errMsg); - return false; - } - } - - if (m_verbose && contextReplace != RteUtils::EMPTY_STRING) { - cout << "selected context(s):" << endl; - for (const auto& context : selectedContexts) { - cout << " " + context << endl; - } - cout << "is replaced with:" << endl; - for (const auto& context : m_selectedContexts) { - cout << " " + context << endl; - } - } if (!((m_selectedContexts.size() == 1) && (m_selectedContexts.front() == RteUtils::EMPTY_STRING))) { for (const auto& context : m_selectedContexts) { diff --git a/tools/projmgr/test/src/ProjMgrUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUnitTests.cpp index 1436d67ab..f42f75f23 100644 --- a/tools/projmgr/test/src/ProjMgrUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUnitTests.cpp @@ -3835,31 +3835,6 @@ TEST_F(ProjMgrUnitTests, EnsurePortability) { } } -TEST_F(ProjMgrUnitTests, RunProjMgrSolution_context_replacement) { - char* argv[10]; - StdStreamRedirect streamRedirect; - // convert --solution solution.yml - const string& csolution = testinput_folder + "/TestSolution/test.csolution.yml"; - RemoveCbuildSetFile(csolution); - - argv[1] = (char*)"convert"; - argv[2] = (char*)"--solution"; - argv[3] = (char*)csolution.c_str(); - argv[4] = (char*)"-c"; - argv[5] = (char*)"test1.Release"; - argv[6] = (char*)"--context-replacement"; - argv[7] = (char*)"test1.Debug"; - argv[8] = (char*)testoutput_folder.c_str(); - argv[9] = (char*)"-v"; - EXPECT_EQ(0, RunProjMgr(10, argv, 0)); - - auto outStr = streamRedirect.GetOutString(); - EXPECT_NE(string::npos, outStr.find("test1.Debug+CM0.cprj - info csolution: file generated successfully")); - EXPECT_EQ(string::npos, outStr.find("test1.Release+CM0.cprj - info csolution: file generated successfully")); - EXPECT_EQ(string::npos, outStr.find("test2.Debug+CM0.cprj - info csolution: file generated successfully")); - EXPECT_EQ(string::npos, outStr.find("test2.Debug+CM3.cprj - info csolution: file generated successfully")); -} - TEST_F(ProjMgrUnitTests, RunProjMgr_NonUniqueMapKeys) { StdStreamRedirect streamRedirect; char* argv[6]; diff --git a/tools/projmgr/test/src/ProjMgrUtilsUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUtilsUnitTests.cpp index d159c51bf..134b0fd4a 100644 --- a/tools/projmgr/test/src/ProjMgrUtilsUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUtilsUnitTests.cpp @@ -268,112 +268,6 @@ TEST_F(ProjMgrUtilsUnitTests, GetSelectedContexts) { } } -TEST_F(ProjMgrUtilsUnitTests, ReplaceContexts) { - const vector allContexts_1 = { - "Project1.Debug+Target", - "Project1.Release+Target", - "Project1.Debug+Target2", - "Project1.Release+Target2", - "Project2.Debug+Target", - "Project2.Release+Target", - "Project2.Debug+Target2", - "Project2.Release+Target2", - }; - - const vector allContexts_2 = { - "Project1.Debug+Target1", - "Project1.Release+Target1", - "Project2.Debug+Target1", - "Project2.Debug+Target2", - }; - - const vector allContexts_3 = { - "test1.Debug+CM3", - "test1.Release+CM3", - "test1.Test+CM3", - "test2.Debug+CM3", - "test2.Release+CM3", - "test2.Test+CM3", - }; - - const vector allContexts_4 = { - "Project1.Debug1+Target", - "Project1.Debug2+Target2", - "Project1.Release1+Target", - "Project1.Release2+Target2", - "Project2.Debug1+Target", - "Project2.Debug2+Target2", - "Project2.Release2+Target", - "Project2.Release2+Target2", - }; - - struct TestCase { - vector inputAllContexts; - vector contextFilters; - string contextReplacement; - vector expectedSelectedContexts; - Error expectedOutError; - - string toString() const { - string input; - std::for_each(contextFilters.begin(), contextFilters.end(), - [&](const std::string& item) { input += "--context " + item + " "; }); - return input + "--context-replacement " + contextReplacement; - } - }; - - vector vecTestCase = { - // Positive tests - { allContexts_1, {""}, "", allContexts_1, {}}, - { allContexts_1, {""}, "+*", allContexts_1, {}}, - { allContexts_1, {"Proj*"}, "Proj*", allContexts_1, {}}, - { allContexts_1, {".Release"}, ".Release", {"Project1.Release+Target", "Project1.Release+Target2", "Project2.Release+Target", "Project2.Release+Target2"}, {}}, - { allContexts_1, {"Project2.Debug+Target"}, "Project2.Release+Target", {"Project2.Release+Target"}, {}}, - { allContexts_1, {"Project1.Debug"}, "Project1.Release", {"Project1.Release+Target","Project1.Release+Target2"}, {}}, - { allContexts_1, {"+Target2"}, "+Target", {"Project1.Debug+Target","Project1.Release+Target", "Project2.Debug+Target","Project2.Release+Target"}, {}}, - { allContexts_1, {"*.Debug", "*.Release"}, "*+Target*", {"Project1.Debug+Target", "Project1.Debug+Target2", "Project2.Debug+Target", "Project2.Debug+Target2", "Project1.Release+Target", "Project1.Release+Target2", "Project2.Release+Target", "Project2.Release+Target2" }, {}}, - { allContexts_1, {"Project2.Debug+Target"}, "Project2.Release+Target2", {"Project2.Release+Target2"}, {}}, - { allContexts_4, {"Project*.Rel*"}, "Project*.Debug*", {"Project1.Debug1+Target", "Project1.Debug2+Target2", "Project2.Debug1+Target", "Project2.Debug2+Target2"}, {}}, - - // Negative tests - { allContexts_1, {"Project2"}, "Project1.Release", {}, Error("no suitable replacement found for context replacement \"Project1.Release\"")}, - { allContexts_1, {"Project1.Debug"}, "Project1.UnknownBuildType", {}, Error("invalid context replacement name. \"Project1.UnknownBuildType\" was not found.\n")}, - { allContexts_1, {".Debug", ".Release"}, ".Release", {}, Error("incompatible replacements found for \".Release\"")}, - { allContexts_1, {"Project1"}, ".Release", {}, Error("incompatible replacements found for \".Release\"")}, - { allContexts_1, {"Project2+Target2"}, "+Target2", {}, Error("invalid replacement request. Replacement contexts are more than the selected contexts")}, - { allContexts_2, {"Project2"}, ".Release", {}, Error("no suitable replacements found for context replacement \".Release\"")}, - { allContexts_2, {"*.Debug"}, ".Release", {}, Error("incompatible replacements found for \".Release\"")}, - { allContexts_3, {"+CM3"}, ".Test", {}, Error("incompatible replacements found for \".Test\"")}, - { allContexts_3, {"test2"}, "test2.Test", {}, Error("incompatible replacements found for \"test2.Test\"")}, - { allContexts_3, {"*.Debug"}, "+CM4", {}, Error("invalid context replacement name. \"+CM4\" was not found.")}, - }; - - const auto ValidateOutput = [&](const auto& selectedContexts, const Error& outError, - const TestCase& testCase) -> testing::AssertionResult - { - if (testCase.expectedOutError != outError) { - return testing::AssertionFailure() << "expected error: " << testCase.expectedOutError.m_errMsg; - } - if (string::npos == outError.m_errMsg.find(testCase.expectedOutError.m_errMsg)) { - return testing::AssertionFailure() << "expected error: " << testCase.expectedOutError.m_errMsg; - } - if (testCase.expectedSelectedContexts != selectedContexts) { - return testing::AssertionFailure() << "selected and expected contexts don't match"; - } - return testing::AssertionSuccess(); - }; - - vector selectedContexts; - for (const auto& test : vecTestCase) { - selectedContexts.clear(); - ASSERT_EQ(false, GetSelectedContexts(selectedContexts, test.inputAllContexts, test.contextFilters)); - auto outError = ReplaceContexts(selectedContexts, test.inputAllContexts, test.contextReplacement); - - EXPECT_TRUE(ValidateOutput(selectedContexts, outError, test)) << - "failed for input \"" << test.toString() << "\""; - } -} - TEST_F(ProjMgrUtilsUnitTests, GetFilteredContexts) { const vector allContexts = { "Project1.Debug+Target", From ab7ac4632896a602b92b0b86a1d1f8b823b64ff1 Mon Sep 17 00:00:00 2001 From: grasci <86058054+grasci-arm@users.noreply.github.com> Date: Tue, 14 Nov 2023 08:43:51 +0000 Subject: [PATCH 3/3] Validate cbuild-set context node --- .../{cbuildset.schema.json => cbuild-set.schema.json} | 0 tools/projmgr/schemas/common.schema.json | 8 +++++++- tools/projmgr/src/ProjMgrYamlSchemaChecker.cpp | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) rename tools/projmgr/schemas/{cbuildset.schema.json => cbuild-set.schema.json} (100%) diff --git a/tools/projmgr/schemas/cbuildset.schema.json b/tools/projmgr/schemas/cbuild-set.schema.json similarity index 100% rename from tools/projmgr/schemas/cbuildset.schema.json rename to tools/projmgr/schemas/cbuild-set.schema.json diff --git a/tools/projmgr/schemas/common.schema.json b/tools/projmgr/schemas/common.schema.json index ca0802954..92de0f00a 100644 --- a/tools/projmgr/schemas/common.schema.json +++ b/tools/projmgr/schemas/common.schema.json @@ -25,6 +25,12 @@ "minItems": 1, "items": { "$ref": "#/definitions/BuildContext" } }, + "ArrayOfBuildContextWithProjectName": { + "type": "array", + "uniqueItems": true, + "minItems": 1, + "items": { "$ref": "#/definitions/BuildContextWithProjectName" } + }, "ConditionIDType": { "type": "string" }, @@ -1120,7 +1126,7 @@ "type": "object", "properties": { "generated-by": { "type": "string", "description": "Tool name along with version information used to generate this application" }, - "contexts": { "$ref": "#/definitions/ArrayOfStrings", "description": "List of fully specified contexts" }, + "contexts": { "$ref": "#/definitions/ArrayOfBuildContextWithProjectName", "description": "List of fully specified contexts" }, "compiler": { "type": "string", "description": "Selection of compiler used" } }, "additionalProperties": false, diff --git a/tools/projmgr/src/ProjMgrYamlSchemaChecker.cpp b/tools/projmgr/src/ProjMgrYamlSchemaChecker.cpp index b553bcb19..10ab61ea8 100644 --- a/tools/projmgr/src/ProjMgrYamlSchemaChecker.cpp +++ b/tools/projmgr/src/ProjMgrYamlSchemaChecker.cpp @@ -74,7 +74,7 @@ bool ProjMgrYamlSchemaChecker::GetSchemaFile(string& schemaFile, const ProjMgrYa schemaFileName = "cbuild-idx.schema.json"; break; case ProjMgrYamlSchemaChecker::FileType::BUILDSET: - schemaFileName = "cbuildset.schema.json"; + schemaFileName = "cbuild-set.schema.json"; break; case ProjMgrYamlSchemaChecker::FileType::GENERATOR: schemaFileName = "generator.schema.json";