diff --git a/tools/projmgr/include/ProjMgr.h b/tools/projmgr/include/ProjMgr.h index 75c44a9f1..1a15f6083 100644 --- a/tools/projmgr/include/ProjMgr.h +++ b/tools/projmgr/include/ProjMgr.h @@ -14,6 +14,16 @@ #include +/** + * @brief Error return codes +*/ +enum ErrorCode +{ + SUCCESS = 0, + ERROR = 1, + VARIABLE_NOT_DEFINED +}; + /** * @brief projmgr class */ @@ -131,6 +141,7 @@ class ProjMgr { bool m_contextSet; bool m_relativePaths; bool m_frozenPacks; + bool m_updateIdx; GroupNode m_files; std::vector m_processedContexts; std::vector m_allContexts; diff --git a/tools/projmgr/include/ProjMgrUtils.h b/tools/projmgr/include/ProjMgrUtils.h index b28bbd5c4..802b3c8d6 100644 --- a/tools/projmgr/include/ProjMgrUtils.h +++ b/tools/projmgr/include/ProjMgrUtils.h @@ -27,7 +27,7 @@ typedef std::vector ConnectPtrVec; */ struct ConnectionsCollection { const std::string& filename; - const std::string& type; + const std::string type; ConnectPtrVec connections; ConnectionsCollection& operator=(const ConnectionsCollection& c) { return *this; }; ConnectionsCollection(const ConnectionsCollection& c) = default; diff --git a/tools/projmgr/include/ProjMgrWorker.h b/tools/projmgr/include/ProjMgrWorker.h index b37a97370..4995995f6 100644 --- a/tools/projmgr/include/ProjMgrWorker.h +++ b/tools/projmgr/include/ProjMgrWorker.h @@ -612,6 +612,7 @@ class ProjMgrWorker { bool ProcessGlobalGenerators(ContextItem* context, const std::string& generatorId, std::string& projectType, StrVec& siblings); + bool HasVarDefineError(); protected: ProjMgrParser* m_parser = nullptr; ProjMgrKernel* m_kernel = nullptr; @@ -639,6 +640,7 @@ class ProjMgrWorker { bool m_debug; bool m_dryRun; bool m_relativePaths; + bool m_varDefineError; StrMap m_packMetadata; bool LoadPacks(ContextItem& context); diff --git a/tools/projmgr/include/ProjMgrYamlParser.h b/tools/projmgr/include/ProjMgrYamlParser.h index c1b519569..c000fc944 100644 --- a/tools/projmgr/include/ProjMgrYamlParser.h +++ b/tools/projmgr/include/ProjMgrYamlParser.h @@ -50,6 +50,7 @@ static constexpr const char* YAML_COMPONENT = "component"; static constexpr const char* YAML_COMPONENTS = "components"; static constexpr const char* YAML_CONDITION = "condition"; static constexpr const char* YAML_CONFIGURATION = "configuration"; +static constexpr const char* YAML_CONFIGURATIONS = "configurations"; static constexpr const char* YAML_CONNECT = "connect"; static constexpr const char* YAML_CONNECTIONS = "connections"; static constexpr const char* YAML_CONSTRUCTEDFILES = "constructed-files"; @@ -143,7 +144,10 @@ static constexpr const char* YAML_SELECTED_BY_PACK = "selected-by-pack"; static constexpr const char* YAML_SETUPS = "setups"; static constexpr const char* YAML_SETUP = "setup"; static constexpr const char* YAML_SET = "set"; +static constexpr const char* YAML_SETTINGS = "settings"; static constexpr const char* YAML_SWITCH = "switch"; +static constexpr const char* YAML_TARGET_CONFIGURATIONS = "target-configurations"; +static constexpr const char* YAML_TARGETTYPE = "target-type"; static constexpr const char* YAML_TARGETTYPES = "target-types"; static constexpr const char* YAML_TRUSTZONE = "trustzone"; static constexpr const char* YAML_CORE = "core"; diff --git a/tools/projmgr/schemas/common.schema.json b/tools/projmgr/schemas/common.schema.json index cf0fb9be5..93a089be0 100644 --- a/tools/projmgr/schemas/common.schema.json +++ b/tools/projmgr/schemas/common.schema.json @@ -841,7 +841,8 @@ "generated-by": { "type": "string", "description": "Tool name along with version information used to generate this file" }, "csolution": { "type": "string", "description": "Path to csolution.yml file" }, "cprojects": { "$ref": "#/definitions/BuildProjectsType" }, - "cbuilds": { "$ref": "#/definitions/BuildContextsType" } + "cbuilds": { "$ref": "#/definitions/BuildContextsType" }, + "configurations": { "$ref": "#/definitions/BuildConfigurationsType" } }, "additionalProperties": false, "required": ["generated-by", "csolution", "cprojects"] @@ -855,11 +856,26 @@ "BuildProjectType": { "type": "object", "properties": { - "cproject": { "type": "string", "description": "Path to cproject.yml file" } + "cproject": { "type": "string", "description": "Path to cproject.yml file" }, + "clayers": { "$ref": "#/definitions/BuildLayersType" } }, "additionalProperties": false, "required": ["cproject"] }, + "BuildLayersType": { + "type": "array", + "uniqueItems": true, + "minItems": 1, + "items": { "$ref": "#/definitions/BuildLayerType", "description": "List of clayers" } + }, + "BuildLayerType": { + "type": "object", + "properties": { + "clayer": { "type": "string", "description": "Path to clayer.yml file" } + }, + "additionalProperties": false, + "required": ["clayer"] + }, "BuildContextsType": { "type": "array", "uniqueItems": true, @@ -877,6 +893,77 @@ "additionalProperties": false, "required": ["cbuild", "project", "configuration"] }, + "BuildConfigurationsType": { + "type": "array", + "uniqueItems": true, + "minItems": 1, + "items": { "$ref": "#/definitions/BuildConfigurationType", "description": "Target specific layer configurations" } + }, + "BuildConfigurationType": { + "type": "object", + "properties": { + "target-type": { "type": "string", "description": "Name of the target" }, + "target-configurations" : { "$ref": "#/definitions/BuildTargetConfigurationsType" } + }, + "additionalProperties": false, + "required": ["target-type", "target-configurations"] + }, + "BuildTargetConfigurationsType": { + "type": "array", + "uniqueItems": true, + "minItems": 1, + "items": { "$ref": "#/definitions/BuildTargetConfigurationType", "description": "Target compatible configurations" } + }, + "BuildTargetConfigurationType": { + "type": "object", + "properties": { + "configuration": { "$ref": "#/definitions/BuildLayerConfigurationsType" } + }, + "additionalProperties": false, + "required": ["configuration"] + }, + "BuildLayerConfigurationsType": { + "type": "array", + "uniqueItems": true, + "minItems": 1, + "items": { "$ref": "#/definitions/BuildLayerConfigurationType" } + }, + "BuildLayerConfigurationType": { + "type": "object", + "properties": { + "variables": { "$ref": "#/definitions/BuildLayerVariablesType", "description": "List of layer variables" } + }, + "additionalProperties": false, + "required": ["variables"] + }, + "BuildLayerVariablesType": { + "type": "array", + "uniqueItems": true, + "minItems": 1, + "items": { "$ref": "#/definitions/BuildLayerVariableType" } + }, + "BuildLayerVariableType": { + "type": "object", + "patternProperties": { + "^.*-Layer$": { "type": "string", "description": "Unique variable name for the layer" }, + "settings": { "$ref": "#/definitions/BuildConnectionSettingsType" } + }, + "additionalProperties": false + }, + "BuildConnectionSettingsType": { + "type": "array", + "uniqueItems": true, + "minItems": 1, + "items": { "$ref": "#/definitions/BuildConnectionSetType", "description": "List of connection sets" } + }, + "BuildConnectionSetType": { + "type": "object", + "properties": { + "set": { "type": "string", "description": "Connection set configurations" } + }, + "additionalProperties": false, + "required": ["set"] + }, "BuildDescType": { "description": "The lock info that describes the resolved state of contexts and also can be used as input for generators", "type": "object", diff --git a/tools/projmgr/src/ProjMgr.cpp b/tools/projmgr/src/ProjMgr.cpp index 8ac3fcfd0..f71f750c5 100644 --- a/tools/projmgr/src/ProjMgr.cpp +++ b/tools/projmgr/src/ProjMgr.cpp @@ -70,7 +70,8 @@ ProjMgr::ProjMgr() : m_ymlOrder(false), m_contextSet(false), m_relativePaths(false), - m_frozenPacks(false) + m_frozenPacks(false), + m_updateIdx(false) { } @@ -153,6 +154,7 @@ int ProjMgr::ParseCommandLine(int argc, char** argv) { cxxopts::Option contextSet("S,context-set", "Use context set", cxxopts::value()->default_value("false")); cxxopts::Option relativePaths("R,relative-paths", "Output paths relative to project or to CMSIS_PACK_ROOT", cxxopts::value()->default_value("false")); cxxopts::Option frozenPacks("frozen-packs", "The list of packs from cbuild-pack.yml is frozen and raises error if not up-to-date", cxxopts::value()->default_value("false")); + cxxopts::Option updateIdx("update-idx", "Update cbuild-idx file with layer info", cxxopts::value()->default_value("false")); // command options dictionary map>> optionsDict = { @@ -168,7 +170,7 @@ int ProjMgr::ParseCommandLine(int argc, char** argv) { {"list dependencies", { false, {context, debug, filter, load, schemaCheck, toolchain, verbose}}}, {"list contexts", { false, {debug, filter, schemaCheck, verbose, ymlOrder}}}, {"list generators", { false, {context, debug, load, schemaCheck, toolchain, verbose}}}, - {"list layers", { false, {context, debug, load, clayerSearchPath, schemaCheck, toolchain, verbose}}}, + {"list layers", { false, {context, debug, load, clayerSearchPath, schemaCheck, toolchain, verbose, updateIdx}}}, {"list toolchains", { false, {context, debug, toolchain, verbose}}}, {"list environment", { true, {}}}, }; @@ -178,7 +180,8 @@ int ProjMgr::ParseCommandLine(int argc, char** argv) { {"positional", "", cxxopts::value>()}, solution, context, contextSet, filter, generator, load, clayerSearchPath, missing, schemaCheck, noUpdateRte, output, - help, version, verbose, debug, dryRun, exportSuffix, toolchain, ymlOrder, relativePaths, frozenPacks + help, version, verbose, debug, dryRun, exportSuffix, toolchain, ymlOrder, + relativePaths, frozenPacks, updateIdx }); options.parse_positional({ "positional" }); @@ -195,6 +198,7 @@ int ProjMgr::ParseCommandLine(int argc, char** argv) { m_worker.SetDebug(m_debug); m_worker.SetDryRun(m_dryRun); m_ymlOrder = parseResult.count("yml-order"); + m_updateIdx = parseResult.count("update-idx"); m_contextSet = parseResult.count("context-set"); m_relativePaths = parseResult.count("relative-paths"); m_worker.SetPrintRelativePaths(m_relativePaths); @@ -228,7 +232,7 @@ int ProjMgr::ParseCommandLine(int argc, char** argv) { if (!m_csolutionFile.empty()) { if (!RteFsUtils::Exists(m_csolutionFile)) { ProjMgrLogger::Error(m_csolutionFile, "csolution file was not found"); - return 1; + return ErrorCode::ERROR; } m_csolutionFile = RteFsUtils::MakePathCanonical(m_csolutionFile); m_rootDir = RteUtils::ExtractFilePath(m_csolutionFile, false); @@ -261,13 +265,13 @@ int ProjMgr::ParseCommandLine(int argc, char** argv) { } } catch (cxxopts::OptionException& e) { ProjMgrLogger::Error(e.what()); - return 1; + return ErrorCode::ERROR; } // Unmatched items in the parse result if (!parseResult.unmatched().empty()) { ProjMgrLogger::Error("too many command line arguments"); - return 1; + return ErrorCode::ERROR; } if (parseResult.count("help")) { @@ -276,9 +280,9 @@ int ProjMgr::ParseCommandLine(int argc, char** argv) { // Set load packs policy if (!SetLoadPacksPolicy()) { - return 1; + return ErrorCode::ERROR; } - return 0; + return ErrorCode::SUCCESS; } @@ -288,7 +292,7 @@ int ProjMgr::RunProjMgr(int argc, char** argv, char** envp) { int res = manager.ParseCommandLine(argc, argv); if(res != 0) { // res == -1 means help or version is requested => program success - return res > 0 ? res : 0; + return res > 0 ? res : ErrorCode::SUCCESS; } // Environment variables @@ -302,7 +306,7 @@ int ProjMgr::RunProjMgr(int argc, char** argv, char** envp) { if(manager.m_worker.InitializeModel()) { res = manager.ProcessCommands(); } else { - res = 1; + res = ErrorCode::ERROR; } return res; } @@ -312,76 +316,79 @@ int ProjMgr::ProcessCommands() { // Process 'list' command if (m_args.empty()) { ProjMgrLogger::Error("list was not specified"); - return 1; + return ErrorCode::ERROR; } // Process argument if (m_args == "packs") { if (!RunListPacks()) { - return 1; + return ErrorCode::ERROR; } } else if (m_args == "boards") { if (!RunListBoards()) { - return 1; + return ErrorCode::ERROR; } } else if (m_args == "devices") { if (!RunListDevices()) { - return 1; + return ErrorCode::ERROR; } } else if (m_args == "components") { if (!RunListComponents()) { - return 1; + return ErrorCode::ERROR; } } else if (m_args == "configs") { if (!RunListConfigs()) { - return 1; + return ErrorCode::ERROR; } } else if (m_args == "dependencies") { if (!RunListDependencies()) { - return 1; + return ErrorCode::ERROR; } } else if (m_args == "contexts") { if (!RunListContexts()) { - return 1; + return ErrorCode::ERROR; } } else if (m_args == "generators") { if (!RunListGenerators()) { - return 1; + return ErrorCode::ERROR; } } else if (m_args == "layers") { if (!RunListLayers()) { - return 1; + return ErrorCode::ERROR; } } else if (m_args == "toolchains") { if (!RunListToolchains()) { - return 1; + return ErrorCode::ERROR; } } else if (m_args == "environment") { RunListEnvironment(); } else { ProjMgrLogger::Error("list was not found"); - return 1; + return ErrorCode::ERROR; } } else if (m_command == "update-rte") { // Process 'update-rte' command if (!RunConfigure()) { - return 1; + return ErrorCode::ERROR; } } else if (m_command == "convert") { // Process 'convert' command if (!RunConvert()) { - return 1; + return ErrorCode::ERROR; + } + if (m_worker.HasVarDefineError()) { + return ErrorCode::VARIABLE_NOT_DEFINED; } } else if (m_command == "run") { // Process 'run' command if (!RunCodeGenerator()) { - return 1; + return ErrorCode::ERROR; } } else { ProjMgrLogger::Error(" was not found"); - return 1; + return ErrorCode::ERROR; } - return 0; + return ErrorCode::SUCCESS; } // Set load packs policy @@ -802,8 +809,30 @@ bool ProjMgr::RunListLayers(void) { if (!m_worker.ListLayers(layers, m_clayerSearchPath)) { return false; } - for (const auto& layer : layers) { - cout << layer << endl; + if (!m_updateIdx) { + for (const auto& layer : layers) { + cout << layer << endl; + } + } + + // Update the cbuild-idx.yml file with layer information + // only when the update-idx flag is set to true. + if (m_updateIdx) { + vector orderedContexts; + map* contexts = nullptr; + m_worker.GetYmlOrderedContexts(orderedContexts); + m_worker.GetContexts(contexts); + + for (auto& contextName : orderedContexts) { + auto& contextItem = (*contexts)[contextName]; + m_allContexts.push_back(&contextItem); + } + + if (!m_allContexts.empty()) { + if (!m_emitter.GenerateCbuildIndex(m_parser, m_allContexts, m_outputDir)) { + return false; + } + } } return true; } diff --git a/tools/projmgr/src/ProjMgrWorker.cpp b/tools/projmgr/src/ProjMgrWorker.cpp index 38f892cd9..a0c59efb0 100644 --- a/tools/projmgr/src/ProjMgrWorker.cpp +++ b/tools/projmgr/src/ProjMgrWorker.cpp @@ -45,8 +45,8 @@ ProjMgrWorker::ProjMgrWorker(ProjMgrParser* parser, ProjMgrExtGenerator* extGene m_verbose(false), m_debug(false), m_dryRun(false), - m_relativePaths(false) - + m_relativePaths(false), + m_varDefineError(false) { RteCondition::SetVerboseFlags(0); } @@ -166,6 +166,7 @@ bool ProjMgrWorker::ParseContextLayers(ContextItem& context) { if (clayerFile.empty()) { if (regex_match(clayer.layer, regex(".*\\$.*\\$.*"))) { ProjMgrLogger::Warn(clayer.layer, "variable was not defined for context '" + context.name +"'"); + m_varDefineError = true; } else { ProjMgrLogger::Error(clayer.layer, "clayer file was not found"); return false; @@ -4417,3 +4418,7 @@ void ProjMgrWorker::PrintContextErrors(const string& contextName) { }); } } + +bool ProjMgrWorker::HasVarDefineError() { + return m_varDefineError; +} diff --git a/tools/projmgr/src/ProjMgrYamlEmitter.cpp b/tools/projmgr/src/ProjMgrYamlEmitter.cpp index f6900e871..b18801e97 100644 --- a/tools/projmgr/src/ProjMgrYamlEmitter.cpp +++ b/tools/projmgr/src/ProjMgrYamlEmitter.cpp @@ -71,6 +71,8 @@ class ProjMgrYamlCbuildIdx : public ProjMgrYamlBase { ProjMgrYamlCbuildIdx( YAML::Node node, const vector& processedContexts, ProjMgrParser& parser, const string& directory); + + void SetVariablesNode(YAML::Node node, const string& csolutionDir, const map>>& layerTypes); }; class ProjMgrYamlCbuildPack : public ProjMgrYamlBase { @@ -214,6 +216,45 @@ ProjMgrYamlCbuildIdx::ProjMgrYamlCbuildIdx(YAML::Node node, } SetNodeValue(node[YAML_CSOLUTION], FormatPath(parser.GetCsolution().path, directory)); + // Generate layer info for each target + vector configTargets; + for (const auto& context : processedContexts) { + // Retrieve layer information for a single target exclusively + if (std::find(configTargets.begin(), configTargets.end(), context->type.target) != configTargets.end()) { + continue; + } + + // Collect layer connection info specific to each target + if (context->validConnections.size() > 0) { + configTargets.push_back(context->type.target); + map>>> configurations; + int index = 0; + for (const auto& combination : context->validConnections) { + index++; + for (const auto& item : combination) { + if (item.type.empty()) + continue; + for (const auto& connect : item.connections) { + configurations[index][item.type][item.filename].insert(connect); + } + } + } + + // Process connection info and generate nodes + if (configurations.size() > 0) { + YAML::Node targetTypeNode; + SetNodeValue(targetTypeNode[YAML_TARGETTYPE], context->type.target); + for (const auto& [index, types] : configurations) { + YAML::Node configurationsNode, variablesNode; + SetVariablesNode(variablesNode[YAML_VARIABLES], context->csolution->directory, types); + configurationsNode[YAML_CONFIGURATION].push_back(variablesNode); + targetTypeNode[YAML_TARGET_CONFIGURATIONS].push_back(configurationsNode); + } + node[YAML_CONFIGURATIONS].push_back(targetTypeNode); + } + } + } + const auto& cprojects = parser.GetCprojects(); const auto& csolution = parser.GetCsolution(); @@ -256,6 +297,26 @@ ProjMgrYamlCbuildIdx::ProjMgrYamlCbuildIdx(YAML::Node node, } } +void ProjMgrYamlCbuildIdx::SetVariablesNode(YAML::Node node, const string& csolutionDir, const map>>& layerTypes) { + for (const auto& [type, filenames] : layerTypes) { + if (type.empty()) { + continue; + } + YAML::Node layerNode; + for (const auto& [filename, options] : filenames) { + SetNodeValue(layerNode[type + "-Layer"], RteFsUtils::RelativePath(filename, csolutionDir)); + for (const auto& connect : options) { + if (!connect->set.empty()) { + YAML::Node setNode; + SetNodeValue(setNode[YAML_SET], connect->set + " (" + connect->connect + (connect->info.empty() ? "" : " - " + connect->info) + ")"); + layerNode[YAML_SETTINGS].push_back(setNode); + } + } + } + node.push_back(layerNode); + } +} + ProjMgrYamlCbuild::ProjMgrYamlCbuild(YAML::Node node, const ContextItem* context, const string& generatorId, const string& generatorPack,const bool convError) : ProjMgrYamlBase(!generatorId.empty()) { diff --git a/tools/projmgr/test/data/TestLayers/config.cproject.yml b/tools/projmgr/test/data/TestLayers/config.cproject.yml index eb1565703..f6f48d155 100644 --- a/tools/projmgr/test/data/TestLayers/config.cproject.yml +++ b/tools/projmgr/test/data/TestLayers/config.cproject.yml @@ -4,9 +4,9 @@ project: compiler: AC6 layers: - - type: Config1 - type: Config2 - layer: config.clayer.yml + type: Config1 connections: - connect: project X diff --git a/tools/projmgr/test/data/TestLayers/ref/config.cbuild-idx.yml b/tools/projmgr/test/data/TestLayers/ref/config.cbuild-idx.yml new file mode 100644 index 000000000..1f69fe9ca --- /dev/null +++ b/tools/projmgr/test/data/TestLayers/ref/config.cbuild-idx.yml @@ -0,0 +1,33 @@ +build-idx: + generated-by: csolution version 0.0.0+ga3f9f5af + csolution: config.csolution.yml + configurations: + - target-type: RteTest_ARMCM3 + target-configurations: + - configuration: + - variables: + - Config1-Layer: ../../../../../../test/packs/ARM/RteTest_DFP/0.2.0/Layers/config1.clayer.yml + settings: + - set: set1.select1 (connect A - set 1 select 1) + - set: set2.select1 (connect C - set 2 select 1) + - Config2-Layer: ../../../../../../test/packs/ARM/RteTest_DFP/0.2.0/Layers/config2.clayer.yml + settings: + - set: set1.select1 (connect F - set 1 select 1) + - configuration: + - variables: + - Config1-Layer: ../../../../../../test/packs/ARM/RteTest_DFP/0.2.0/Layers/config1.clayer.yml + settings: + - set: set1.select2 (connect B - set 1 select 2) + - set: set2.select2 (connect D - set 2 select 2) + - Config2-Layer: ../../../../../../test/packs/ARM/RteTest_DFP/0.2.0/Layers/config2.clayer.yml + settings: + - set: set1.select2 (connect G - set 1 select 2) + cprojects: + - cproject: config.cproject.yml + clayers: + - clayer: . + - clayer: config.clayer.yml + cbuilds: + - cbuild: config.CompatibleLayers+RteTest_ARMCM3.cbuild.yml + project: config + configuration: .CompatibleLayers+RteTest_ARMCM3 diff --git a/tools/projmgr/test/data/TestLayers/select.clayer.yml b/tools/projmgr/test/data/TestLayers/select.clayer.yml index ecddb7e0a..2b3da37a4 100644 --- a/tools/projmgr/test/data/TestLayers/select.clayer.yml +++ b/tools/projmgr/test/data/TestLayers/select.clayer.yml @@ -1,7 +1,7 @@ # yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/main/tools/projmgr/schemas/clayer.schema.json layer: - + type: Board components: - component: Board:Test:Rev1 diff --git a/tools/projmgr/test/src/ProjMgrUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUnitTests.cpp index 5b45c411b..925e09cb9 100644 --- a/tools/projmgr/test/src/ProjMgrUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUnitTests.cpp @@ -1529,6 +1529,38 @@ info csolution: valid configuration #3: \\(context 'genericlayers.CompatibleLaye EXPECT_TRUE(regex_match(outStr, regex(expectedOutStr))); } + +TEST_F(ProjMgrUnitTests, ListLayersConfigurations_update_idx) { + StdStreamRedirect streamRedirect; + char* argv[6]; + const string& csolution = testinput_folder + "/TestLayers/config.csolution.yml"; + string expectedOutStr = ".*config.cbuild-idx.yml - info csolution: file generated successfully\\n"; + + argv[1] = (char*)"list"; + argv[2] = (char*)"layers"; + argv[3] = (char*)"--solution"; + argv[4] = (char*)csolution.c_str(); + argv[5] = (char*)"--update-idx"; + + auto replacePackPathFunc = [](const std::string& in) { + std::string str = in, packPathEnd = "/test/packs", packPathStart = "-Layer: "; + auto endPos = str.find(packPathEnd); + if (endPos != string::npos) { + auto startPos = str.find(packPathStart); + startPos += packPathStart.length(); + auto packPath = str.substr(startPos, endPos + packPathEnd.length() - startPos); + RteUtils::ReplaceAll(str, packPath, "../../../../../../test/packs"); + } + return str; + }; + + EXPECT_EQ(0, RunProjMgr(6, argv, 0)); + EXPECT_TRUE(regex_match(streamRedirect.GetOutString(), regex(expectedOutStr))); + ProjMgrTestEnv::CompareFile(testinput_folder + "/TestLayers/ref/config.cbuild-idx.yml", + testinput_folder + "/TestLayers/config.cbuild-idx.yml", replacePackPathFunc); + EXPECT_TRUE(ProjMgrYamlSchemaChecker().Validate(testinput_folder + "/TestLayers/config.cbuild-idx.yml")); +} + TEST_F(ProjMgrUnitTests, ListLayersConfigurations) { StdStreamRedirect streamRedirect; char* argv[6]; @@ -1593,17 +1625,17 @@ TEST_F(ProjMgrUnitTests, ListLayersMultipleSelect) { const string& expectedOutStr = "\ info csolution: valid configuration #1: \\(context 'select\\+RteTest_ARMCM3'\\)\n\ - .*/TestLayers/select.clayer.yml\n\ .*/TestLayers/select.cproject.yml\n\ set: set1.select1 \\(project X - set 1 select 1\\)\n\ + .*/TestLayers/select.clayer.yml \\(layer type: Board\\)\n\ \n\ info csolution: valid configuration #2: \\(context 'select\\+RteTest_ARMCM3'\\)\n\ - .*/TestLayers/select.clayer.yml\n\ .*/TestLayers/select.cproject.yml\n\ set: set1.select2 \\(project Y - set 1 select 2\\)\n\ set: set1.select2 \\(project Z - set 1 select 2\\)\n\ + .*/TestLayers/select.clayer.yml \\(layer type: Board\\)\n\ \n\ -.*/TestLayers/select.clayer.yml\n\ +.*/TestLayers/select.clayer.yml \\(layer type: Board\\)\n\ "; const string& outStr = streamRedirect.GetOutString(); @@ -3858,7 +3890,7 @@ TEST_F(ProjMgrUnitTests, RunCheckContextProcessing) { argv[4] = (char*)"contexts.B1+T1"; argv[5] = (char*)"-o"; argv[6] = (char*)testoutput_folder.c_str(); - EXPECT_EQ(0, RunProjMgr(7, argv, 0)); + EXPECT_EQ(2, RunProjMgr(7, argv, 0)); // Check warning for processed context const string expected = "$LayerVar$ - warning csolution: variable was not defined for context 'contexts.B1+T1'";