ceedling 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (383) hide show
  1. checksums.yaml +4 -4
  2. data/GIT_COMMIT_SHA +1 -1
  3. data/README.md +57 -58
  4. data/Rakefile +5 -3
  5. data/assets/features/ceedling +1 -1
  6. data/assets/fixtures/test_source_file_duplicate_basenames/test_calc_typo.c +14 -0
  7. data/assets/fixtures/tests_with_duplicate_test_names/test_foo.c +21 -0
  8. data/bin/actionator.rb +6 -12
  9. data/bin/app_cfg.rb +35 -1
  10. data/bin/ceedling +13 -3
  11. data/bin/cli.rb +25 -6
  12. data/bin/cli_handler.rb +119 -73
  13. data/bin/cli_helper.rb +56 -78
  14. data/bin/installation_selector.rb +81 -0
  15. data/bin/launchinator.rb +69 -0
  16. data/bin/mixin_resolvinator.rb +26 -36
  17. data/bin/objects.yml +13 -0
  18. data/bin/path_validator.rb +25 -29
  19. data/bin/versionator.rb +47 -48
  20. data/ceedling.gemspec +19 -15
  21. data/docs/BreakingChanges.md +70 -1
  22. data/docs/Changelog.md +84 -3
  23. data/docs/KnownIssues.md +90 -4
  24. data/docs/ReleaseNotes.md +13 -0
  25. data/docs/overrides/main.html +11 -8
  26. data/lib/ceedling/build_log_writer.rb +33 -0
  27. data/lib/ceedling/config/build_root_policy.rb +70 -0
  28. data/lib/ceedling/config/configurator.rb +19 -18
  29. data/lib/ceedling/config/configurator_builder.rb +58 -28
  30. data/lib/ceedling/config/configurator_paths_validator.rb +179 -0
  31. data/lib/ceedling/config/configurator_plugins.rb +1 -1
  32. data/lib/ceedling/config/configurator_setup.rb +39 -41
  33. data/lib/ceedling/config/configurator_validator.rb +1 -110
  34. data/lib/ceedling/defaults.rb +4 -4
  35. data/lib/ceedling/dependencies/README.md +18 -16
  36. data/lib/ceedling/dependencies/dependency_cache_store.rb +20 -3
  37. data/lib/ceedling/dependencies/dependency_hasher.rb +35 -1
  38. data/lib/ceedling/filename_extension.rb +7 -1
  39. data/lib/ceedling/filesystem/FILE_TREE.md +253 -0
  40. data/lib/ceedling/filesystem/PATH_HANDLING.md +304 -0
  41. data/lib/ceedling/filesystem/README.md +41 -0
  42. data/lib/ceedling/filesystem/build_subpath.rb +102 -0
  43. data/lib/ceedling/filesystem/destination_collision.rb +25 -0
  44. data/lib/ceedling/{file_finder.rb → filesystem/file_finder.rb} +159 -104
  45. data/lib/ceedling/{file_finder_helper.rb → filesystem/file_finder_helper.rb} +36 -31
  46. data/lib/ceedling/filesystem/file_path_collection_utils.rb +183 -0
  47. data/lib/ceedling/{file_path_utils.rb → filesystem/file_path_utils.rb} +108 -97
  48. data/lib/ceedling/{file_system_wrapper.rb → filesystem/file_system_wrapper.rb} +6 -5
  49. data/lib/ceedling/filesystem/file_tree.rb +241 -0
  50. data/lib/ceedling/{file_wrapper.rb → filesystem/file_wrapper.rb} +65 -28
  51. data/lib/ceedling/filesystem/path_exclusions.rb +30 -0
  52. data/lib/ceedling/{path_matcher.rb → filesystem/path_matcher.rb} +27 -23
  53. data/lib/ceedling/{path_mirror.rb → filesystem/path_mirror.rb} +19 -18
  54. data/lib/ceedling/filesystem/path_spellings.rb +55 -0
  55. data/lib/ceedling/filesystem/project_paths.rb +184 -0
  56. data/lib/ceedling/filesystem/working_dir.rb +40 -0
  57. data/lib/ceedling/generators/generator.rb +5 -6
  58. data/lib/ceedling/generators/generator_partials.rb +1 -1
  59. data/lib/ceedling/generators/generator_test_results_backtrace.rb +7 -7
  60. data/lib/ceedling/handoff.rb +121 -0
  61. data/lib/ceedling/includes/include_factory.rb +3 -3
  62. data/lib/ceedling/includes/include_pathinator.rb +67 -10
  63. data/lib/ceedling/includes/includes.rb +1 -1
  64. data/lib/ceedling/installation.rb +92 -0
  65. data/lib/ceedling/library_resolver.rb +99 -0
  66. data/lib/ceedling/objects.yml +23 -2
  67. data/lib/ceedling/partials/partializer.rb +4 -4
  68. data/lib/ceedling/partials/partializer_config.rb +3 -1
  69. data/lib/ceedling/plugins/report_log_writer_plugin.rb +3 -5
  70. data/lib/ceedling/preprocess/preprocessinator_file_assembler.rb +1 -1
  71. data/lib/ceedling/preprocess/preprocessinator_includes_handler.rb +1 -1
  72. data/lib/ceedling/preprocess/preprocessinator_line_marker_includes_extractor.rb +1 -1
  73. data/lib/ceedling/rake_app/rakefile_component_resolver.rb +10 -17
  74. data/lib/ceedling/rake_app/test_task_name.rb +29 -0
  75. data/lib/ceedling/rakefile.rb +16 -1
  76. data/lib/ceedling/rakefiles/base/tasks_base.rake +1 -1
  77. data/lib/ceedling/rakefiles/release/rules_release.rake +4 -7
  78. data/lib/ceedling/rakefiles/tests/rules_tests.rake +3 -20
  79. data/lib/ceedling/rakefiles/tests/rules_tests_generate.rake +4 -30
  80. data/lib/ceedling/release_invoker/release_build_executor.rb +33 -44
  81. data/lib/ceedling/release_invoker/release_build_planner.rb +14 -6
  82. data/lib/ceedling/reportinator.rb +3 -4
  83. data/lib/ceedling/setupinator.rb +95 -87
  84. data/lib/ceedling/test_context_extractor.rb +5 -1
  85. data/lib/ceedling/test_invoker/PIPELINE.md +9 -7
  86. data/lib/ceedling/test_invoker/mock_locator.rb +60 -2
  87. data/lib/ceedling/test_invoker/partials_manager.rb +12 -0
  88. data/lib/ceedling/test_invoker/standin_headerinator.rb +22 -13
  89. data/lib/ceedling/test_invoker/test_build_executor.rb +42 -41
  90. data/lib/ceedling/test_invoker/test_build_planner.rb +37 -18
  91. data/lib/ceedling/test_invoker/test_build_setup.rb +17 -12
  92. data/lib/ceedling/test_invoker/test_build_validations.rb +16 -31
  93. data/lib/ceedling/test_invoker/test_file_preprocessinator.rb +1 -1
  94. data/lib/ceedling/test_invoker/test_invoker.rb +6 -1
  95. data/lib/ceedling/test_invoker/test_pipeline_helpers.rb +1 -1
  96. data/lib/ceedling/test_invoker/test_source_file_directive_resolver.rb +40 -20
  97. data/lib/ceedling/tool_executor.rb +9 -3
  98. data/lib/ceedling/yaml_wrapper.rb +3 -2
  99. data/lib/version.rb +1 -1
  100. data/plugins/bullseye/bullseye.rake +6 -9
  101. data/plugins/bullseye/config/defaults_bullseye.rb +1 -1
  102. data/plugins/bullseye/lib/bullseye.rb +9 -7
  103. data/plugins/cppcheck/config/defaults_cppcheck.rb +1 -1
  104. data/plugins/dependencies/config/defaults.yml +6 -6
  105. data/plugins/dependencies/dependencies.rake +4 -1
  106. data/plugins/dependencies/lib/dependencies.rb +18 -8
  107. data/plugins/dependencies/lib/dependency_spec.rb +17 -5
  108. data/plugins/fff/lib/fff.rb +45 -39
  109. data/plugins/fff/spec/fff_cmock_wrapper_spec.rb +128 -0
  110. data/plugins/gcov/config/defaults_gcov.rb +1 -1
  111. data/plugins/gcov/gcov.rake +6 -9
  112. data/plugins/gcov/lib/console_reportinator.rb +4 -18
  113. data/plugins/gcov/lib/gcov.rb +9 -2
  114. data/plugins/gcov/lib/gcovr_reportinator.rb +8 -40
  115. data/plugins/gcov/lib/gcovr_thresholds.rb +74 -0
  116. data/plugins/gcov/lib/reportgenerator_reportinator.rb +1 -1
  117. data/plugins/module_generator/lib/module_generator.rb +3 -3
  118. data/plugins/report_tests_teamcity_stdout/lib/report_tests_teamcity_stdout.rb +53 -80
  119. data/plugins/sanitize/lib/sanitize_records.rb +3 -6
  120. data/plugins/sanitize/sanitize.rake +6 -6
  121. data/plugins/valgrind/lib/valgrind.rb +14 -7
  122. data/plugins/valgrind/valgrind.rake +6 -6
  123. data/site-local/404.html +6 -20
  124. data/site-local/assets/javascripts/{bundle.d7400e89.min.js → bundle.c21346df.min.js} +3 -3
  125. data/site-local/assets/javascripts/{bundle.d7400e89.min.js.map → bundle.c21346df.min.js.map} +2 -2
  126. data/site-local/assets/javascripts/workers/{search.2c215733.min.js → search.a7633da7.min.js} +2 -2
  127. data/site-local/assets/javascripts/workers/{search.2c215733.min.js.map → search.a7633da7.min.js.map} +1 -1
  128. data/site-local/assets/stylesheets/main.57a0d79d.min.css +6 -0
  129. data/site-local/assets/stylesheets/main.57a0d79d.min.css.map +1 -0
  130. data/site-local/assets/stylesheets/palette.fb2fffe2.min.css +4 -0
  131. data/site-local/assets/stylesheets/palette.fb2fffe2.min.css.map +1 -0
  132. data/site-local/configuration/environment-vars.html +6 -20
  133. data/site-local/configuration/global-collections.html +6 -20
  134. data/site-local/configuration/index.html +6 -20
  135. data/site-local/configuration/loading.html +6 -20
  136. data/site-local/configuration/mixins.html +10 -24
  137. data/site-local/configuration/parallel-builds.html +6 -20
  138. data/site-local/configuration/project-file.html +8 -22
  139. data/site-local/configuration/reference/cexception.html +6 -20
  140. data/site-local/configuration/reference/cmock.html +8 -21
  141. data/site-local/configuration/reference/defines.html +16 -30
  142. data/site-local/configuration/reference/environment.html +10 -24
  143. data/site-local/configuration/reference/extension.html +6 -20
  144. data/site-local/configuration/reference/files.html +22 -30
  145. data/site-local/configuration/reference/flags.html +13 -27
  146. data/site-local/configuration/reference/index.html +6 -20
  147. data/site-local/configuration/reference/libraries.html +27 -23
  148. data/site-local/configuration/reference/mixins.html +6 -20
  149. data/site-local/configuration/reference/partials.html +6 -20
  150. data/site-local/configuration/reference/paths.html +38 -29
  151. data/site-local/configuration/reference/plugins.html +6 -20
  152. data/site-local/configuration/reference/project.html +32 -36
  153. data/site-local/configuration/reference/release-build.html +8 -20
  154. data/site-local/configuration/reference/test-build.html +6 -20
  155. data/site-local/configuration/reference/test-runner.html +6 -20
  156. data/site-local/configuration/reference/tools.html +27 -32
  157. data/site-local/configuration/reference/unity.html +6 -20
  158. data/site-local/configuration/which-ceedling.html +383 -37
  159. data/site-local/development/index.html +6 -20
  160. data/site-local/development/plugins/configuration.html +6 -20
  161. data/site-local/development/plugins/index.html +6 -20
  162. data/site-local/development/plugins/plugin-subclass.html +54 -68
  163. data/site-local/development/plugins/rake-tasks.html +8 -22
  164. data/site-local/development/releases.html +84 -29
  165. data/site-local/development/workflow.html +62 -71
  166. data/site-local/getting-started/builds.html +8 -20
  167. data/site-local/getting-started/command-line.html +62 -24
  168. data/site-local/getting-started/example-projects/cipher-quest.html +6 -20
  169. data/site-local/getting-started/example-projects/index.html +6 -20
  170. data/site-local/getting-started/example-projects/temp-sensor.html +6 -20
  171. data/site-local/getting-started/example-projects/wondrous-forest.html +6 -20
  172. data/site-local/getting-started/index.html +6 -20
  173. data/site-local/getting-started/installation.html +6 -20
  174. data/site-local/getting-started/quick-start.html +6 -20
  175. data/site-local/help.html +6 -20
  176. data/site-local/index.html +11 -24
  177. data/site-local/overview/build-system.html +6 -20
  178. data/site-local/overview/index.html +6 -20
  179. data/site-local/overview/test-environments.html +6 -20
  180. data/site-local/overview/tools-and-frameworks.html +6 -20
  181. data/site-local/plugins/beep.html +6 -20
  182. data/site-local/plugins/bullseye/index.html +13 -24
  183. data/site-local/plugins/bullseye/licensing.html +14 -28
  184. data/site-local/plugins/command-hooks.html +8 -22
  185. data/site-local/plugins/compile-commands-json-db.html +6 -20
  186. data/site-local/plugins/cppcheck.html +8 -22
  187. data/site-local/plugins/dependencies.html +16 -27
  188. data/site-local/plugins/fff.html +49 -32
  189. data/site-local/plugins/gcov/examples.html +7 -21
  190. data/site-local/plugins/gcov/gcovr.html +22 -33
  191. data/site-local/plugins/gcov/index.html +6 -20
  192. data/site-local/plugins/gcov/overview.html +9 -20
  193. data/site-local/plugins/gcov/reportgenerator.html +9 -23
  194. data/site-local/plugins/gcov/reporting.html +6 -20
  195. data/site-local/plugins/gcov/setup.html +8 -21
  196. data/site-local/plugins/gcov/tool-versions.html +6 -20
  197. data/site-local/plugins/gcov/troubleshooting.html +10 -24
  198. data/site-local/plugins/index.html +6 -20
  199. data/site-local/plugins/module-generator.html +21 -35
  200. data/site-local/plugins/report-build-warnings-log.html +53 -67
  201. data/site-local/plugins/report-tests-gtestlike-stdout.html +6 -20
  202. data/site-local/plugins/report-tests-ide-stdout.html +43 -57
  203. data/site-local/plugins/report-tests-log-factory.html +50 -64
  204. data/site-local/plugins/report-tests-pretty-stdout.html +7 -21
  205. data/site-local/plugins/report-tests-raw-output-log.html +9 -21
  206. data/site-local/plugins/report-tests-teamcity-stdout.html +20 -31
  207. data/site-local/plugins/sanitize.html +56 -65
  208. data/site-local/plugins/valgrind.html +49 -58
  209. data/site-local/project/index.html +6 -20
  210. data/site-local/project/release-history.html +6 -20
  211. data/site-local/project/sbom.html +6 -20
  212. data/site-local/project/upgrade.html +9 -20
  213. data/site-local/reference/build-directives.html +6 -20
  214. data/site-local/reference/command-line.html +15 -22
  215. data/site-local/reference/environment-vars.html +6 -20
  216. data/site-local/reference/gcov-plugin.html +6 -20
  217. data/site-local/reference/global-collections.html +6 -20
  218. data/site-local/reference/index.html +6 -20
  219. data/site-local/reference/partials-macros.html +6 -20
  220. data/site-local/reference/project-configuration.html +6 -20
  221. data/site-local/sitemap.xml.gz +0 -0
  222. data/site-local/snapshot/examples/cipher_quest/index.html +16 -30
  223. data/site-local/snapshot/examples/temp_sensor/index.html +8 -22
  224. data/site-local/snapshot/examples/wondrous_forest/index.html +6 -20
  225. data/site-local/snapshot/plugins/bullseye/config/defaults_bullseye.rb +1 -1
  226. data/site-local/snapshot/plugins/gcov/config/defaults_gcov.rb +1 -1
  227. data/site-local/testing-guide/build-directives.html +14 -28
  228. data/site-local/testing-guide/conventions.html +66 -27
  229. data/site-local/testing-guide/frameworks.html +11 -25
  230. data/site-local/testing-guide/index.html +6 -20
  231. data/site-local/testing-guide/partials/configuration.html +8 -22
  232. data/site-local/testing-guide/partials/conventions.html +8 -22
  233. data/site-local/testing-guide/partials/directives.html +16 -30
  234. data/site-local/testing-guide/partials/example.html +14 -28
  235. data/site-local/testing-guide/partials/index.html +6 -20
  236. data/site-local/testing-guide/partials/overview.html +6 -20
  237. data/site-local/testing-guide/partials/variables.html +11 -25
  238. data/site-local/testing-guide/test-cases.html +13 -27
  239. data/site-local/testing-guide/test-sample.html +12 -26
  240. data/site-local/testing-guide/test-suite-anatomy.html +6 -20
  241. data/spec/integration/actionator_file_operations_spec.rb +91 -1
  242. data/spec/integration/compile_commands_json_db_spec.rb +1 -1
  243. data/spec/integration/configurator_pipeline_spec.rb +10 -0
  244. data/spec/integration/configurator_validation_spec.rb +1 -1
  245. data/spec/integration/dependencies/dependency_tracker_cache_hardening_spec.rb +26 -0
  246. data/spec/integration/dependencies/dependency_tracker_core_spec.rb +62 -0
  247. data/spec/integration/launcher_handoff_spec.rb +297 -0
  248. data/spec/integration/mixin_loading_spec.rb +1 -1
  249. data/spec/integration/module_generator_spec.rb +3 -3
  250. data/spec/integration/nested_test_artifacts_spec.rb +99 -0
  251. data/spec/integration/partials_module_resolution_spec.rb +7 -4
  252. data/spec/integration/path_intake_scenarios_spec.rb +101 -0
  253. data/spec/integration/path_scenarios_spec.rb +322 -0
  254. data/spec/integration/quote_include_isolator_spec.rb +1 -1
  255. data/spec/integration/rake_task_registry_plugins_spec.rb +95 -0
  256. data/spec/integration/report_build_warnings_log_spec.rb +1 -1
  257. data/spec/integration/report_tests_log_factory_spec.rb +1 -1
  258. data/spec/integration/test_executable_manifest_spec.rb +1 -1
  259. data/spec/integration/test_includes_extractinator_spec.rb +2 -1
  260. data/spec/integration/test_naming_spec.rb +198 -0
  261. data/spec/integration/test_source_file_checks_spec.rb +166 -0
  262. data/spec/integration/tool_validator_spec.rb +1 -1
  263. data/spec/integration/upgrade_docs_spec.rb +84 -0
  264. data/spec/integration/vendor_copy_transient_io_retry_spec.rb +192 -75
  265. data/spec/support/file_tree_helper.rb +88 -0
  266. data/spec/support/integration/configurator_integration_helper.rb +10 -7
  267. data/spec/support/integration/dependency_tracker_integration_helper.rb +1 -1
  268. data/spec/support/integration/partials_generation_integration_helper.rb +2 -2
  269. data/spec/support/integration/path_scenario_harness.rb +173 -0
  270. data/spec/support/integration/spec_integration_helper.rb +1 -1
  271. data/spec/support/integration/test_includes_harness.rb +13 -2
  272. data/spec/support/spec_helper.rb +2 -0
  273. data/spec/support/system/spec_system_helper.rb +7 -6
  274. data/spec/support/system/system_context.rb +21 -3
  275. data/spec/support/working_dir_tracking.rb +49 -0
  276. data/spec/system/build_output_mirroring_spec.rb +2 -2
  277. data/spec/system/conditional_mock_includes_spec.rb +1 -1
  278. data/spec/system/delta_builds_spec.rb +137 -11
  279. data/spec/system/gcov_deployment_spec.rb +1 -0
  280. data/spec/system/header_include_path_validation_spec.rb +4 -4
  281. data/spec/system/launcher_handoff_spec.rb +82 -0
  282. data/spec/system/mock_include_folders_spec.rb +91 -0
  283. data/spec/system/parent_directory_reference_spec.rb +5 -3
  284. data/spec/system/path_handling_probes_spec.rb +192 -0
  285. data/spec/system/preprocessing_parameterized_tests_spec.rb +1 -1
  286. data/spec/system/rake_release_task_path_disambiguation_spec.rb +6 -6
  287. data/spec/system/rake_test_task_path_disambiguation_spec.rb +85 -0
  288. data/spec/system/special_path_characters_spec.rb +86 -0
  289. data/spec/system/support/common_test_cases.rb +23 -21
  290. data/spec/system/support/gcov_common_test_cases.rb +37 -9
  291. data/spec/system/support/sanitize_common_test_cases.rb +2 -2
  292. data/spec/system/support/valgrind_common_test_cases.rb +12 -12
  293. data/spec/system/test_pipeline_stop_points_spec.rb +4 -4
  294. data/spec/system/test_runner_system_include_spec.rb +1 -1
  295. data/spec/system/test_source_file_directive_spec.rb +34 -5
  296. data/spec/units/bin/actionator_spec.rb +14 -17
  297. data/spec/units/bin/app_cfg_spec.rb +47 -0
  298. data/spec/units/bin/cli_handler_spec.rb +284 -7
  299. data/spec/units/bin/cli_helper_spec.rb +126 -45
  300. data/spec/units/bin/installation_selector_spec.rb +114 -0
  301. data/spec/units/bin/launchinator_spec.rb +171 -0
  302. data/spec/units/bin/path_validator_spec.rb +10 -0
  303. data/spec/units/bin/versionator_spec.rb +38 -6
  304. data/spec/units/build_log_writer_spec.rb +57 -0
  305. data/spec/units/config/build_root_policy_spec.rb +61 -0
  306. data/spec/units/config/configurator_builder_spec.rb +37 -6
  307. data/spec/units/config/configurator_paths_validator_spec.rb +292 -0
  308. data/spec/units/config/configurator_setup_spec.rb +65 -103
  309. data/spec/units/config/configurator_spec.rb +37 -6
  310. data/spec/units/config/configurator_validator_spec.rb +1 -172
  311. data/spec/units/default_tools_quoting_spec.rb +83 -0
  312. data/spec/units/dependencies/dependency_cache_store_spec.rb +33 -2
  313. data/spec/units/dependencies/dependency_debug_tree_spec.rb +1 -1
  314. data/spec/units/dependencies/dependency_hasher_spec.rb +42 -1
  315. data/spec/units/dependencies/dependency_path_normalizer_spec.rb +1 -1
  316. data/spec/units/dependencies/dependency_tracker_spec.rb +3 -1
  317. data/spec/units/filename_extension_spec.rb +11 -0
  318. data/spec/units/filesystem/build_subpath_spec.rb +122 -0
  319. data/spec/units/filesystem/destination_collision_spec.rb +30 -0
  320. data/spec/units/{file_finder_helper_spec.rb → filesystem/file_finder_helper_spec.rb} +46 -1
  321. data/spec/units/{file_finder_spec.rb → filesystem/file_finder_spec.rb} +188 -22
  322. data/spec/units/{file_path_collection_utils_spec.rb → filesystem/file_path_collection_utils_spec.rb} +181 -1
  323. data/spec/units/{file_path_utils_spec.rb → filesystem/file_path_utils_spec.rb} +204 -87
  324. data/spec/units/filesystem/file_system_wrapper_spec.rb +33 -0
  325. data/spec/units/filesystem/file_tree_spec.rb +511 -0
  326. data/spec/units/filesystem/file_tree_windows_spec.rb +78 -0
  327. data/spec/units/{file_wrapper_spec.rb → filesystem/file_wrapper_spec.rb} +154 -32
  328. data/spec/units/{path_matcher_spec.rb → filesystem/path_matcher_spec.rb} +12 -1
  329. data/spec/units/{path_mirror_spec.rb → filesystem/path_mirror_spec.rb} +32 -4
  330. data/spec/units/filesystem/project_paths_spec.rb +147 -0
  331. data/spec/units/filesystem/working_dir_spec.rb +71 -0
  332. data/spec/units/generators/generator_spec.rb +12 -6
  333. data/spec/units/generators/generator_test_results_backtrace_spec.rb +50 -46
  334. data/spec/units/generators/generator_test_results_spec.rb +1 -1
  335. data/spec/units/handoff_spec.rb +205 -0
  336. data/spec/units/includes/include_factory_spec.rb +3 -3
  337. data/spec/units/includes/include_pathinator_spec.rb +46 -0
  338. data/spec/units/installation_spec.rb +228 -0
  339. data/spec/units/library_resolver_spec.rb +157 -0
  340. data/spec/units/mock_locator_spec.rb +76 -1
  341. data/spec/units/partials/partializer_config_spec.rb +7 -0
  342. data/spec/units/partials/partializer_spec.rb +1 -0
  343. data/spec/units/partials_manager_spec.rb +17 -0
  344. data/spec/units/plugins/bullseye_spec.rb +15 -2
  345. data/spec/units/plugins/console_reportinator_spec.rb +18 -20
  346. data/spec/units/plugins/dependencies_spec.rb +33 -7
  347. data/spec/units/plugins/dependency_spec_spec.rb +17 -0
  348. data/spec/units/plugins/gcov_spec.rb +28 -3
  349. data/spec/units/plugins/gcovr_reportinator_spec.rb +19 -47
  350. data/spec/units/plugins/gcovr_thresholds_spec.rb +95 -0
  351. data/spec/units/plugins/module_generator_spec.rb +5 -5
  352. data/spec/units/plugins/report_build_warnings_log_spec.rb +3 -3
  353. data/spec/units/plugins/report_log_writer_plugin_spec.rb +10 -1
  354. data/spec/units/plugins/report_tests_raw_output_log_spec.rb +13 -2
  355. data/spec/units/plugins/report_tests_teamcity_stdout_spec.rb +77 -3
  356. data/spec/units/plugins/reportgenerator_reportinator_spec.rb +1 -1
  357. data/spec/units/plugins/sanitize_records_spec.rb +3 -1
  358. data/spec/units/plugins/sanitize_spec.rb +1 -1
  359. data/spec/units/plugins/valgrind_spec.rb +23 -8
  360. data/spec/units/preprocess/preprocessinator_comment_stripper_spec.rb +1 -1
  361. data/spec/units/rake_app/rakefile_component_resolver_spec.rb +21 -0
  362. data/spec/units/rake_app/test_task_name_spec.rb +47 -0
  363. data/spec/units/release_build_executor_spec.rb +53 -14
  364. data/spec/units/release_build_planner_spec.rb +15 -3
  365. data/spec/units/reportinator_spec.rb +5 -5
  366. data/spec/units/standin_headerinator_spec.rb +31 -1
  367. data/spec/units/test_build_executor_spec.rb +107 -5
  368. data/spec/units/test_build_planner_spec.rb +104 -2
  369. data/spec/units/test_build_setup_spec.rb +96 -12
  370. data/spec/units/test_context_extractor_spec.rb +25 -0
  371. data/spec/units/test_file_preprocessinator_spec.rb +17 -1
  372. data/spec/units/test_includes_extractinator_spec.rb +5 -1
  373. data/spec/units/test_invoker/objects_wiring_spec.rb +6 -3
  374. data/spec/units/test_invoker_spec.rb +14 -1
  375. data/spec/units/test_source_file_directive_resolver_spec.rb +38 -7
  376. data/spec/units/tool_executor_spec.rb +26 -0
  377. data/spec/units/yaml_wrapper_spec.rb +11 -0
  378. metadata +122 -33
  379. data/lib/ceedling/file_path_collection_utils.rb +0 -164
  380. data/site-local/assets/stylesheets/main.ec1eaa64.min.css +0 -1
  381. data/site-local/assets/stylesheets/main.ec1eaa64.min.css.map +0 -1
  382. data/site-local/assets/stylesheets/palette.ab4e12ef.min.css +0 -1
  383. data/site-local/assets/stylesheets/palette.ab4e12ef.min.css.map +0 -1
@@ -0,0 +1,69 @@
1
+ # =========================================================================
2
+ # Ceedling - Test-Centered Build System for C
3
+ # ThrowTheSwitch.org
4
+ # Copyright (c) 2010-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
5
+ # SPDX-License-Identifier: MIT
6
+ # =========================================================================
7
+
8
+ require 'ceedling/constants'
9
+ require 'ceedling/exceptions'
10
+ require 'ceedling/installation'
11
+ require 'ceedling/handoff'
12
+
13
+ # Runs each command in the installation it selects. Another installation's own launcher
14
+ # replaces this process. The launcher's own installation continues here.
15
+ class Launchinator
16
+
17
+ constructor :installation_selector, :loginator
18
+
19
+ # Selects which Ceedling runs a command and points app_cfg's paths at it, without handing off
20
+ def resolve(env:, app_cfg:, config: {}, detect_vendor: true)
21
+ return @installation_selector.select( env:env, config:config, app_cfg:app_cfg, detect_vendor:detect_vendor )
22
+ end
23
+
24
+ # Hands off to another selected installation and never returns. Otherwise returns the
25
+ # rakefile to load in this process. A process a launcher already handed off to says so
26
+ # and never hands off again.
27
+ def launch(env:, app_cfg:, config: {}, detect_vendor: true)
28
+ target = resolve( env:env, app_cfg:app_cfg, config:config, detect_vendor:detect_vendor )
29
+ return proceed( target:target, app_cfg:app_cfg )
30
+ end
31
+
32
+ # As #launch, for a target already selected through #resolve
33
+ def proceed(target:, app_cfg:)
34
+ launcher = Installation.new( app_cfg[:launcher_root_path] )
35
+
36
+ if Handoff.received?( app_cfg[:handoff], own:launcher )
37
+ @loginator.log( Handoff.received_message( app_cfg[:handoff], own:launcher ), Verbosity::COMPLAIN, LogLabels::NOTICE )
38
+ elsif target != launcher
39
+ hand_off( target, launcher, app_cfg[:argv] )
40
+ end
41
+
42
+ return target.rakefile_path
43
+ end
44
+
45
+ private
46
+
47
+ def hand_off(target, launcher, argv)
48
+ validate_runnable( target )
49
+
50
+ @loginator.log( Handoff.handing_off_message( launcher:launcher, target:target ), Verbosity::COMPLAIN, LogLabels::NOTICE )
51
+ Handoff.exec( target:target, launcher:launcher, argv:argv, loginator:@loginator )
52
+ end
53
+
54
+ # An installation that cannot run on its own would fail in a way that hides why
55
+ def validate_runnable(target)
56
+ if !File.exist?( target.bin_path )
57
+ raise CeedlingException.new( "Cannot hand off to #{target.describe()}: it has no launcher at #{target.bin_path}" )
58
+ end
59
+
60
+ return if !target.missing_builtin_mixins?
61
+
62
+ raise CeedlingException.new(
63
+ "#{target.describe()} cannot run on its own: it lacks #{Installation::BUILTIN_MIXINS_DIR}/, which `--local` " +
64
+ "vendoring left out from Ceedling 1.1.0 through 1.2.1. Re-vendor it with `ceedling upgrade <project path>`, " +
65
+ "then run this command again."
66
+ )
67
+ end
68
+
69
+ end
@@ -22,26 +22,14 @@ class MixinResolvinator
22
22
  # - Empty load paths
23
23
  return [], [] if _mixins.nil?
24
24
 
25
- # Build list of load paths
26
25
  # Configured load paths are higher in search path ordering
27
26
  load_paths = _mixins[:load_paths] || []
27
+ enabled = (_mixins[:enabled] || []).clone # A copy of the configuration section
28
28
 
29
- # Get list of mixins
30
- enabled = _mixins[:enabled] || []
31
- enabled = enabled.clone # Ensure it's a copy of configuration section
32
-
33
- # Handle any inline Ruby string expansion, then standardize Windows backslashes --
34
- # cmdline and env var mixin paths already go through standardize_paths elsewhere,
35
- # so config :mixins section paths need the same treatment for consistency.
36
- load_paths.each do |load_path|
37
- load_path.replace( @ruby_expandinator.expand( load_path, source: ":mixins ↳ :load_paths" ) )
38
- load_path.replace( @path_validator.standardize_paths( load_path ).first )
39
- end
40
-
41
- enabled.each do |mixin|
42
- mixin.replace( @ruby_expandinator.expand( mixin, source: ":mixins ↳ :enabled" ) )
43
- mixin.replace( @path_validator.standardize_paths( mixin ).first )
44
- end
29
+ # Command line and environment variable mixin paths are standardized elsewhere, so
30
+ # :mixins section paths are too, after any inline Ruby string expansion
31
+ prepare_in_place( load_paths, ":mixins ↳ :load_paths" )
32
+ prepare_in_place( enabled, ":mixins ↳ :enabled" )
45
33
 
46
34
  # Remove the :mixins section of the configuration
47
35
  config.delete( :mixins )
@@ -66,25 +54,7 @@ class MixinResolvinator
66
54
 
67
55
  # Validate mixins list
68
56
  def validate_mixins(mixins:, load_paths:, source:, yaml_extensions:)
69
- validated = true
70
-
71
- mixins.each do |mixin|
72
- # Validate mixin filepaths
73
- if @path_validator.filepath?( mixin )
74
- if !@file_wrapper.exist?( mixin )
75
- @loginator.log( "Cannot find mixin at #{mixin}", Verbosity::ERRORS )
76
- validated = false
77
- end
78
-
79
- # Otherwise, validate that mixin name can be found in load paths
80
- elsif mixin_filepath( mixin, load_paths, yaml_extensions ).nil?
81
- filenames = yaml_extensions.map { |extension| "'#{mixin}#{extension}'" }.join( ' or ' )
82
- @loginator.log( "#{source} '#{mixin}' cannot be found in mixin load paths as #{filenames}", Verbosity::ERRORS )
83
- validated = false
84
- end
85
- end
86
-
87
- return validated
57
+ return mixins.map { |mixin| mixin_found?( mixin, load_paths, source, yaml_extensions ) }.all?
88
58
  end
89
59
 
90
60
 
@@ -114,6 +84,26 @@ class MixinResolvinator
114
84
 
115
85
  private
116
86
 
87
+ # Expands and standardizes each of `paths`, keeping each String the configuration holds
88
+ def prepare_in_place(paths, source)
89
+ paths.each { |path| path.replace( @path_validator.standardize_paths( @ruby_expandinator.expand( path, source: source ) ).first ) }
90
+ end
91
+
92
+ # A mixin filepath must exist, and a mixin name must be found in the load paths
93
+ def mixin_found?(mixin, load_paths, source, yaml_extensions)
94
+ if @path_validator.filepath?( mixin )
95
+ return true if @file_wrapper.exist?( mixin )
96
+
97
+ @loginator.log( "Cannot find mixin at #{mixin}", Verbosity::ERRORS )
98
+ return false
99
+ end
100
+ return true unless mixin_filepath( mixin, load_paths, yaml_extensions ).nil?
101
+
102
+ filenames = yaml_extensions.map { |extension| "'#{mixin}#{extension}'" }.join( ' or ' )
103
+ @loginator.log( "#{source} '#{mixin}' cannot be found in mixin load paths as #{filenames}", Verbosity::ERRORS )
104
+ return false
105
+ end
106
+
117
107
  # The first existing file named for the mixin, searching each load path in turn for each
118
108
  # extension
119
109
  def mixin_filepath(mixin, load_paths, yaml_extensions)
data/bin/objects.yml CHANGED
@@ -55,6 +55,19 @@ cli_handler:
55
55
  - path_validator
56
56
  - rake_task_registry
57
57
  - actionator
58
+ - launchinator
59
+ - loginator
60
+
61
+ launchinator:
62
+ compose:
63
+ - installation_selector
64
+ - loginator
65
+
66
+ installation_selector:
67
+ compose:
68
+ - file_wrapper
69
+ - config_walkinator
70
+ - path_validator
58
71
  - loginator
59
72
 
60
73
  cli_helper:
@@ -5,44 +5,27 @@
5
5
  # SPDX-License-Identifier: MIT
6
6
  # =========================================================================
7
7
 
8
+ require 'ceedling/filesystem/project_paths'
9
+
8
10
  class PathValidator
9
11
 
10
12
  constructor :file_wrapper, :loginator
11
13
 
14
+ # Logs why each of `paths` fails as a `type` (:filepath or :directory), and whether none did
12
15
  def validate(paths:, source:, type: :filepath)
13
- validated = true
14
-
15
- paths.each do |path|
16
- # Error out on empty paths
17
- if path.empty?
18
- validated = false
19
- @loginator.log( "#{source} contains an empty path", Verbosity::ERRORS )
20
- next
21
- end
22
-
23
- # Error out if path is not a directory / does not exist
24
- if (type == :directory) and !@file_wrapper.directory?( path )
25
- validated = false
26
- @loginator.log( "#{source} '#{path}' does not exist as a directory in the filesystem", Verbosity::ERRORS )
27
- end
28
-
29
- # Error out if filepath does not exist
30
- if (type == :filepath) and !@file_wrapper.exist?( path )
31
- validated = false
32
- @loginator.log( "#{source} '#{path}' does not exist in the filesystem", Verbosity::ERRORS )
33
- end
34
- end
16
+ problems = paths.filter_map { |path| path_problem( path, type ) }
17
+ problems.each { |problem| @loginator.log( "#{source} #{problem}", Verbosity::ERRORS ) }
35
18
 
36
- return validated
19
+ return problems.empty?
37
20
  end
38
21
 
39
- # Ensure any Windows backslashes are converted to Ruby path forward slashes.
40
- # Returns new values in the same order as the arguments given, rather than
41
- # mutating the caller's own String objects in place.
22
+ # Each path spelled as configuration spells it (ProjectPaths.standardize): forward slashes,
23
+ # `~` as the home directory, no trailing separator. Returns new values in the same order as
24
+ # the arguments given, rather than mutating the caller's own String objects in place.
42
25
  def standardize_paths( *paths )
43
26
  paths.map do |path|
44
- next path if path.nil? or path.empty?
45
- path.tr( "\\", '/' )
27
+ next path if path.nil? or path.strip.empty?
28
+ ProjectPaths.standardize( path )
46
29
  end
47
30
  end
48
31
 
@@ -52,4 +35,17 @@ class PathValidator
52
35
  return (!File.extname( str ).empty?) || (str.include?( File::SEPARATOR ))
53
36
  end
54
37
 
55
- end
38
+ ### Private ###
39
+
40
+ private
41
+
42
+ # Why `path` fails as a `type`, or nil
43
+ def path_problem(path, type)
44
+ return 'contains an empty path' if path.empty?
45
+ return "'#{path}' does not exist as a directory in the filesystem" if (type == :directory) and !@file_wrapper.directory?( path )
46
+ return "'#{path}' does not exist in the filesystem" if (type == :filepath) and !@file_wrapper.exist?( path )
47
+
48
+ return nil
49
+ end
50
+
51
+ end
data/bin/versionator.rb CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  require 'exceptions'
9
9
  require 'constants' # Filename constants
10
- require 'version' # Import Ceedling constant symbols from lib/version.rb
10
+ require 'ceedling/installation'
11
11
 
12
12
  ## Definitions
13
13
  ## TAG: <#.#.#> version string used to package the software bundle
@@ -15,66 +15,65 @@ require 'version' # Import Ceedling constant symbols from lib/version.rb
15
15
 
16
16
  class Versionator
17
17
 
18
+ # Vendored framework headers and the prefix of their version macros
19
+ FRAMEWORK_HEADERS = {
20
+ 'UNITY' => File.join( 'unity', 'src', 'unity.h' ),
21
+ 'CMOCK' => File.join( 'cmock', 'src', 'cmock.h' ),
22
+ 'CEXCEPTION' => File.join( 'c_exception', 'lib', 'CException.h' )
23
+ }.freeze
24
+
18
25
  attr_reader :ceedling_tag, :ceedling_build, :ceedling_install_path
19
26
  attr_reader :unity_tag, :cmock_tag, :cexception_tag
20
27
 
21
28
  def initialize(ceedling_root_path, ceedling_vendor_path=nil)
22
-
23
- ##
24
- ## Ceedling version info
25
- ##
26
-
27
29
  @ceedling_install_path = ceedling_root_path.clone()
30
+ @ceedling_tag = read_tag( ceedling_root_path )
31
+ @ceedling_build = read_build( ceedling_root_path )
28
32
 
29
- # Set Ceedling tag
30
- @ceedling_tag = Ceedling::Version::TAG
33
+ # Framework versions are gathered only when asked for
34
+ read_framework_tags( ceedling_vendor_path ) unless ceedling_vendor_path.nil?
35
+ end
31
36
 
32
- # Create Ceedling build string
33
- # Lookup the Ceedling Git commit SHA if it exists as simple text file in the root of the codebase
34
- ceedling_commit_sha_filepath = File.join( ceedling_root_path, GIT_COMMIT_SHA_FILENAME )
35
- @ceedling_build =
36
- if File.exist?( ceedling_commit_sha_filepath )
37
- # Ingest text from commit SHA file and clean it up
38
- sha = File.read( ceedling_commit_sha_filepath ).strip()
39
- # <TAG>-<SHA>
40
- "#{@ceedling_tag}-#{sha}"
41
- else
42
- # <TAG>
43
- @ceedling_tag
44
- end
37
+ private
45
38
 
46
- ##
47
- ## Build frameworks version info
48
- ##
39
+ # The tag comes from the installation's own lib/version.rb, never from a loaded constant
40
+ def read_tag(root_path)
41
+ installation = Installation.new( root_path )
42
+ tag = installation.version
43
+ return tag unless tag.nil?
49
44
 
50
- # Do no framework version gathering if it's not asked for
51
- return if ceedling_vendor_path.nil?
45
+ raise CeedlingException.new( "Could not read a Ceedling version from #{File.join( installation.root, Installation::VERSION_FILE )}" )
46
+ end
52
47
 
53
- # Create _tag accessors in the Versionator object
48
+ # <TAG>-<SHA> when the installation carries a commit SHA file, otherwise <TAG>
49
+ def read_build(root_path)
50
+ sha_filepath = File.join( root_path, GIT_COMMIT_SHA_FILENAME )
51
+ return @ceedling_tag unless File.exist?( sha_filepath )
54
52
 
55
- # Anonymous hash to iterate through complementary vendor projects
56
- { 'UNITY' => File.join( 'unity', 'src', 'unity.h' ),
57
- 'CMOCK' => File.join( 'cmock', 'src', 'cmock.h' ),
58
- 'CEXCEPTION' => File.join( 'c_exception', 'lib', 'CException.h' )
59
- }.each_pair do |name, path|
60
- filename = File.join( ceedling_vendor_path, path )
53
+ return "#{@ceedling_tag}-#{File.read( sha_filepath ).strip()}"
54
+ end
61
55
 
62
- # Actually look up the vendor project version number components
63
- version = [0,0,0]
56
+ # Sets @unity_tag, @cmock_tag and @cexception_tag from each header's version macros
57
+ def read_framework_tags(vendor_path)
58
+ FRAMEWORK_HEADERS.each_pair do |name, path|
59
+ filepath = File.join( vendor_path, path )
60
+ instance_variable_set( "@#{name.downcase}_tag", read_framework_tag( name, filepath ) )
61
+ end
62
+ end
64
63
 
65
- begin
66
- File.readlines( filename ).each do |line|
67
- ['VERSION_MAJOR', 'VERSION_MINOR', 'VERSION_BUILD'].each_with_index do |field, i|
68
- m = line.match(/#{name}_#{field}\s+(\d+)/)
69
- version[i] = m[1] unless (m.nil?)
70
- end
71
- end
72
- rescue
73
- raise CeedlingException.new( "Could not collect version information for vendor component ⏩️ #{filename}" )
74
- end
64
+ def read_framework_tag(name, filepath)
65
+ lines = File.readlines( filepath )
66
+ rescue StandardError
67
+ raise CeedlingException.new( "Could not collect version information for vendor component ⏩️ #{filepath}" )
68
+ else
69
+ return framework_version( name, lines )
70
+ end
75
71
 
76
- # Set the version tag accessor directly instead of building and evaling a string
77
- instance_variable_set("@#{name.downcase}_tag", version.join('.'))
78
- end
72
+ # MAJOR.MINOR.BUILD from the header's last definition of each macro, 0 for any missing
73
+ def framework_version(name, lines)
74
+ return ['VERSION_MAJOR', 'VERSION_MINOR', 'VERSION_BUILD'].map do |field|
75
+ matches = lines.filter_map { |line| line.match( /#{name}_#{field}\s+(\d+)/ ) }
76
+ matches.empty? ? '0' : matches.last[1]
77
+ end.join( '.' )
79
78
  end
80
79
  end
data/ceedling.gemspec CHANGED
@@ -80,27 +80,31 @@ Ceedling projects start with a YAML configuration file. A variety of conventions
80
80
  s.files += Dir['vendor/unity/auto/**/*.rb']
81
81
  s.files += Dir['vendor/unity/src/**/*.[ch]']
82
82
 
83
- s.files += Dir['**/*']
84
- # Dir['**/*'] above sweeps the working tree, so anything a local run leaves behind
85
- # would otherwise be packaged into a release.
83
+ # The working tree, less the top-level directories never packaged. The walk never
84
+ # descends into them: Bundler evaluates this file on every `bundle exec`, and a
85
+ # retained system test project below specout/ can nest past Windows' path limit,
86
+ # which makes the glob itself raise. A retained project also nests a vendored Ceedling
87
+ # deep enough to exceed the tar name limit (Gem::Package::TooLongFileName).
86
88
  #
87
- # System test artifacts are the worst of it. `rake spec:system:debug:*` retains whole
88
- # deployed projects under specout/, which both bloats the gem and breaks packaging
89
- # outright, since a retained project nests a vendored Ceedling deep enough to exceed
90
- # the tar name limit (Gem::Package::TooLongFileName).
89
+ # build Local build output
90
+ # site-web Hosted/versioned docs site -- not needed offline
91
+ # specout Retained system test artifacts and run logs
92
+ # tools Dev tooling the Rakefile above shells out to
93
+ unpackaged = %w[build site-web specout tools]
94
+ s.files += Dir['*'].reject { |entry| unpackaged.include?( entry ) }.flat_map { |entry| [entry, *Dir["#{entry}/**/*"]] }
95
+
96
+ # The walk above still sweeps the rest of the working tree, so anything a local run
97
+ # leaves behind there would otherwise be packaged into a release.
91
98
  #
92
- # Build output matters for a second reason. Running the examples or the plugin example
93
- # projects locally fills their build/ directories with object files and executables,
94
- # and shipping compiled binaries in a release gem is exactly what trips the security
99
+ # Build output matters most. Running the examples or the plugin example projects
100
+ # locally fills their build/ directories with object files and executables, and
101
+ # shipping compiled binaries in a release gem is exactly what trips the security
95
102
  # scanners described in docs/SECURITY.md. `build` is matched as a whole path segment
96
103
  # on purpose: each vendored submodule ships a `meson.build` file, and a substring test
97
104
  # would silently drop all three.
98
105
  s.files.reject! do |f|
99
- f.start_with?('site-web/') || # Hosted/versioned docs site -- not needed offline
100
- f == 'tools' || f.start_with?('tools/') || # Dev tooling the Rakefile above shells out to
101
106
  f == 'docs/mkdocs' || f.start_with?('docs/mkdocs/') || # Raw docs source -- site-local/ is the built artifact the gem actually serves
102
- f == 'specout' || f.start_with?('specout/') || # Retained system test artifacts and run logs
103
- f == 'build' || f.start_with?('build/') || f.include?('/build/') || # Local build output
107
+ f.include?('/build/') || # Local build output
104
108
  f.match?(/\.(cdx|spdx)\.json\z/) || # Generated SBOMs -- release assets, not gem contents
105
109
  # Upstream fff's own test apparatus. Ceedling needs fff.h from this tree and
106
110
  # nothing else, and these three directories are 1.2 MB that no Ceedling code path
@@ -118,7 +122,7 @@ Ceedling projects start with a YAML configuration file. A variety of conventions
118
122
  f == 'plugins/fff/vendor/fff/buildandtest'
119
123
  end
120
124
 
121
- # Dir['**/*'] cannot see dotfiles, and a few are required for the spec suites that
125
+ # The walk above cannot see dotfiles, and a few are required for the spec suites that
122
126
  # ship with this gem to run at all. Those suites exist to support certification
123
127
  # self-testing, driven by separate tooling against the versioned gem, which is also
124
128
  # why spec/, Gemfile, and Gemfile.lock are packaged rather than trimmed out.
@@ -6,9 +6,78 @@ These breaking changes are complemented by three other documents:
6
6
  1. 🪵 **[Changelog](Changelog.md)** for a structured list of additions, fixes, changes, and removals.
7
7
  1. 🐛 **[Known Issues](KnownIssues.md)** for a list of presently known problems and limitations.
8
8
 
9
+ A release has a section only if it breaks something. Each section lists what changed in that release alone, so upgrading across several releases means reading each section between them.
10
+
11
+ ---
12
+
13
+ # [1.2.2] — 2026-10-31
14
+
15
+ ## Test build output is organized by each test’s path from the project root
16
+
17
+ A test’s build output, results, and logs are organized by its name, and a test is now named by its path from the project root without its extension. Before 1.2.2, the name was its path below its test root, so two tests could mistakenly share one. `test/unit/test_calc.c` was named `unit/test_calc` and is now `test/unit/test_calc`. A test directly in its root gains a directory: `test/test_calc.c` logs to `build/artifacts/valgrind/test/test_calc.log`, not `build/artifacts/valgrind/test_calc.log`.
18
+
19
+ Update anything that reads per-test output by path:
20
+
21
+ 1. Scripts that collect Valgrind, sanitizer, raw output, or gdb backtrace logs. A glob such as `build/artifacts/valgrind/*.log` no longer reaches them; use `build/artifacts/valgrind/**/*.log`.
22
+ 1. Tools that read results, runners, or objects from `build/test/` directly.
23
+ 1. TeamCity suite names, which now carry the same path (e.g. `test/TestUsartModel`).
24
+
25
+ The first build after upgrading rebuilds everything once. Run `ceedling clobber` to remove the output left in the old layout. Until then, any coverage reports also read the old coverage data.
26
+
27
+ ## Build files are placed by each source’s path from the project root
28
+
29
+ An object, preprocessed file, or dependencies file now sits below its build directory at its source’s path from the project root. Before 1.2.2, it sat at the source’s path below its `:paths` root, or flat. In a test, `src/drivers/uart.c` builds to `build/test/out/<test name>/src/drivers/uart.o`, not `build/test/out/<test name>/drivers/uart.o`. A release builds it to `build/release/out/src/drivers/uart.o`. Each `..` in a path outside the project becomes `_up_`, and a file of the running Ceedling installation outside the project sits below `_ceedling_`. Mocks, runners, and vendored framework objects keep their places.
30
+
31
+ The first build after upgrading recompiles each moved object once. Run `ceedling clobber` to remove objects left in the old layout. Until then, coverage reports also include the old coverage data.
32
+
33
+ ## A `-:` `:paths` entry removes the directories below it
34
+
35
+ A `-:` entry in `:paths` used to remove only the directory it named. It now also removes every directory below that directory. An additive entry naming one of those directories more closely keeps it, as `+:src/legacy/keep` does beside `-:src/legacy`. A project that relied on subdirectories surviving a `-:` entry must name them in entries of their own.
36
+
37
+ ## A build root holding the project is refused
38
+
39
+ `:project` ↳ `:build_root` can no longer be empty, the project directory, or a directory above it. `clobber` empties the build root’s test and release trees, so with `:build_root: .` it deleted the project’s own `test/` directory. Configuration now stops with an error naming the problem.
40
+
41
+ A `:paths` or `:files` entry within the build root, such as one naming generated code in `build/gen`, still collects from it, with a warning. No entry collects from the directories Ceedling and its plugins create, such as `test/`, `release/`, `vendor/`, and `artifacts/` below the build root, or the mocks directory. A project that named one of them in `:paths` or `:files` loses those files from its collections.
42
+
43
+ ## `-L` arguments name the directories `:paths` ↳ `:libraries` collects
44
+
45
+ Linker `-L` arguments used to repeat `:paths` ↳ `:libraries` entries exactly as written. They now name the directories those entries collect, as any `:paths` entry does. A glob names each directory it matches, a `-:` entry removes directories, and an entry that collects no existing directory adds no argument.
46
+
47
+ ## `TEST_SOURCE_FILE()` entries are checked without test preprocessing
48
+
49
+ With `:project` ↳ `:use_test_preprocessor` set to `:none` or `:mocks`, a `TEST_SOURCE_FILE()` entry naming a file that doesn’t exist, or that isn’t a source file, was previously silently dropped. A build now stops with an error naming the entry and its test file, as it already did with test preprocessing.
50
+
51
+ Without test preprocessing, Ceedling reads these entries as text and does not evaluate `#if`. An entry inside an `#if` branch that is off is checked too, so it must name a real file.
52
+
53
+ ## A project that selects another installation runs entirely in it
54
+
55
+ A project can select another Ceedling installation through `:project` ↳ `:which_ceedling`, the `WHICH_CEEDLING` environment variable, or a `vendor/ceedling/` copy. Before 1.2.2, the `ceedling` command you ran parsed the command line and loaded that installation’s application into its own process. Now that installation’s own launcher runs the command, in a new process.
56
+
57
+ 1. The selected installation parses the command line itself. An older one rejects commands and options added after its release.
58
+ 1. `new`, `example`, `examples`, `docs`, and `help` run in the installation `WHICH_CEEDLING` or a `vendor/ceedling/` copy selects, not in the `ceedling` command you ran. A `--local` copy carries no documentation bundle, so `docs` exports the documentation of the `ceedling` command you ran instead, with a notice.
59
+ 1. Both sides of a hand-off log a notice at warning verbosity. It names both installations and their versions.
60
+ 1. A project vendored by Ceedling 1.1.0 through 1.2.1 lacks Unity’s built-in mixins, so its copy cannot run on its own. The `ceedling` command you run stops with advice to re-vendor it with `ceedling upgrade`.
61
+
62
+ ## `upgrade` no longer finds its source in `vendor/ceedling/`
63
+
64
+ `ceedling upgrade PATH` copies the Ceedling you run or the installation `WHICH_CEEDLING` names into the project at `PATH`. It no longer selects a `vendor/ceedling/` directory it finds in the working directory, which inside a `--local` project was the very copy it was replacing.
65
+
66
+ ## `version` reads your project file
67
+
68
+ `ceedling version` reads your project file when one is available, as `build` does, and reports the installation the project selects. For a project that selects another installation, it lists `Ceedling Launcher =>` and `Ceedling App =>` instead of a single `Ceedling =>` line. A tool that parses `version` for the project’s Ceedling should read `Ceedling App =>` when present.
69
+
70
+ ## Impacts on third-party plugins by file and path code moved to `lib/ceedling/filesystem/`
71
+
72
+ Ceedling plugin development currently makes no guarantees about the location and interface of internal Ceedling resources. And, it is unlikely that custom plugins would rely on the reorganized filesystem handling code to begin with.
73
+
74
+ Ceedling’s file and path code now sits in `lib/ceedling/filesystem/`. A plugin that requires one of these files directly must name its new path, such as `require 'ceedling/filesystem/file_path_utils'` in place of `require 'ceedling/file_path_utils'`. A require of an old path fails with a `LoadError`. Where an older Ceedling gem is installed, Ruby can instead load that gem’s copy of the file, and the build fails with an unrelated error such as `wrong number of arguments`. Plugins that reach these objects through `@ceedling[:file_wrapper]` and the like need no change. A plugin that names the new paths no longer loads in Ceedling 1.2.1 or earlier.
75
+
76
+ The moved files are `project_paths`, `build_subpath`, `path_spellings`, `path_exclusions`, `path_mirror`, `path_matcher`, `destination_collision`, `file_path_utils`, `file_path_collection_utils`, `file_finder`, `file_finder_helper`, `file_wrapper`, and `file_system_wrapper`.
77
+
9
78
  ---
10
79
 
11
- # [1.2.0] — Prerelease
80
+ # [1.2.0] — 2026-10-21
12
81
 
13
82
  ## Mocks included through a folder are named by that folder
14
83