cmCMakePresetsErrors.cxx 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "cmConfigure.h" // IWYU pragma: keep
  4. #include "cmCMakePresetsErrors.h"
  5. #include <functional>
  6. #include <utility>
  7. #include <vector>
  8. #include <cm3p/json/value.h>
  9. #include "cmJSONHelpers.h"
  10. #include "cmJSONState.h"
  11. #include "cmStringAlgorithms.h"
  12. namespace cmCMakePresetsErrors {
  13. const Json::Value* getPreset(cmJSONState* state)
  14. {
  15. if (state->parseStack.size() < 2) {
  16. return nullptr;
  17. }
  18. std::string firstKey = state->parseStack[0].first;
  19. if (firstKey == "configurePresets" || firstKey == "packagePresets" ||
  20. firstKey == "buildPresets" || firstKey == "testPresets") {
  21. return state->parseStack[1].second;
  22. }
  23. return nullptr;
  24. }
  25. std::string getPresetName(cmJSONState* state)
  26. {
  27. const Json::Value* preset = getPreset(state);
  28. if (preset && preset->isMember("name")) {
  29. return preset->operator[]("name").asString();
  30. }
  31. return "";
  32. }
  33. std::string getVariableName(cmJSONState* state)
  34. {
  35. std::string var = state->key_after("cacheVariables");
  36. std::string errMsg = cmStrCat("variable \"", var, "\"");
  37. errMsg = cmStrCat(errMsg, " for preset \"", getPresetName(state), "\"");
  38. return errMsg;
  39. }
  40. void FILE_NOT_FOUND(const std::string& filename, cmJSONState* state)
  41. {
  42. state->AddError(cmStrCat("File not found: ", filename));
  43. }
  44. void INVALID_ROOT(const Json::Value* value, cmJSONState* state)
  45. {
  46. state->AddErrorAtValue("Invalid root object", value);
  47. }
  48. void NO_VERSION(const Json::Value* value, cmJSONState* state)
  49. {
  50. state->AddErrorAtValue("No \"version\" field", value);
  51. }
  52. void INVALID_VERSION(const Json::Value* value, cmJSONState* state)
  53. {
  54. state->AddErrorAtValue("Invalid \"version\" field", value);
  55. }
  56. void UNRECOGNIZED_VERSION(const Json::Value* value, cmJSONState* state)
  57. {
  58. state->AddErrorAtValue("Unrecognized \"version\" field", value);
  59. }
  60. void INVALID_PRESETS(const Json::Value* value, cmJSONState* state)
  61. {
  62. state->AddErrorAtValue("Invalid \"configurePresets\" field", value);
  63. }
  64. void INVALID_PRESET(const Json::Value* value, cmJSONState* state)
  65. {
  66. state->AddErrorAtValue("Invalid preset", value);
  67. }
  68. void INVALID_PRESET_NAMED(const std::string& presetName, cmJSONState* state)
  69. {
  70. state->AddError(cmStrCat("Invalid preset: \"", presetName, "\""));
  71. }
  72. void INVALID_VARIABLE(const Json::Value* value, cmJSONState* state)
  73. {
  74. std::string var = cmCMakePresetsErrors::getVariableName(state);
  75. state->AddErrorAtValue(cmStrCat("Invalid CMake ", var), value);
  76. }
  77. void DUPLICATE_PRESETS(const std::string& presetName, cmJSONState* state)
  78. {
  79. state->AddError(cmStrCat("Duplicate preset: \"", presetName, "\""));
  80. }
  81. void CYCLIC_PRESET_INHERITANCE(const std::string& presetName,
  82. cmJSONState* state)
  83. {
  84. state->AddError(
  85. cmStrCat("Cyclic preset inheritance for preset \"", presetName, "\""));
  86. }
  87. void INHERITED_PRESET_UNREACHABLE_FROM_FILE(const std::string& presetName,
  88. cmJSONState* state)
  89. {
  90. state->AddError(cmStrCat("Inherited preset \"", presetName,
  91. "\" is unreachable from preset's file"));
  92. }
  93. void CONFIGURE_PRESET_UNREACHABLE_FROM_FILE(const std::string& presetName,
  94. cmJSONState* state)
  95. {
  96. state->AddError(cmStrCat("Configure preset \"", presetName,
  97. "\" is unreachable from preset's file"));
  98. }
  99. void INVALID_MACRO_EXPANSION(const std::string& presetName, cmJSONState* state)
  100. {
  101. state->AddError(cmStrCat("Invalid macro expansion in \"", presetName, "\""));
  102. }
  103. void BUILD_TEST_PRESETS_UNSUPPORTED(const Json::Value*, cmJSONState* state)
  104. {
  105. state->AddError("File version must be 2 or higher for build and test preset "
  106. "support");
  107. }
  108. void PACKAGE_PRESETS_UNSUPPORTED(const Json::Value*, cmJSONState* state)
  109. {
  110. state->AddError(
  111. "File version must be 6 or higher for package preset support");
  112. }
  113. void WORKFLOW_PRESETS_UNSUPPORTED(const Json::Value*, cmJSONState* state)
  114. {
  115. state->AddError(
  116. "File version must be 6 or higher for workflow preset support");
  117. }
  118. void INCLUDE_UNSUPPORTED(const Json::Value*, cmJSONState* state)
  119. {
  120. state->AddError("File version must be 4 or higher for include support");
  121. }
  122. void INVALID_INCLUDE(const Json::Value* value, cmJSONState* state)
  123. {
  124. state->AddErrorAtValue("Invalid \"include\" field", value);
  125. }
  126. void INVALID_CONFIGURE_PRESET(const std::string& presetName,
  127. cmJSONState* state)
  128. {
  129. state->AddError(
  130. cmStrCat(R"(Invalid "configurePreset": ")", presetName, "\""));
  131. }
  132. void INSTALL_PREFIX_UNSUPPORTED(const Json::Value* value, cmJSONState* state)
  133. {
  134. state->AddErrorAtValue(
  135. "File version must be 3 or higher for installDir preset "
  136. "support",
  137. value);
  138. }
  139. void CONDITION_UNSUPPORTED(cmJSONState* state)
  140. {
  141. state->AddError("File version must be 3 or higher for condition support");
  142. }
  143. void TOOLCHAIN_FILE_UNSUPPORTED(cmJSONState* state)
  144. {
  145. state->AddError("File version must be 3 or higher for toolchainFile preset "
  146. "support");
  147. }
  148. void GRAPHVIZ_FILE_UNSUPPORTED(cmJSONState* state)
  149. {
  150. state->AddError(
  151. "File version must be 10 or higher for graphviz preset support");
  152. }
  153. void CYCLIC_INCLUDE(const std::string& file, cmJSONState* state)
  154. {
  155. state->AddError(cmStrCat("Cyclic include among preset files: ", file));
  156. }
  157. void TEST_OUTPUT_TRUNCATION_UNSUPPORTED(cmJSONState* state)
  158. {
  159. state->AddError("File version must be 5 or higher for testOutputTruncation "
  160. "preset support");
  161. }
  162. void INVALID_WORKFLOW_STEPS(const std::string& workflowStep,
  163. cmJSONState* state)
  164. {
  165. state->AddError(cmStrCat("Invalid workflow step \"", workflowStep, "\""));
  166. }
  167. void NO_WORKFLOW_STEPS(const std::string& presetName, cmJSONState* state)
  168. {
  169. state->AddError(
  170. cmStrCat("No workflow steps specified for \"", presetName, "\""));
  171. }
  172. void FIRST_WORKFLOW_STEP_NOT_CONFIGURE(const std::string& stepName,
  173. cmJSONState* state)
  174. {
  175. state->AddError(cmStrCat("First workflow step \"", stepName,
  176. "\" must be a configure step"));
  177. }
  178. void CONFIGURE_WORKFLOW_STEP_NOT_FIRST(const std::string& stepName,
  179. cmJSONState* state)
  180. {
  181. state->AddError(cmStrCat("Configure workflow step \"", stepName,
  182. "\" must be the first step"));
  183. }
  184. void WORKFLOW_STEP_UNREACHABLE_FROM_FILE(const std::string& workflowStep,
  185. cmJSONState* state)
  186. {
  187. state->AddError(cmStrCat("Workflow step \"", workflowStep,
  188. "\" is unreachable from preset's file"));
  189. }
  190. void CTEST_JUNIT_UNSUPPORTED(cmJSONState* state)
  191. {
  192. state->AddError(
  193. "File version must be 6 or higher for CTest JUnit output support");
  194. }
  195. void TRACE_UNSUPPORTED(cmJSONState* state)
  196. {
  197. state->AddError("File version must be 7 or higher for trace preset support");
  198. }
  199. JsonErrors::ErrorGenerator UNRECOGNIZED_VERSION_RANGE(int min, int max)
  200. {
  201. return [min, max](const Json::Value* value, cmJSONState* state) -> void {
  202. state->AddErrorAtValue(cmStrCat("Unrecognized \"version\" ",
  203. value->asString(), ": must be >=", min,
  204. " and <=", max),
  205. value);
  206. };
  207. }
  208. JsonErrors::ErrorGenerator UNRECOGNIZED_CMAKE_VERSION(
  209. const std::string& version, int current, int required)
  210. {
  211. return [version, current, required](const Json::Value* value,
  212. cmJSONState* state) -> void {
  213. state->AddErrorAtValue(cmStrCat("\"cmakeMinimumRequired\" ", version,
  214. " version ", required,
  215. " must be less than ", current),
  216. value);
  217. };
  218. }
  219. void INVALID_PRESET_NAME(const Json::Value* value, cmJSONState* state)
  220. {
  221. std::string errMsg = "Invalid Preset Name";
  222. if (value && value->isConvertibleTo(Json::ValueType::stringValue) &&
  223. !value->asString().empty()) {
  224. errMsg = cmStrCat(errMsg, ": ", value->asString());
  225. }
  226. state->AddErrorAtValue(errMsg, value);
  227. }
  228. void INVALID_CONDITION(const Json::Value* value, cmJSONState* state)
  229. {
  230. state->AddErrorAtValue(
  231. cmStrCat("Invalid condition for preset \"", getPresetName(state), "\""),
  232. value);
  233. }
  234. JsonErrors::ErrorGenerator INVALID_CONDITION_OBJECT(
  235. JsonErrors::ObjectError errorType, const Json::Value::Members& extraFields)
  236. {
  237. return JsonErrors::INVALID_NAMED_OBJECT(
  238. [](const Json::Value*, cmJSONState* state) -> std::string {
  239. return cmStrCat(" condition for preset \"", getPresetName(state), "\"");
  240. })(errorType, extraFields);
  241. }
  242. JsonErrors::ErrorGenerator INVALID_VARIABLE_OBJECT(
  243. JsonErrors::ObjectError errorType, const Json::Value::Members& extraFields)
  244. {
  245. return JsonErrors::INVALID_NAMED_OBJECT(
  246. [](const Json::Value*, cmJSONState* state) -> std::string {
  247. return getVariableName(state);
  248. })(errorType, extraFields);
  249. }
  250. JsonErrors::ErrorGenerator INVALID_PRESET_OBJECT(
  251. JsonErrors::ObjectError errorType, const Json::Value::Members& extraFields)
  252. {
  253. return JsonErrors::INVALID_NAMED_OBJECT(
  254. [](const Json::Value*, cmJSONState*) -> std::string { return "Preset"; })(
  255. errorType, extraFields);
  256. }
  257. JsonErrors::ErrorGenerator INVALID_ROOT_OBJECT(
  258. JsonErrors::ObjectError errorType, const Json::Value::Members& extraFields)
  259. {
  260. return JsonErrors::INVALID_NAMED_OBJECT(
  261. [](const Json::Value*, cmJSONState*) -> std::string {
  262. return "root object";
  263. })(errorType, extraFields);
  264. }
  265. void PRESET_MISSING_FIELD(const std::string& presetName,
  266. const std::string& missingField, cmJSONState* state)
  267. {
  268. state->AddError(cmStrCat("Preset \"", presetName, "\" missing field \"",
  269. missingField, "\""));
  270. }
  271. void SCHEMA_UNSUPPORTED(cmJSONState* state)
  272. {
  273. state->AddError("File version must be 8 or higher for $schema support");
  274. }
  275. }