diff --git a/Source/cmCMakePresetsErrors.cxx b/Source/cmCMakePresetsErrors.cxx index 36dceaec79..5679eeaa44 100644 --- a/Source/cmCMakePresetsErrors.cxx +++ b/Source/cmCMakePresetsErrors.cxx @@ -235,10 +235,19 @@ void TEST_OUTPUT_TRUNCATION_UNSUPPORTED(cmJSONState* state) "preset support"); } -void INVALID_WORKFLOW_STEPS(std::string const& workflowStep, - cmJSONState* state) +namespace { +std::string WorkflowStepLabel(cm::string_view stepType, + std::string const& stepName) { - state->AddError(cmStrCat("Invalid workflow step \"", workflowStep, '"')); + return cmStrCat("of type \"", stepType, "\" named \"", stepName, '"'); +} +} + +void INVALID_WORKFLOW_STEPS(cm::string_view stepType, + std::string const& stepName, cmJSONState* state) +{ + state->AddError( + cmStrCat("Invalid workflow step ", WorkflowStepLabel(stepType, stepName))); } void WORKFLOW_STEP_CONFIGURE_PRESET_MISMATCH( @@ -266,25 +275,31 @@ void NO_WORKFLOW_STEPS(std::string const& presetName, cmJSONState* state) cmStrCat("No workflow steps specified for \"", presetName, '"')); } -void FIRST_WORKFLOW_STEP_NOT_CONFIGURE(std::string const& stepName, +void FIRST_WORKFLOW_STEP_NOT_CONFIGURE(cm::string_view stepType, + std::string const& stepName, cmJSONState* state) { - state->AddError(cmStrCat("First workflow step \"", stepName, - "\" must be a configure step")); + state->AddError(cmStrCat("First workflow step ", + WorkflowStepLabel(stepType, stepName), + " must be a configure step")); } -void CONFIGURE_WORKFLOW_STEP_NOT_FIRST(std::string const& stepName, +void CONFIGURE_WORKFLOW_STEP_NOT_FIRST(cm::string_view stepType, + std::string const& stepName, cmJSONState* state) { - state->AddError(cmStrCat("Configure workflow step \"", stepName, - "\" must be the first step")); + state->AddError(cmStrCat("Workflow step ", + WorkflowStepLabel(stepType, stepName), + " must be the first step")); } -void WORKFLOW_STEP_UNREACHABLE_FROM_FILE(std::string const& workflowStep, +void WORKFLOW_STEP_UNREACHABLE_FROM_FILE(cm::string_view stepType, + std::string const& stepName, cmJSONState* state) { - state->AddError(cmStrCat("Workflow step \"", workflowStep, - "\" is unreachable from preset's file")); + state->AddError(cmStrCat("Workflow step ", + WorkflowStepLabel(stepType, stepName), + " is unreachable from preset's file")); } void CTEST_JUNIT_UNSUPPORTED(cmJSONState* state) diff --git a/Source/cmCMakePresetsErrors.h b/Source/cmCMakePresetsErrors.h index 14a3e29e8f..fd1ca03578 100644 --- a/Source/cmCMakePresetsErrors.h +++ b/Source/cmCMakePresetsErrors.h @@ -90,8 +90,8 @@ void CYCLIC_INCLUDE(std::string const& file, cmJSONState* state); void TEST_OUTPUT_TRUNCATION_UNSUPPORTED(cmJSONState* state); -void INVALID_WORKFLOW_STEPS(std::string const& workflowStep, - cmJSONState* state); +void INVALID_WORKFLOW_STEPS(cm::string_view stepType, + std::string const& stepName, cmJSONState* state); void WORKFLOW_STEP_CONFIGURE_PRESET_MISMATCH( std::string const& kind, std::string const& workflowStep, @@ -103,13 +103,16 @@ void INVALID_TEST_FILTER_INCLUDE_INDEX(Json::Value const* value, void NO_WORKFLOW_STEPS(std::string const& presetName, cmJSONState* state); -void FIRST_WORKFLOW_STEP_NOT_CONFIGURE(std::string const& stepName, +void FIRST_WORKFLOW_STEP_NOT_CONFIGURE(cm::string_view stepType, + std::string const& stepName, cmJSONState* state); -void CONFIGURE_WORKFLOW_STEP_NOT_FIRST(std::string const& stepName, +void CONFIGURE_WORKFLOW_STEP_NOT_FIRST(cm::string_view stepType, + std::string const& stepName, cmJSONState* state); -void WORKFLOW_STEP_UNREACHABLE_FROM_FILE(std::string const& workflowStep, +void WORKFLOW_STEP_UNREACHABLE_FROM_FILE(cm::string_view stepType, + std::string const& stepName, cmJSONState* state); void CTEST_JUNIT_UNSUPPORTED(cmJSONState* state); diff --git a/Source/cmCMakePresetsGraph.cxx b/Source/cmCMakePresetsGraph.cxx index 9fb27b2eda..e2d1934bd4 100644 --- a/Source/cmCMakePresetsGraph.cxx +++ b/Source/cmCMakePresetsGraph.cxx @@ -64,6 +64,21 @@ using cmCMakePresetsGraphInternal::ExpandMacros; bool gSkipNewLine = true; +char const* WorkflowStepTypeToString(WorkflowPreset::WorkflowStep::Type type) +{ + switch (type) { + case WorkflowPreset::WorkflowStep::Type::Configure: + return "configure"; + case WorkflowPreset::WorkflowStep::Type::Build: + return "build"; + case WorkflowPreset::WorkflowStep::Type::Test: + return "test"; + case WorkflowPreset::WorkflowStep::Type::Package: + return "package"; + } + return ""; +} + void InheritString(std::string& child, std::string const& parent) { if (child.empty()) { @@ -701,6 +716,7 @@ namespace { template bool SetupWorkflowConfigurePreset(T const& preset, ConfigurePreset const*& configurePreset, + char const*, std::string const&, cmJSONState* state) { if (preset.ConfigurePreset != configurePreset->Name) { @@ -715,7 +731,7 @@ bool SetupWorkflowConfigurePreset(T const& preset, template <> bool SetupWorkflowConfigurePreset( ConfigurePreset const& preset, ConfigurePreset const*& configurePreset, - cmJSONState*) + char const*, std::string const&, cmJSONState*) { configurePreset = &preset; return true; @@ -725,20 +741,23 @@ template bool TryReachPresetFromWorkflow( WorkflowPreset const& origin, std::map> const& presets, std::string const& name, - ConfigurePreset const*& configurePreset, cmJSONState* state) + char const* workflowStepType, ConfigurePreset const*& configurePreset, + cmJSONState* state) { auto it = presets.find(name); if (it == presets.end()) { - cmCMakePresetsErrors::INVALID_WORKFLOW_STEPS(name, state); + cmCMakePresetsErrors::INVALID_WORKFLOW_STEPS(workflowStepType, name, + state); return false; } if (!origin.OriginFile->ReachableFiles.count( it->second.Unexpanded.OriginFile)) { - cmCMakePresetsErrors::WORKFLOW_STEP_UNREACHABLE_FROM_FILE(name, state); + cmCMakePresetsErrors::WORKFLOW_STEP_UNREACHABLE_FROM_FILE(workflowStepType, + name, state); return false; } - return SetupWorkflowConfigurePreset(it->second.Unexpanded, - configurePreset, state); + return SetupWorkflowConfigurePreset( + it->second.Unexpanded, configurePreset, workflowStepType, name, state); } } @@ -1382,14 +1401,15 @@ bool cmCMakePresetsGraph::ReadProjectPresetsInternal( ConfigurePreset const* configurePreset = nullptr; for (auto const& step : it.second.Unexpanded.Steps) { + char const* const stepType = WorkflowStepTypeToString(step.PresetType); if (!configurePreset && step.PresetType != Type::Configure) { cmCMakePresetsErrors::FIRST_WORKFLOW_STEP_NOT_CONFIGURE( - step.PresetName, &this->parseState); + stepType, step.PresetName, &this->parseState); return false; } if (configurePreset && step.PresetType == Type::Configure) { cmCMakePresetsErrors::CONFIGURE_WORKFLOW_STEP_NOT_FIRST( - step.PresetName, &this->parseState); + stepType, step.PresetName, &this->parseState); return false; } @@ -1397,22 +1417,22 @@ bool cmCMakePresetsGraph::ReadProjectPresetsInternal( case Type::Configure: result = TryReachPresetFromWorkflow( it.second.Unexpanded, this->ConfigurePresets, step.PresetName, - configurePreset, &this->parseState); + stepType, configurePreset, &this->parseState); break; case Type::Build: result = TryReachPresetFromWorkflow( it.second.Unexpanded, this->BuildPresets, step.PresetName, - configurePreset, &this->parseState); + stepType, configurePreset, &this->parseState); break; case Type::Test: result = TryReachPresetFromWorkflow( - it.second.Unexpanded, this->TestPresets, step.PresetName, + it.second.Unexpanded, this->TestPresets, step.PresetName, stepType, configurePreset, &this->parseState); break; case Type::Package: result = TryReachPresetFromWorkflow( it.second.Unexpanded, this->PackagePresets, step.PresetName, - configurePreset, &this->parseState); + stepType, configurePreset, &this->parseState); break; } if (!result) { diff --git a/Source/cmake.cxx b/Source/cmake.cxx index fa569374e6..40de2f777a 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -4228,38 +4228,46 @@ bool cmake::Open(std::string const& dir, DryRun dryRun) } #if !defined(CMAKE_BOOTSTRAP) +namespace { +std::string WorkflowStepLabel(cm::static_string_view type, + std::string const& name) +{ + return cmStrCat("of type \"", type, "\" named \"", name, '"'); +} +} + template T const* cmake::FindPresetForWorkflow( cm::static_string_view type, std::map> const& presets, cmCMakePresetsGraph::WorkflowPreset::WorkflowStep const& step) { + std::string const stepLabel = WorkflowStepLabel(type, step.PresetName); auto it = presets.find(step.PresetName); if (it == presets.end()) { - cmSystemTools::Error(cmStrCat("No such ", type, " preset in ", - this->GetHomeDirectory(), ": \"", - step.PresetName, '"')); + cmSystemTools::Error(cmStrCat("No such preset for workflow step ", + stepLabel, " in ", + this->GetHomeDirectory())); return nullptr; } if (it->second.Unexpanded.Hidden) { - cmSystemTools::Error(cmStrCat("Cannot use hidden ", type, " preset in ", - this->GetHomeDirectory(), ": \"", - step.PresetName, '"')); + cmSystemTools::Error( + cmStrCat("Cannot use hidden preset for workflow step ", stepLabel, + " in ", this->GetHomeDirectory())); return nullptr; } if (!it->second.Expanded) { - cmSystemTools::Error(cmStrCat("Could not evaluate ", type, " preset \"", - step.PresetName, - "\": Invalid macro expansion")); + cmSystemTools::Error(cmStrCat("Could not evaluate workflow step ", + stepLabel, ": Invalid macro expansion")); return nullptr; } if (!it->second.Expanded->ConditionResult) { - cmSystemTools::Error(cmStrCat("Cannot use disabled ", type, " preset in ", - this->GetHomeDirectory(), ": \"", - step.PresetName, '"')); + cmSystemTools::Error( + cmStrCat("Cannot use disabled preset for workflow step ", stepLabel, + " in ", this->GetHomeDirectory())); return nullptr; } @@ -4437,13 +4445,17 @@ int cmake::Workflow(cmCMakePresetsWorkflowArgs const& args) << std::flush; cmUVProcessChain::Status const status = step.Action(); if (status.ExitStatus != 0) { + cmSystemTools::Error( + cmStrCat("Workflow step ", WorkflowStepLabel(step.Type, step.Name), + " failed with exit code ", status.ExitStatus)); exitStatus = static_cast(status.ExitStatus); break; } auto const codeReasonPair = status.GetException(); if (codeReasonPair.first != cmUVProcessChain::ExceptionCode::None) { - std::cout << "Step command ended abnormally: " << codeReasonPair.second - << std::endl; + cmSystemTools::Error( + cmStrCat("Workflow step ", WorkflowStepLabel(step.Type, step.Name), + " command ended abnormally: ", codeReasonPair.second)); exitStatus = status.SpawnResult != 0 ? status.SpawnResult : status.TermSignal; break; diff --git a/Tests/RunCMake/CMakePresetsWorkflow/BadExitCode-stderr.txt b/Tests/RunCMake/CMakePresetsWorkflow/BadExitCode-stderr.txt index 0690c694ba..6f597ff7f5 100644 --- a/Tests/RunCMake/CMakePresetsWorkflow/BadExitCode-stderr.txt +++ b/Tests/RunCMake/CMakePresetsWorkflow/BadExitCode-stderr.txt @@ -1,4 +1,5 @@ ^Errors while running CTest Output from these tests are in: [^ ]*/Tests/RunCMake/CMakePresetsWorkflow/BadExitCode/build/Testing/Temporary/LastTest\.log -Use "--rerun-failed --output-on-failure" to re-run the failed cases verbosely\.$ +Use "--rerun-failed --output-on-failure" to re-run the failed cases verbosely\. +CMake Error: Workflow step of type "test" named "default" failed with exit code 8$ diff --git a/Tests/RunCMake/CMakePresetsWorkflow/FirstStepNotConfigure-stderr.txt b/Tests/RunCMake/CMakePresetsWorkflow/FirstStepNotConfigure-stderr.txt index 776257bd93..cfc3a4a8ca 100644 --- a/Tests/RunCMake/CMakePresetsWorkflow/FirstStepNotConfigure-stderr.txt +++ b/Tests/RunCMake/CMakePresetsWorkflow/FirstStepNotConfigure-stderr.txt @@ -1,3 +1,3 @@ ^CMake Error: Could not read presets from [^ ]*/Tests/RunCMake/CMakePresetsWorkflow/FirstStepNotConfigure: -First workflow step "default" must be a configure step$ +First workflow step of type "build" named "default" must be a configure step$ diff --git a/Tests/RunCMake/CMakePresetsWorkflow/NonexistentStep-stderr.txt b/Tests/RunCMake/CMakePresetsWorkflow/NonexistentStep-stderr.txt index a9029e116b..5f09fed81a 100644 --- a/Tests/RunCMake/CMakePresetsWorkflow/NonexistentStep-stderr.txt +++ b/Tests/RunCMake/CMakePresetsWorkflow/NonexistentStep-stderr.txt @@ -1,3 +1,3 @@ ^CMake Error: Could not read presets from [^ ]*/Tests/RunCMake/CMakePresetsWorkflow/NonexistentStep: -Invalid workflow step "default"$ +Invalid workflow step of type "configure" named "default"$ diff --git a/Tests/RunCMake/CMakePresetsWorkflow/SecondStepConfigure-stderr.txt b/Tests/RunCMake/CMakePresetsWorkflow/SecondStepConfigure-stderr.txt index 35eac16c38..f211a71e4e 100644 --- a/Tests/RunCMake/CMakePresetsWorkflow/SecondStepConfigure-stderr.txt +++ b/Tests/RunCMake/CMakePresetsWorkflow/SecondStepConfigure-stderr.txt @@ -1,3 +1,3 @@ ^CMake Error: Could not read presets from [^ ]*/Tests/RunCMake/CMakePresetsWorkflow/SecondStepConfigure: -Configure workflow step "default" must be the first step +Workflow step of type "configure" named "default" must be the first step diff --git a/Tests/RunCMake/CMakePresetsWorkflow/UnreachableStep-stderr.txt b/Tests/RunCMake/CMakePresetsWorkflow/UnreachableStep-stderr.txt index f0a36f898a..711cdb49ae 100644 --- a/Tests/RunCMake/CMakePresetsWorkflow/UnreachableStep-stderr.txt +++ b/Tests/RunCMake/CMakePresetsWorkflow/UnreachableStep-stderr.txt @@ -1,3 +1,3 @@ ^CMake Error: Could not read presets from [^ ]*/Tests/RunCMake/CMakePresetsWorkflow/UnreachableStep: -Workflow step "default" is unreachable from preset's file$ +Workflow step of type "configure" named "default" is unreachable from preset's file$ diff --git a/Tests/RunCMake/CMakePresetsWorkflow/WorkflowStepDisabled-stderr.txt b/Tests/RunCMake/CMakePresetsWorkflow/WorkflowStepDisabled-stderr.txt index b598b272f1..1fd0dde853 100644 --- a/Tests/RunCMake/CMakePresetsWorkflow/WorkflowStepDisabled-stderr.txt +++ b/Tests/RunCMake/CMakePresetsWorkflow/WorkflowStepDisabled-stderr.txt @@ -1,2 +1,2 @@ -^CMake Error: Cannot use disabled configure preset in [^ -]*/Tests/RunCMake/CMakePresetsWorkflow/WorkflowStepDisabled: "default"$ +^CMake Error: Cannot use disabled preset for workflow step of type "configure" named "default" in [^ +]*/Tests/RunCMake/CMakePresetsWorkflow/WorkflowStepDisabled$ diff --git a/Tests/RunCMake/CMakePresetsWorkflow/WorkflowStepHidden-stderr.txt b/Tests/RunCMake/CMakePresetsWorkflow/WorkflowStepHidden-stderr.txt index 838ded5141..38b361a4c3 100644 --- a/Tests/RunCMake/CMakePresetsWorkflow/WorkflowStepHidden-stderr.txt +++ b/Tests/RunCMake/CMakePresetsWorkflow/WorkflowStepHidden-stderr.txt @@ -1,2 +1,2 @@ -^CMake Error: Cannot use hidden configure preset in [^ -]*/Tests/RunCMake/CMakePresetsWorkflow/WorkflowStepHidden: "default"$ +^CMake Error: Cannot use hidden preset for workflow step of type "configure" named "default" in [^ +]*/Tests/RunCMake/CMakePresetsWorkflow/WorkflowStepHidden$ diff --git a/Tests/RunCMake/CMakePresetsWorkflow/WorkflowStepInvalidMacro-stderr.txt b/Tests/RunCMake/CMakePresetsWorkflow/WorkflowStepInvalidMacro-stderr.txt index f132a93364..aa1326aa95 100644 --- a/Tests/RunCMake/CMakePresetsWorkflow/WorkflowStepInvalidMacro-stderr.txt +++ b/Tests/RunCMake/CMakePresetsWorkflow/WorkflowStepInvalidMacro-stderr.txt @@ -1 +1 @@ -^CMake Error: Could not evaluate configure preset "default": Invalid macro expansion$ +^CMake Error: Could not evaluate workflow step of type "configure" named "default": Invalid macro expansion$