ceedling 1.1.10 → 1.2.0

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 (1131) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +3 -0
  3. data/.simplecov +73 -0
  4. data/GIT_COMMIT_SHA +1 -1
  5. data/Gemfile +84 -8
  6. data/Gemfile.lock +38 -8
  7. data/README.md +51 -29
  8. data/Rakefile +768 -16
  9. data/assets/{project.yml → features/project.yml} +4 -1
  10. data/assets/fixtures/bullseye_branch_coverage/src/branchy.c +24 -0
  11. data/assets/fixtures/bullseye_branch_coverage/src/branchy.h +14 -0
  12. data/assets/fixtures/bullseye_branch_coverage/test/test_branchy.c +18 -0
  13. data/assets/fixtures/cppcheck_findings/findings.c +23 -0
  14. data/assets/fixtures/cppcheck_findings/findings.h +13 -0
  15. data/assets/fixtures/header_include_path_validation/alt_drivers/foo.h +6 -0
  16. data/assets/fixtures/header_include_path_validation/bar.h +6 -0
  17. data/assets/fixtures/header_include_path_validation/drivers/foo.h +6 -0
  18. data/assets/fixtures/header_include_path_validation/dup.h +6 -0
  19. data/assets/fixtures/header_include_path_validation/other_inc/dup.h +6 -0
  20. data/assets/fixtures/header_include_path_validation/test_ambiguous_mock.c +15 -0
  21. data/assets/fixtures/header_include_path_validation/test_bare_mock.c +11 -0
  22. data/assets/fixtures/header_include_path_validation/test_bogus_mock_path.c +11 -0
  23. data/assets/fixtures/header_include_path_validation/test_bogus_vanilla_path.c +10 -0
  24. data/assets/fixtures/header_include_path_validation/test_include_outranks_test_include_path.c +16 -0
  25. data/assets/fixtures/header_include_path_validation/test_pathed_mock.c +11 -0
  26. data/assets/fixtures/header_include_path_validation/test_pathed_mock_ambiguous.c +14 -0
  27. data/assets/fixtures/header_include_path_validation/test_test_include_path_outranks_include.c +17 -0
  28. data/assets/fixtures/implicit_source_header_correspondence/alpha/dup.c +6 -0
  29. data/assets/fixtures/implicit_source_header_correspondence/alpha/dup.h +6 -0
  30. data/assets/fixtures/implicit_source_header_correspondence/beta/dup.c +6 -0
  31. data/assets/fixtures/implicit_source_header_correspondence/beta/dup.h +6 -0
  32. data/assets/fixtures/implicit_source_header_correspondence/gamma/dup_gamma.c +6 -0
  33. data/assets/fixtures/implicit_source_header_correspondence/test_dup_alpha.c +10 -0
  34. data/assets/fixtures/implicit_source_header_correspondence/test_dup_bare.c +10 -0
  35. data/assets/fixtures/implicit_source_header_correspondence/test_dup_beta.c +10 -0
  36. data/assets/fixtures/implicit_source_header_correspondence/test_dup_override.c +19 -0
  37. data/assets/fixtures/implicit_source_header_correspondence/test_dup_subtractive.c +19 -0
  38. data/assets/fixtures/implicit_source_header_correspondence/test_dup_subtractive_noop.c +16 -0
  39. data/assets/fixtures/parent_directory_references/alpha/extra.c +4 -0
  40. data/assets/fixtures/parent_directory_references/common/helper.c +6 -0
  41. data/assets/fixtures/parent_directory_references/common/helper.h +6 -0
  42. data/assets/fixtures/parent_directory_references/unit/test_dotdot_include.c +10 -0
  43. data/assets/fixtures/parent_directory_references/unit/test_dotdot_source.c +16 -0
  44. data/assets/fixtures/plain_inline_module.h +9 -0
  45. data/assets/fixtures/same_named_modules/include/drivers/spi/config.h +6 -0
  46. data/assets/fixtures/same_named_modules/include/drivers/uart/config.h +6 -0
  47. data/assets/fixtures/same_named_modules/src/drivers/spi/config.c +8 -0
  48. data/assets/fixtures/same_named_modules/src/drivers/uart/config.c +10 -0
  49. data/assets/fixtures/same_named_modules/test/test_both_configs.c +26 -0
  50. data/assets/fixtures/same_named_modules/test/test_both_configs_mocked.c +20 -0
  51. data/assets/fixtures/same_named_modules/test/test_both_configs_mocked_traditional.c +19 -0
  52. data/assets/fixtures/same_named_modules/test/test_both_modules.c +19 -0
  53. data/assets/fixtures/same_named_modules/test/test_uart_config_bare.c +19 -0
  54. data/assets/fixtures/same_named_modules/test/test_uart_config_partial_only.c +20 -0
  55. data/assets/fixtures/sources_with_duplicate_basenames/baz/bar.c +6 -0
  56. data/assets/fixtures/sources_with_duplicate_basenames/baz/bar.h +6 -0
  57. data/assets/fixtures/sources_with_duplicate_basenames/foo/bar.c +6 -0
  58. data/assets/fixtures/sources_with_duplicate_basenames/foo/bar.h +6 -0
  59. data/assets/fixtures/sources_with_duplicate_basenames/main.c +11 -0
  60. data/assets/fixtures/sources_with_duplicate_basenames/test_baz_bar.c +10 -0
  61. data/assets/fixtures/sources_with_duplicate_basenames/test_both_bars.c +12 -0
  62. data/assets/fixtures/sources_with_duplicate_basenames/test_foo_bar.c +10 -0
  63. data/assets/{test_example_file_boom.c → fixtures/test_nosanitize_boom.c} +9 -0
  64. data/assets/{test_example_file_crash_assert.c → fixtures/test_nosanitize_crash_assert.c} +8 -0
  65. data/assets/{test_example_file_crash_sigsegv.c → fixtures/test_nosanitize_crash_sigsegv.c} +8 -0
  66. data/assets/{test_example_file_crash_sigsegv_with_param.c → fixtures/test_nosanitize_crash_sigsegv_with_param.c} +8 -0
  67. data/assets/fixtures/test_nosanitize_heap_buffer_overflow.c +31 -0
  68. data/assets/fixtures/test_nosanitize_leak.c +34 -0
  69. data/assets/fixtures/test_nosanitize_two_findings.c +36 -0
  70. data/assets/{test_example_file_ub_shift_overflow.c → fixtures/test_nosanitize_ub_shift_overflow.c} +9 -0
  71. data/assets/fixtures/test_plain_inline_module.c +15 -0
  72. data/assets/fixtures/test_source_file_duplicate_basenames/alpha/calc.c +4 -0
  73. data/assets/fixtures/test_source_file_duplicate_basenames/beta/calc.c +4 -0
  74. data/assets/fixtures/test_source_file_duplicate_basenames/test_calc_alpha.c +15 -0
  75. data/assets/fixtures/test_source_file_duplicate_basenames/test_calc_ambiguous.c +15 -0
  76. data/assets/fixtures/test_source_file_duplicate_basenames/test_calc_beta.c +15 -0
  77. data/assets/fixtures/tests_with_conditional_includes/src/feature_extra2.h +13 -0
  78. data/assets/fixtures/tests_with_conditional_includes/src/macro_target_extra.h +13 -0
  79. data/assets/{tests_with_conditional_includes → fixtures/tests_with_conditional_includes}/src/widget.c +19 -3
  80. data/assets/{tests_with_conditional_includes → fixtures/tests_with_conditional_includes}/src/widget.h +1 -0
  81. data/assets/{tests_with_conditional_includes → fixtures/tests_with_conditional_includes}/src/widget_feature.c +17 -1
  82. data/assets/{tests_with_conditional_includes → fixtures/tests_with_conditional_includes}/test/test_widget.c +12 -4
  83. data/assets/{tests_with_conditional_includes → fixtures/tests_with_conditional_includes}/test/test_widget_feature.c +8 -5
  84. data/assets/fixtures/tests_with_conditional_mocks/src/Case_01.c +7 -0
  85. data/assets/fixtures/tests_with_conditional_mocks/src/Case_01.h +6 -0
  86. data/assets/fixtures/tests_with_conditional_mocks/src/Case_02.c +16 -0
  87. data/assets/fixtures/tests_with_conditional_mocks/src/Case_02.h +6 -0
  88. data/assets/fixtures/tests_with_conditional_mocks/src/FeatureConfig.h +6 -0
  89. data/assets/fixtures/tests_with_conditional_mocks/src/Gpt.h +6 -0
  90. data/assets/fixtures/tests_with_conditional_mocks/src/MyModuleConfig.h +17 -0
  91. data/assets/fixtures/tests_with_conditional_mocks/src/MyModulePart1.h +6 -0
  92. data/assets/fixtures/tests_with_conditional_mocks/src/MyModulePart2.h +6 -0
  93. data/assets/fixtures/tests_with_conditional_mocks/src/drivers/widget.h +6 -0
  94. data/assets/fixtures/tests_with_conditional_mocks/src/reader.c +7 -0
  95. data/assets/fixtures/tests_with_conditional_mocks/src/reader.h +6 -0
  96. data/assets/fixtures/tests_with_conditional_mocks/test/test_Case_01.c +21 -0
  97. data/assets/fixtures/tests_with_conditional_mocks/test/test_Case_01_legacy.c +16 -0
  98. data/assets/fixtures/tests_with_conditional_mocks/test/test_Case_02.c +31 -0
  99. data/assets/fixtures/tests_with_conditional_mocks/test/test_FeatureConfig.c +15 -0
  100. data/assets/fixtures/tests_with_conditional_mocks/test/test_reader.c +13 -0
  101. data/assets/fixtures/tests_with_duplicate_test_names/integration/test_foo.c +21 -0
  102. data/assets/fixtures/tests_with_duplicate_test_names/unit/test_foo.c +21 -0
  103. data/assets/fixtures/tests_with_fallback_conditionals/src/conditional_module.c +28 -0
  104. data/assets/{tests_with_fallback_conditionals → fixtures/tests_with_fallback_conditionals}/test/test_conditionals.c +8 -1
  105. data/assets/fixtures/tests_with_multiple_assembly_extensions/src/asm_helper_lower.s +2 -0
  106. data/assets/fixtures/tests_with_multiple_assembly_extensions/src/asm_helper_upper.S +13 -0
  107. data/assets/fixtures/tests_with_multiple_assembly_extensions/src/counter_module.c +13 -0
  108. data/assets/fixtures/tests_with_multiple_assembly_extensions/src/counter_module.h +13 -0
  109. data/assets/fixtures/tests_with_multiple_assembly_extensions/test/test_counter_module.c +27 -0
  110. data/assets/fixtures/tests_with_subdir_includes/src/module/app/config.h +13 -0
  111. data/assets/fixtures/tests_with_subdir_includes/src/module/drivers/config.h +13 -0
  112. data/assets/fixtures/tests_with_subdir_includes/src/module/sensor.c +30 -0
  113. data/assets/fixtures/tests_with_subdir_includes/src/module/sensor.h +13 -0
  114. data/assets/fixtures/tests_with_subdir_includes/src/shared/config.h +13 -0
  115. data/assets/fixtures/tests_with_subdir_includes/test/test_sensor.c +32 -0
  116. data/bin/actionator.rb +234 -0
  117. data/bin/app_cfg.rb +7 -0
  118. data/bin/cli.rb +78 -47
  119. data/bin/cli_handler.rb +89 -57
  120. data/bin/cli_helper.rb +90 -49
  121. data/bin/cli_options_transform.rb +22 -0
  122. data/bin/{configinator.rb → composinator.rb} +39 -32
  123. data/bin/mixin_resolvinator.rb +124 -0
  124. data/bin/mixin_standardizer.rb +31 -61
  125. data/bin/mixinator.rb +27 -29
  126. data/bin/mixins.rb +0 -5
  127. data/bin/objects.yml +20 -7
  128. data/bin/path_validator.rb +6 -5
  129. data/bin/projectinator.rb +51 -142
  130. data/bin/rake_patches.rb +36 -2
  131. data/bin/recursive_merger.rb +7 -1
  132. data/bin/versionator.rb +2 -3
  133. data/ceedling.gemspec +83 -12
  134. data/docs/BreakingChanges.md +46 -2
  135. data/docs/CONTRIBUTING.md +45 -29
  136. data/docs/CeedlingPullRequestChecklist.md +10 -9
  137. data/docs/Changelog.md +327 -37
  138. data/docs/KnownIssues.md +30 -4
  139. data/docs/ReleaseNotes.md +288 -12
  140. data/docs/SECURITY.md +46 -2
  141. data/docs/ThrowTheSwitchCodingStandard.md +21 -3
  142. data/docs/overrides/main.html +32 -0
  143. data/examples/temp_sensor/mixin/add_bullseye.yml +19 -0
  144. data/examples/wondrous_forest/README.md +3 -0
  145. data/examples/wondrous_forest/src/sensors/light/Calibration.c +21 -0
  146. data/examples/wondrous_forest/src/sensors/light/Calibration.h +14 -0
  147. data/examples/wondrous_forest/src/sensors/soil/Calibration.c +23 -0
  148. data/examples/wondrous_forest/src/sensors/soil/Calibration.h +14 -0
  149. data/examples/wondrous_forest/test/TestCalibration.c +39 -0
  150. data/lib/ceedling/batchinator.rb +81 -22
  151. data/lib/ceedling/c_extractor/README.md +61 -0
  152. data/lib/ceedling/c_extractor/c_extractor.rb +33 -2
  153. data/lib/ceedling/c_extractor/c_extractor_code_text.rb +18 -10
  154. data/lib/ceedling/c_extractor/c_extractor_constants.rb +10 -10
  155. data/lib/ceedling/c_extractor/c_extractor_declarations.rb +14 -14
  156. data/lib/ceedling/c_extractor/c_extractor_functions.rb +10 -13
  157. data/lib/ceedling/c_extractor/c_extractor_preprocessing.rb +77 -0
  158. data/lib/ceedling/c_extractor/c_extractor_types.rb +8 -5
  159. data/lib/ceedling/ceedling.h +33 -0
  160. data/lib/ceedling/config/config_matchinator.rb +36 -13
  161. data/lib/ceedling/config/configurator.rb +366 -530
  162. data/lib/ceedling/config/configurator_builder.rb +253 -365
  163. data/lib/ceedling/config/configurator_plugins.rb +68 -102
  164. data/lib/ceedling/config/configurator_setup.rb +343 -610
  165. data/lib/ceedling/config/configurator_validator.rb +114 -142
  166. data/lib/ceedling/config/line_marker_suppressors.rb +67 -0
  167. data/lib/ceedling/constants.rb +60 -6
  168. data/lib/ceedling/defaults.rb +28 -14
  169. data/lib/ceedling/defineinator.rb +9 -4
  170. data/lib/ceedling/dependencies/README.md +69 -0
  171. data/lib/ceedling/dependencies/dependency_cache_store.rb +160 -0
  172. data/lib/ceedling/dependencies/dependency_debug_tree.rb +129 -0
  173. data/lib/ceedling/dependencies/dependency_differ.rb +127 -0
  174. data/lib/ceedling/dependencies/dependency_hasher.rb +94 -0
  175. data/lib/ceedling/dependencies/dependency_path_normalizer.rb +80 -0
  176. data/lib/ceedling/dependencies/dependency_tracker.rb +405 -0
  177. data/lib/ceedling/dependencies/dependinator.rb +65 -0
  178. data/lib/ceedling/dependencies/gcc_dependency_parser.rb +86 -0
  179. data/lib/ceedling/encodinator.rb +23 -11
  180. data/lib/ceedling/file_finder.rb +373 -89
  181. data/lib/ceedling/file_finder_helper.rb +44 -33
  182. data/lib/ceedling/file_path_collection_utils.rb +17 -4
  183. data/lib/ceedling/file_path_utils.rb +310 -52
  184. data/lib/ceedling/file_wrapper.rb +245 -8
  185. data/lib/ceedling/filename_extension.rb +91 -0
  186. data/lib/ceedling/flaginator.rb +6 -2
  187. data/lib/ceedling/generators/generator.rb +192 -70
  188. data/lib/ceedling/generators/generator_helper.rb +116 -69
  189. data/lib/ceedling/generators/generator_mocks.rb +13 -8
  190. data/lib/ceedling/generators/generator_partials.rb +47 -15
  191. data/lib/ceedling/generators/generator_test_results.rb +29 -17
  192. data/lib/ceedling/generators/generator_test_results_backtrace.rb +199 -107
  193. data/lib/ceedling/generators/generator_test_results_sanity_checker.rb +1 -1
  194. data/lib/ceedling/includes/include_factory.rb +21 -6
  195. data/lib/ceedling/includes/include_pathinator.rb +40 -4
  196. data/lib/ceedling/includes/includes.rb +215 -61
  197. data/lib/ceedling/loginator.rb +13 -4
  198. data/lib/ceedling/objects.yml +216 -33
  199. data/lib/ceedling/parsing_parcels.rb +39 -13
  200. data/lib/ceedling/partials/README.md +53 -0
  201. data/lib/ceedling/partials/partializer.rb +118 -26
  202. data/lib/ceedling/partials/partializer_config.rb +141 -8
  203. data/lib/ceedling/partials/partializer_helper.rb +88 -2
  204. data/lib/ceedling/partials/partializer_utils.rb +1 -1
  205. data/lib/ceedling/partials/partials.rb +4 -4
  206. data/lib/ceedling/path_matcher.rb +163 -0
  207. data/lib/ceedling/path_mirror.rb +73 -0
  208. data/lib/ceedling/plugins/plugin.rb +1 -1
  209. data/lib/ceedling/plugins/plugin_manager.rb +31 -15
  210. data/lib/ceedling/plugins/plugin_manager_helper.rb +5 -1
  211. data/lib/ceedling/plugins/plugin_reportinator.rb +36 -7
  212. data/lib/ceedling/plugins/plugin_reportinator_helper.rb +3 -3
  213. data/lib/ceedling/plugins/report_log_writer_plugin.rb +66 -0
  214. data/lib/ceedling/plugins/report_tests_stdout_plugin.rb +18 -5
  215. data/lib/ceedling/preprocess/README.md +135 -120
  216. data/lib/ceedling/preprocess/c_comment_scanner.rb +9 -7
  217. data/lib/ceedling/preprocess/c_preprocessor_conditionals.rb +27 -10
  218. data/lib/ceedling/preprocess/preprocessinator.rb +253 -217
  219. data/lib/ceedling/preprocess/preprocessinator_bare_includes_extractor.rb +7 -10
  220. data/lib/ceedling/preprocess/preprocessinator_code_finder.rb +8 -6
  221. data/lib/ceedling/preprocess/preprocessinator_comment_stripper.rb +5 -3
  222. data/lib/ceedling/preprocess/preprocessinator_file_assembler.rb +86 -82
  223. data/lib/ceedling/preprocess/preprocessinator_includes_handler.rb +182 -163
  224. data/lib/ceedling/preprocess/preprocessinator_line_marker_includes_extractor.rb +174 -8
  225. data/lib/ceedling/preprocess/preprocessinator_reconstructor.rb +41 -20
  226. data/lib/ceedling/quote_include_isolator.rb +129 -0
  227. data/lib/ceedling/rake_app/rake_task_registry.rb +9 -9
  228. data/lib/ceedling/rake_app/rake_wrapper.rb +0 -13
  229. data/lib/ceedling/rake_app/rakefile_component_resolver.rb +24 -12
  230. data/lib/ceedling/rakefile.rb +2 -1
  231. data/lib/ceedling/{tasks_base.rake → rakefiles/base/tasks_base.rake} +1 -1
  232. data/lib/ceedling/{tasks_filesystem.rake → rakefiles/base/tasks_filesystem.rake} +3 -0
  233. data/lib/ceedling/rakefiles/release/rules_release.rake +52 -0
  234. data/lib/ceedling/{erb_wrapper.rb → rakefiles/release/tasks_release.rake} +5 -8
  235. data/lib/ceedling/rakefiles/tests/rules_tests.rake +43 -0
  236. data/lib/ceedling/rakefiles/tests/rules_tests_generate.rake +80 -0
  237. data/lib/ceedling/{tasks_tests.rake → rakefiles/tests/tasks_tests.rake} +11 -20
  238. data/lib/ceedling/rakefiles/tests/tasks_tests_generate.rake +55 -0
  239. data/lib/ceedling/release_invoker/README.md +35 -0
  240. data/lib/ceedling/release_invoker/release_build_executor.rb +263 -0
  241. data/lib/ceedling/release_invoker/release_build_planner.rb +80 -0
  242. data/lib/ceedling/release_invoker/release_invoker.rb +78 -0
  243. data/lib/ceedling/release_invoker/release_invoker_types.rb +40 -0
  244. data/lib/ceedling/reportinator.rb +18 -2
  245. data/lib/ceedling/ruby_expandinator.rb +40 -1
  246. data/lib/ceedling/setupinator.rb +9 -3
  247. data/lib/ceedling/system_wrapper.rb +17 -0
  248. data/lib/ceedling/templateinator.rb +146 -0
  249. data/lib/ceedling/test_context_extractor.rb +59 -28
  250. data/lib/ceedling/test_invoker/HEADER_COLLISIONS.md +41 -0
  251. data/lib/ceedling/test_invoker/PIPELINE.md +142 -0
  252. data/lib/ceedling/test_invoker/README.md +6 -0
  253. data/lib/ceedling/test_invoker/mock_locator.rb +49 -0
  254. data/lib/ceedling/test_invoker/partials_manager.rb +426 -0
  255. data/lib/ceedling/test_invoker/standin_headerinator.rb +136 -0
  256. data/lib/ceedling/test_invoker/test_bare_includes_extractinator.rb +117 -0
  257. data/lib/ceedling/test_invoker/test_build_executor.rb +783 -429
  258. data/lib/ceedling/test_invoker/test_build_planner.rb +175 -70
  259. data/lib/ceedling/test_invoker/test_build_setup.rb +132 -241
  260. data/lib/ceedling/test_invoker/test_build_validations.rb +102 -0
  261. data/lib/ceedling/test_invoker/test_file_preprocessinator.rb +148 -0
  262. data/lib/ceedling/test_invoker/test_includes_extractinator.rb +34 -0
  263. data/lib/ceedling/test_invoker/test_includes_preprocessinator.rb +118 -0
  264. data/lib/ceedling/test_invoker/test_includes_reconcilinator.rb +149 -0
  265. data/lib/ceedling/test_invoker/test_invoker.rb +16 -183
  266. data/lib/ceedling/test_invoker/test_invoker_types.rb +85 -16
  267. data/lib/ceedling/test_invoker/test_pipeline_helpers.rb +121 -0
  268. data/lib/ceedling/test_invoker/test_pipeline_manager.rb +303 -0
  269. data/lib/ceedling/test_invoker/test_runner_generatinator.rb +105 -0
  270. data/lib/ceedling/test_invoker/test_search_paths.rb +73 -0
  271. data/lib/ceedling/test_invoker/test_source_file_directive_resolver.rb +78 -0
  272. data/lib/ceedling/tool_executor.rb +42 -13
  273. data/lib/ceedling/tool_executor_helper.rb +1 -1
  274. data/lib/ceedling/tool_validator.rb +124 -123
  275. data/lib/ceedling/yaml_wrapper.rb +5 -3
  276. data/lib/version.rb +19 -2
  277. data/mkdocs.prerelease.yml +42 -0
  278. data/mkdocs.yml +10 -2
  279. data/plugins/bullseye/bullseye.rake +70 -107
  280. data/plugins/bullseye/config/defaults.yml +12 -54
  281. data/plugins/bullseye/config/defaults_bullseye.rb +182 -0
  282. data/plugins/bullseye/lib/bullseye.rb +511 -120
  283. data/plugins/bullseye/lib/bullseye_constants.rb +100 -0
  284. data/plugins/command_hooks/lib/command_hooks.rb +117 -199
  285. data/plugins/compile_commands_json_db/lib/compile_commands_json_db.rb +72 -27
  286. data/plugins/cppcheck/config/defaults.yml +6 -1
  287. data/plugins/cppcheck/config/defaults_cppcheck.rb +5 -1
  288. data/plugins/cppcheck/cppcheck.rake +7 -1
  289. data/plugins/cppcheck/lib/cppcheck.rb +175 -26
  290. data/plugins/cppcheck/lib/cppcheck_constants.rb +12 -0
  291. data/plugins/cppcheck/lib/cppcheck_reports.rb +5 -1
  292. data/plugins/dependencies/Rakefile +14 -2
  293. data/plugins/dependencies/config/defaults.yml +9 -6
  294. data/plugins/dependencies/dependencies.rake +46 -76
  295. data/plugins/dependencies/example/boss/project.yml +1 -1
  296. data/plugins/dependencies/example/supervisor/project.yml +1 -1
  297. data/plugins/dependencies/example/version.tar.gzip +0 -0
  298. data/plugins/dependencies/lib/dependencies.rb +232 -427
  299. data/plugins/dependencies/lib/dependency_commands.rb +72 -0
  300. data/plugins/dependencies/lib/dependency_environment.rb +57 -0
  301. data/plugins/dependencies/lib/dependency_spec.rb +145 -0
  302. data/plugins/fff/.rspec +1 -0
  303. data/plugins/fff/Rakefile +14 -2
  304. data/plugins/fff/examples/fff_example/project.yml +1 -1
  305. data/plugins/fff/lib/fff.rb +30 -9
  306. data/plugins/fff/lib/fff_mock_generator.rb +142 -128
  307. data/plugins/fff/spec/fff_mock_header_generator_spec.rb +15 -0
  308. data/plugins/fff/spec/fff_mock_source_generator_spec.rb +14 -0
  309. data/plugins/fff/spec/spec_helper.rb +45 -0
  310. data/plugins/fff/src/fff_unity_helper.h +5 -0
  311. data/plugins/fff/vendor/fff/fakegen.rb +5 -4
  312. data/plugins/fff/vendor/fff/fff.h +4 -4
  313. data/plugins/gcov/config/defaults.yml +5 -0
  314. data/plugins/gcov/gcov.rake +12 -8
  315. data/plugins/gcov/lib/console_reportinator.rb +140 -20
  316. data/plugins/gcov/lib/gcov.rb +155 -60
  317. data/plugins/gcov/lib/gcov_constants.rb +4 -7
  318. data/plugins/gcov/lib/gcov_reportinator.rb +90 -0
  319. data/plugins/gcov/lib/gcov_types.rb +62 -1
  320. data/plugins/gcov/lib/gcovr_reportinator.rb +255 -213
  321. data/plugins/gcov/lib/reportgenerator_reportinator.rb +122 -44
  322. data/plugins/module_generator/Rakefile +4 -4
  323. data/plugins/module_generator/config/module_generator.yml +0 -1
  324. data/plugins/module_generator/example/project.yml +1 -1
  325. data/plugins/module_generator/lib/module_generator.rb +117 -87
  326. data/plugins/module_generator/lib/module_generator_options.rb +150 -0
  327. data/plugins/module_generator/lib/module_generator_project.rb +45 -0
  328. data/plugins/module_generator/lib/module_generator_request.rb +83 -0
  329. data/plugins/module_generator/lib/module_generator_test_file.rb +68 -0
  330. data/plugins/module_generator/lib/module_generator_unity.rb +24 -0
  331. data/plugins/module_generator/module_generator.rake +24 -46
  332. data/plugins/report_build_warnings_log/config/defaults.yml +4 -1
  333. data/plugins/report_build_warnings_log/lib/report_build_warnings_log.rb +47 -55
  334. data/plugins/report_build_warnings_log/lib/warning_collector.rb +140 -0
  335. data/plugins/report_build_warnings_log/lib/warning_reports.rb +135 -0
  336. data/plugins/report_tests_gtestlike_stdout/assets/test_results.template +3 -0
  337. data/{spec/units/configurator_builder_spec.rb → plugins/report_tests_gtestlike_stdout/config/defaults.yml} +6 -10
  338. data/plugins/report_tests_gtestlike_stdout/lib/gtestlike_report.rb +168 -0
  339. data/plugins/report_tests_gtestlike_stdout/lib/report_tests_gtestlike_stdout.rb +25 -1
  340. data/plugins/report_tests_ide_stdout/assets/test_results.template +50 -0
  341. data/plugins/report_tests_ide_stdout/config/defaults.yml +13 -0
  342. data/plugins/report_tests_ide_stdout/lib/ide_report_lines.rb +103 -0
  343. data/plugins/report_tests_ide_stdout/lib/report_tests_ide_stdout.rb +12 -4
  344. data/plugins/report_tests_log_factory/lib/cppunit_tests_reporter.rb +33 -51
  345. data/plugins/report_tests_log_factory/lib/html_tests_reporter.rb +286 -295
  346. data/plugins/report_tests_log_factory/lib/json_tests_reporter.rb +22 -35
  347. data/plugins/report_tests_log_factory/lib/junit_tests_reporter.rb +91 -133
  348. data/plugins/report_tests_log_factory/lib/report_tests_log_factory.rb +72 -86
  349. data/plugins/report_tests_log_factory/lib/tests_reporter.rb +31 -12
  350. data/plugins/report_tests_pretty_stdout/assets/{template.erb → test_results.template} +8 -8
  351. data/plugins/report_tests_raw_output_log/lib/report_tests_raw_output_log.rb +18 -48
  352. data/plugins/report_tests_teamcity_stdout/lib/report_tests_teamcity_stdout.rb +13 -2
  353. data/plugins/sanitize/config/defaults.yml +44 -0
  354. data/plugins/sanitize/config/defaults_sanitize.rb +20 -0
  355. data/plugins/sanitize/lib/sanitize.rb +174 -0
  356. data/plugins/sanitize/lib/sanitize_config.rb +110 -0
  357. data/plugins/sanitize/lib/sanitize_constants.rb +13 -0
  358. data/plugins/sanitize/lib/sanitize_findings.rb +85 -0
  359. data/plugins/sanitize/lib/sanitize_records.rb +115 -0
  360. data/plugins/sanitize/lib/sanitize_reports.rb +135 -0
  361. data/plugins/sanitize/sanitize.rake +108 -0
  362. data/plugins/valgrind/config/defaults.yml +7 -1
  363. data/plugins/valgrind/config/defaults_valgrind.rb +6 -1
  364. data/plugins/valgrind/lib/valgrind.rb +202 -39
  365. data/plugins/valgrind/lib/valgrind_constants.rb +4 -0
  366. data/plugins/valgrind/lib/valgrind_report.rb +52 -0
  367. data/plugins/valgrind/valgrind.rake +33 -11
  368. data/site-local/404.html +248 -14
  369. data/site-local/configuration/environment-vars.html +248 -14
  370. data/site-local/configuration/global-collections.html +248 -19
  371. data/site-local/configuration/index.html +249 -15
  372. data/site-local/configuration/loading.html +260 -22
  373. data/site-local/configuration/mixins.html +252 -17
  374. data/site-local/configuration/parallel-builds.html +248 -14
  375. data/site-local/configuration/project-file.html +275 -30
  376. data/site-local/configuration/reference/cexception.html +255 -20
  377. data/site-local/configuration/reference/cmock.html +281 -14
  378. data/site-local/configuration/reference/defines.html +262 -19
  379. data/site-local/configuration/reference/environment.html +251 -17
  380. data/site-local/configuration/reference/extension.html +361 -16
  381. data/site-local/configuration/reference/files.html +262 -14
  382. data/site-local/configuration/reference/flags.html +270 -19
  383. data/site-local/configuration/reference/index.html +248 -14
  384. data/site-local/configuration/reference/libraries.html +248 -14
  385. data/site-local/configuration/reference/mixins.html +248 -14
  386. data/site-local/configuration/reference/partials.html +249 -19
  387. data/site-local/configuration/reference/paths.html +275 -15
  388. data/site-local/configuration/reference/plugins.html +248 -14
  389. data/site-local/configuration/reference/project.html +291 -14
  390. data/site-local/configuration/reference/release-build.html +256 -14
  391. data/site-local/configuration/reference/test-build.html +290 -24
  392. data/site-local/configuration/reference/test-runner.html +288 -17
  393. data/site-local/configuration/reference/tools.html +254 -14
  394. data/site-local/configuration/reference/unity.html +280 -15
  395. data/site-local/configuration/which-ceedling.html +248 -14
  396. data/site-local/development/index.html +254 -14
  397. data/site-local/development/plugins/configuration.html +269 -17
  398. data/site-local/development/plugins/index.html +267 -15
  399. data/site-local/development/plugins/plugin-subclass.html +906 -154
  400. data/site-local/development/plugins/rake-tasks.html +276 -14
  401. data/site-local/development/releases.html +4708 -0
  402. data/site-local/development/workflow.html +1030 -51
  403. data/site-local/getting-started/builds.html +4607 -0
  404. data/site-local/getting-started/command-line.html +418 -34
  405. data/site-local/getting-started/example-projects/cipher-quest.html +248 -14
  406. data/site-local/getting-started/example-projects/index.html +249 -15
  407. data/site-local/getting-started/example-projects/temp-sensor.html +248 -14
  408. data/site-local/getting-started/example-projects/wondrous-forest.html +248 -14
  409. data/site-local/getting-started/index.html +255 -14
  410. data/site-local/getting-started/installation.html +258 -22
  411. data/site-local/getting-started/quick-start.html +251 -15
  412. data/site-local/help.html +255 -14
  413. data/site-local/index.html +292 -22
  414. data/site-local/overview/build-system.html +249 -15
  415. data/site-local/overview/index.html +248 -14
  416. data/site-local/overview/test-environments.html +257 -14
  417. data/site-local/overview/tools-and-frameworks.html +248 -14
  418. data/site-local/plugins/beep.html +251 -14
  419. data/site-local/plugins/bullseye/index.html +5079 -0
  420. data/site-local/plugins/bullseye/licensing.html +4840 -0
  421. data/site-local/plugins/command-hooks.html +265 -27
  422. data/site-local/plugins/compile-commands-json-db.html +256 -17
  423. data/site-local/plugins/cppcheck.html +1081 -262
  424. data/site-local/plugins/dependencies.html +934 -242
  425. data/site-local/plugins/fff.html +296 -15
  426. data/site-local/plugins/gcov/examples.html +251 -14
  427. data/site-local/plugins/gcov/gcovr.html +567 -65
  428. data/site-local/plugins/gcov/index.html +251 -14
  429. data/site-local/plugins/gcov/overview.html +259 -18
  430. data/site-local/plugins/gcov/reportgenerator.html +386 -38
  431. data/site-local/plugins/gcov/reporting.html +348 -100
  432. data/site-local/plugins/gcov/setup.html +253 -15
  433. data/site-local/plugins/gcov/tool-versions.html +301 -19
  434. data/site-local/plugins/gcov/troubleshooting.html +273 -36
  435. data/site-local/plugins/index.html +294 -36
  436. data/site-local/plugins/module-generator.html +779 -195
  437. data/site-local/plugins/report-build-warnings-log.html +578 -33
  438. data/site-local/plugins/report-tests-gtestlike-stdout.html +467 -84
  439. data/site-local/plugins/report-tests-ide-stdout.html +654 -51
  440. data/site-local/plugins/report-tests-log-factory.html +337 -70
  441. data/site-local/plugins/report-tests-pretty-stdout.html +251 -14
  442. data/site-local/plugins/report-tests-raw-output-log.html +251 -14
  443. data/site-local/plugins/report-tests-teamcity-stdout.html +251 -14
  444. data/site-local/plugins/sanitize.html +5332 -0
  445. data/site-local/plugins/valgrind.html +416 -26
  446. data/site-local/{plugins/bullseye.html → project/index.html} +297 -217
  447. data/site-local/project/release-history.html +251 -17
  448. data/site-local/project/sbom.html +4726 -0
  449. data/site-local/project/upgrade.html +250 -16
  450. data/site-local/reference/build-directives.html +257 -14
  451. data/site-local/reference/command-line.html +373 -16
  452. data/site-local/reference/environment-vars.html +248 -14
  453. data/site-local/reference/gcov-plugin.html +492 -18
  454. data/site-local/reference/global-collections.html +249 -15
  455. data/site-local/reference/index.html +248 -14
  456. data/site-local/reference/partials-macros.html +258 -14
  457. data/site-local/reference/project-configuration.html +248 -14
  458. data/site-local/sitemap.xml.gz +0 -0
  459. data/{docs/mkdocs/snapshot/assets → site-local/snapshot/assets/features}/project.yml +4 -1
  460. data/site-local/snapshot/examples/cipher_quest/index.html +248 -14
  461. data/site-local/snapshot/examples/temp_sensor/index.html +248 -14
  462. data/site-local/snapshot/examples/wondrous_forest/index.html +265 -25
  463. data/site-local/snapshot/plugins/bullseye/config/defaults.yml +24 -0
  464. data/site-local/snapshot/plugins/bullseye/config/defaults_bullseye.rb +182 -0
  465. data/site-local/snapshot/plugins/gcov/config/defaults.yml +5 -0
  466. data/site-local/testing-guide/build-directives.html +332 -22
  467. data/site-local/testing-guide/conventions.html +678 -153
  468. data/site-local/testing-guide/frameworks.html +248 -14
  469. data/site-local/testing-guide/index.html +248 -21
  470. data/site-local/testing-guide/partials/configuration.html +248 -14
  471. data/site-local/testing-guide/partials/conventions.html +316 -17
  472. data/site-local/testing-guide/partials/directives.html +456 -48
  473. data/site-local/testing-guide/partials/example.html +248 -14
  474. data/site-local/testing-guide/partials/index.html +255 -14
  475. data/site-local/testing-guide/partials/overview.html +248 -14
  476. data/site-local/testing-guide/partials/variables.html +248 -14
  477. data/site-local/testing-guide/test-cases.html +248 -14
  478. data/site-local/testing-guide/test-sample.html +248 -14
  479. data/site-local/testing-guide/test-suite-anatomy.html +248 -14
  480. data/spec/integration/actionator_file_operations_spec.rb +287 -0
  481. data/spec/integration/analysis_tool_output_spec.rb +204 -0
  482. data/spec/{units/c_extractor/c_extractor_integration_spec.rb → integration/c_extractor_composition_spec.rb} +196 -17
  483. data/spec/integration/command_hooks_plugin_spec.rb +152 -0
  484. data/spec/integration/compile_commands_json_db_spec.rb +76 -0
  485. data/spec/integration/configurator_pipeline_spec.rb +180 -0
  486. data/spec/integration/configurator_plugins_spec.rb +122 -0
  487. data/spec/integration/configurator_validation_spec.rb +98 -0
  488. data/spec/integration/dependencies/dependency_tracker_cache_hardening_spec.rb +396 -0
  489. data/spec/integration/dependencies/dependency_tracker_core_spec.rb +244 -0
  490. data/spec/integration/dependencies/dependency_tracker_diagnose_spec.rb +224 -0
  491. data/spec/integration/dependencies/dependency_tracker_filename_handling_spec.rb +118 -0
  492. data/spec/integration/dependencies/dependency_tracker_gcc_deps_spec.rb +199 -0
  493. data/spec/integration/dependencies/dependency_tracker_pruning_spec.rb +167 -0
  494. data/spec/integration/dependencies_plugin_spec.rb +473 -0
  495. data/spec/integration/erb_dependency_removed_spec.rb +167 -0
  496. data/spec/integration/includes_extraction_spec.rb +612 -0
  497. data/spec/integration/mixin_loading_spec.rb +414 -0
  498. data/spec/integration/module_generator_spec.rb +436 -0
  499. data/spec/integration/partials_fallback_preprocessing_spec.rb +316 -0
  500. data/spec/integration/partials_header_composition_spec.rb +889 -0
  501. data/spec/integration/partials_module_resolution_spec.rb +372 -0
  502. data/spec/integration/partials_symbol_linkage_spec.rb +371 -0
  503. data/spec/integration/preprocessing_transient_io_retry_spec.rb +135 -0
  504. data/spec/integration/quote_include_isolator_spec.rb +167 -0
  505. data/spec/integration/report_build_warnings_log_spec.rb +170 -0
  506. data/spec/integration/report_tests_log_factory_spec.rb +100 -0
  507. data/spec/integration/sanitizer_exclusions_spec.rb +126 -0
  508. data/spec/integration/system_harness_sanitizers_spec.rb +104 -0
  509. data/spec/integration/test_build_parallel_barrier_spec.rb +89 -0
  510. data/spec/integration/test_executable_manifest_spec.rb +118 -0
  511. data/spec/integration/test_includes_extractinator_spec.rb +293 -0
  512. data/spec/integration/tool_executor_spec.rb +224 -0
  513. data/spec/integration/tool_validator_spec.rb +133 -0
  514. data/spec/integration/vendor_copy_transient_io_retry_spec.rb +130 -0
  515. data/spec/manual/stress_test.rb +1 -1
  516. data/spec/support/config_yaml_helper.rb +17 -0
  517. data/spec/support/fixtures/sanitizer_reports/clang_asan_heap.txt +45 -0
  518. data/spec/support/fixtures/sanitizer_reports/clang_ubsan_shift.txt +5 -0
  519. data/spec/support/fixtures/sanitizer_reports/gcc_heap.txt +47 -0
  520. data/spec/support/fixtures/sanitizer_reports/gcc_leak.txt +10 -0
  521. data/spec/support/fixtures/sanitizer_reports/gcc_segv.txt +6 -0
  522. data/spec/support/fixtures/sanitizer_reports/gcc_ubsan_shift.txt +6 -0
  523. data/spec/support/fixtures/templates/bullseye__all_pass.txt +6 -0
  524. data/spec/support/fixtures/templates/bullseye__coverage_branches_only.txt +6 -0
  525. data/spec/support/fixtures/templates/bullseye__coverage_functions_only.txt +6 -0
  526. data/spec/support/fixtures/templates/bullseye__coverage_none.txt +6 -0
  527. data/spec/support/fixtures/templates/bullseye__empty.txt +6 -0
  528. data/spec/support/fixtures/templates/bullseye__gcov_context.txt +6 -0
  529. data/spec/support/fixtures/templates/bullseye__mixed_all.txt +6 -0
  530. data/spec/support/fixtures/templates/bullseye__one_failure_matching.txt +6 -0
  531. data/spec/support/fixtures/templates/bullseye__one_failure_multiline.txt +6 -0
  532. data/spec/support/fixtures/templates/bullseye__one_failure_no_message.txt +6 -0
  533. data/spec/support/fixtures/templates/bullseye__one_failure_nonmatching.txt +6 -0
  534. data/spec/support/fixtures/templates/bullseye__one_ignore_no_message.txt +6 -0
  535. data/spec/support/fixtures/templates/bullseye__one_ignore_with_message.txt +6 -0
  536. data/spec/support/fixtures/templates/bullseye__stdout_only.txt +6 -0
  537. data/spec/support/fixtures/templates/ide__all_pass.txt +10 -0
  538. data/spec/support/fixtures/templates/ide__coverage_branches_only.txt +10 -0
  539. data/spec/support/fixtures/templates/ide__coverage_functions_only.txt +10 -0
  540. data/spec/support/fixtures/templates/ide__coverage_none.txt +10 -0
  541. data/spec/support/fixtures/templates/ide__empty.txt +8 -0
  542. data/spec/support/fixtures/templates/ide__gcov_context.txt +28 -0
  543. data/spec/support/fixtures/templates/ide__mixed_all.txt +29 -0
  544. data/spec/support/fixtures/templates/ide__one_failure_matching.txt +15 -0
  545. data/spec/support/fixtures/templates/ide__one_failure_multiline.txt +17 -0
  546. data/spec/support/fixtures/templates/ide__one_failure_no_message.txt +15 -0
  547. data/spec/support/fixtures/templates/ide__one_failure_nonmatching.txt +15 -0
  548. data/spec/support/fixtures/templates/ide__one_ignore_no_message.txt +15 -0
  549. data/spec/support/fixtures/templates/ide__one_ignore_with_message.txt +15 -0
  550. data/spec/support/fixtures/templates/ide__stdout_only.txt +16 -0
  551. data/spec/support/fixtures/templates/pretty__all_pass.txt +8 -0
  552. data/spec/support/fixtures/templates/pretty__coverage_branches_only.txt +8 -0
  553. data/spec/support/fixtures/templates/pretty__coverage_functions_only.txt +8 -0
  554. data/spec/support/fixtures/templates/pretty__coverage_none.txt +8 -0
  555. data/spec/support/fixtures/templates/pretty__empty.txt +6 -0
  556. data/spec/support/fixtures/templates/pretty__gcov_context.txt +31 -0
  557. data/spec/support/fixtures/templates/pretty__mixed_all.txt +35 -0
  558. data/spec/support/fixtures/templates/pretty__one_failure_matching.txt +15 -0
  559. data/spec/support/fixtures/templates/pretty__one_failure_multiline.txt +17 -0
  560. data/spec/support/fixtures/templates/pretty__one_failure_no_message.txt +15 -0
  561. data/spec/support/fixtures/templates/pretty__one_failure_nonmatching.txt +15 -0
  562. data/spec/support/fixtures/templates/pretty__one_ignore_no_message.txt +15 -0
  563. data/spec/support/fixtures/templates/pretty__one_ignore_with_message.txt +15 -0
  564. data/spec/support/fixtures/templates/pretty__stdout_only.txt +15 -0
  565. data/spec/support/fixtures/valgrind_reports/sigsegv.log +51 -0
  566. data/spec/support/fixtures/valgrind_reports/sigsegv.xml +182 -0
  567. data/spec/support/include_guard_helper.rb +20 -0
  568. data/spec/support/integration/configurator_integration_helper.rb +159 -0
  569. data/spec/support/integration/dependency_tracker_integration_helper.rb +136 -0
  570. data/spec/support/integration/partials_generation_integration_helper.rb +726 -0
  571. data/spec/support/integration/spec_integration_helper.rb +285 -0
  572. data/spec/support/integration/test_includes_harness.rb +259 -0
  573. data/spec/support/integration/tool_executor_integration_helper.rb +55 -0
  574. data/spec/support/spec_helper.rb +41 -0
  575. data/spec/support/system/sanitizers/asan_ubsan.yml +82 -0
  576. data/spec/support/system/sanitizers/asan_ubsan_leaks.yml +57 -0
  577. data/spec/support/system/simplecov_boot.rb +66 -0
  578. data/spec/support/system/spec_system_helper.rb +376 -16
  579. data/spec/support/system/system_context.rb +181 -59
  580. data/spec/support/template_render_cases.rb +166 -0
  581. data/spec/system/bracket_path_handling_spec.rb +175 -0
  582. data/spec/system/build_output_mirroring_spec.rb +89 -0
  583. data/spec/system/build_recovery_spec.rb +382 -0
  584. data/spec/system/bullseye_deployment_spec.rb +102 -0
  585. data/spec/system/cli_surface_spec.rb +245 -0
  586. data/spec/system/command_hooks_spec.rb +117 -0
  587. data/spec/system/conditional_include_macro_visibility_spec.rb +32 -124
  588. data/spec/system/conditional_mock_includes_spec.rb +181 -0
  589. data/spec/system/cppcheck_deployment_spec.rb +26 -8
  590. data/spec/system/delta_builds_spec.rb +751 -0
  591. data/spec/system/deployment_as_gem_spec.rb +7 -0
  592. data/spec/system/deployment_as_vendor_spec.rb +29 -145
  593. data/spec/system/dumpconfig_spec.rb +137 -0
  594. data/spec/system/encoding_stress_spec.rb +7 -4
  595. data/spec/system/example_cipher_quest_spec.rb +25 -100
  596. data/spec/system/example_temp_sensor_spec.rb +30 -172
  597. data/spec/system/example_wondrous_forest_spec.rb +25 -62
  598. data/spec/system/extension_multiple_values_spec.rb +75 -0
  599. data/spec/system/files_paths_reporting_spec.rb +154 -0
  600. data/spec/system/gcov_deployment_spec.rb +72 -3
  601. data/spec/system/header_include_path_validation_spec.rb +222 -0
  602. data/spec/system/implicit_source_header_correspondence_disambiguation_spec.rb +100 -0
  603. data/spec/system/include_path_reconciliation_spec.rb +64 -0
  604. data/spec/system/mixin_ordering_spec.rb +30 -415
  605. data/spec/system/mocks_partials_configuration_validation_spec.rb +126 -0
  606. data/spec/system/parent_directory_reference_spec.rb +114 -0
  607. data/spec/system/partials_module_disambiguation_spec.rb +143 -0
  608. data/spec/system/pinned_thread_count_spec.rb +102 -0
  609. data/spec/system/plugin_delta_builds_spec.rb +179 -0
  610. data/spec/system/preprocessing_encoding_spec.rb +87 -4
  611. data/spec/system/preprocessing_fallback_conditionals_spec.rb +19 -25
  612. data/spec/system/preprocessing_parameterized_tests_spec.rb +2 -2
  613. data/spec/system/rake_release_task_path_disambiguation_spec.rb +97 -0
  614. data/spec/system/rake_test_task_path_disambiguation_spec.rb +118 -0
  615. data/spec/system/report_and_tooling_plugins_spec.rb +327 -0
  616. data/spec/system/ruby_replacement_spec.rb +1 -1
  617. data/spec/system/same_named_modules_spec.rb +115 -0
  618. data/spec/system/sanitize_deployment_spec.rb +64 -0
  619. data/spec/system/shuffle_tests_spec.rb +139 -0
  620. data/spec/system/sibling_header_collision_spec.rb +620 -0
  621. data/spec/system/subdir_include_preservation_spec.rb +63 -0
  622. data/spec/system/support/bullseye_common_test_cases.rb +369 -0
  623. data/spec/system/support/bullseye_helpers.rb +70 -0
  624. data/spec/system/support/common_test_cases.rb +167 -43
  625. data/spec/system/support/cppcheck_common_test_cases.rb +80 -0
  626. data/spec/system/support/cppcheck_helpers.rb +10 -8
  627. data/spec/system/support/gcov_common_test_cases.rb +173 -37
  628. data/spec/system/support/gcov_helpers.rb +3 -3
  629. data/spec/system/support/gcov_partials_test_cases.rb +48 -2
  630. data/spec/system/support/sanitize_common_test_cases.rb +222 -0
  631. data/spec/system/support/sanitize_helpers.rb +27 -0
  632. data/spec/system/support/valgrind_common_test_cases.rb +116 -16
  633. data/spec/system/support/valgrind_helpers.rb +3 -4
  634. data/spec/system/test_pipeline_stop_points_spec.rb +160 -0
  635. data/spec/system/test_runner_system_include_spec.rb +19 -41
  636. data/spec/system/test_source_file_directive_spec.rb +235 -0
  637. data/spec/system/upgrade_as_vendor_spec.rb +25 -46
  638. data/spec/system/valgrind_deployment_spec.rb +41 -0
  639. data/spec/units/batchinator_spec.rb +314 -0
  640. data/spec/units/bin/actionator_spec.rb +412 -0
  641. data/spec/units/bin/app_cfg_spec.rb +90 -0
  642. data/spec/units/bin/cli_handler_spec.rb +204 -0
  643. data/spec/units/bin/cli_helper_spec.rb +238 -10
  644. data/spec/units/bin/cli_options_transform_spec.rb +49 -0
  645. data/spec/units/bin/composinator_spec.rb +236 -0
  646. data/spec/units/bin/{projectinator_mixin_spec.rb → mixin_resolvinator_spec.rb} +122 -83
  647. data/spec/units/bin/mixin_standardizer_spec.rb +4 -3
  648. data/spec/units/bin/mixinator_spec.rb +58 -22
  649. data/spec/units/bin/path_validator_spec.rb +112 -0
  650. data/spec/units/bin/projectinator_spec.rb +223 -0
  651. data/spec/units/bin/rake_patches_spec.rb +52 -0
  652. data/spec/units/bin/recursive_merger_spec.rb +22 -0
  653. data/spec/units/bin/versionator_spec.rb +104 -0
  654. data/spec/units/c_extractor/c_extractor_code_text_spec.rb +4 -4
  655. data/spec/units/c_extractor/c_extractor_declarations_spec.rb +70 -0
  656. data/spec/units/c_extractor/c_extractor_functions_spec.rb +75 -1
  657. data/spec/units/c_extractor/c_extractor_preprocessing_spec.rb +158 -0
  658. data/spec/units/c_extractor/c_extractor_spec.rb +236 -6
  659. data/spec/units/ceedling/templateinator_golden_spec.rb +84 -0
  660. data/spec/units/ceedling/templateinator_spec.rb +188 -0
  661. data/spec/units/config/configurator_builder_spec.rb +444 -0
  662. data/spec/units/config/configurator_plugins_spec.rb +160 -0
  663. data/spec/units/config/configurator_setup_spec.rb +706 -6
  664. data/spec/units/config/configurator_spec.rb +952 -0
  665. data/spec/units/config/configurator_validator_spec.rb +259 -0
  666. data/spec/units/config/line_marker_suppressors_spec.rb +89 -0
  667. data/spec/units/config_matchinator_spec.rb +103 -0
  668. data/spec/units/defineinator_spec.rb +158 -0
  669. data/spec/units/dependencies/dependency_cache_store_spec.rb +364 -0
  670. data/spec/units/dependencies/dependency_debug_tree_spec.rb +189 -0
  671. data/spec/units/dependencies/dependency_differ_spec.rb +139 -0
  672. data/spec/units/dependencies/dependency_hasher_spec.rb +141 -0
  673. data/spec/units/dependencies/dependency_path_normalizer_spec.rb +111 -0
  674. data/spec/units/dependencies/dependency_tracker_spec.rb +905 -0
  675. data/spec/units/dependencies/dependinator_spec.rb +99 -0
  676. data/spec/units/dependencies/gcc_dependency_parser_spec.rb +152 -0
  677. data/spec/units/encodinator_spec.rb +92 -0
  678. data/spec/units/file_finder_helper_spec.rb +99 -15
  679. data/spec/units/file_finder_spec.rb +495 -0
  680. data/spec/units/file_path_collection_utils_spec.rb +9 -0
  681. data/spec/units/file_path_utils_spec.rb +736 -0
  682. data/spec/units/file_wrapper_spec.rb +447 -0
  683. data/spec/units/filename_extension_spec.rb +120 -0
  684. data/spec/units/flaginator_spec.rb +114 -0
  685. data/spec/units/generators/generator_helper_spec.rb +113 -0
  686. data/spec/units/generators/generator_mocks_spec.rb +131 -0
  687. data/spec/units/generators/generator_partials_spec.rb +336 -160
  688. data/spec/units/generators/generator_spec.rb +317 -0
  689. data/spec/units/generators/generator_test_results_backtrace_spec.rb +169 -9
  690. data/spec/units/generators/generator_test_results_sanity_checker_spec.rb +14 -6
  691. data/spec/units/generators/generator_test_results_spec.rb +65 -8
  692. data/spec/units/generators/generator_test_runner_spec.rb +1 -1
  693. data/spec/units/includes/include_factory_spec.rb +53 -0
  694. data/spec/units/includes/include_pathinator_spec.rb +269 -0
  695. data/spec/units/includes/include_spec.rb +8 -4
  696. data/spec/units/includes/includes_spec.rb +326 -18
  697. data/spec/units/mock_locator_spec.rb +74 -0
  698. data/spec/units/parsing_parcels_spec.rb +65 -0
  699. data/spec/units/partials/partializer_config_spec.rb +284 -18
  700. data/spec/units/partials/partializer_helper_spec.rb +122 -0
  701. data/spec/units/partials/partializer_spec.rb +346 -71
  702. data/spec/units/partials/partializer_utils_spec.rb +4 -4
  703. data/spec/units/partials_manager_spec.rb +539 -0
  704. data/spec/units/path_matcher_spec.rb +193 -0
  705. data/spec/units/path_mirror_spec.rb +103 -0
  706. data/spec/units/plugin_manager_spec.rb +77 -0
  707. data/spec/units/plugin_reportinator_spec.rb +78 -3
  708. data/spec/units/plugins/bullseye_spec.rb +1068 -0
  709. data/spec/units/plugins/command_hooks_spec.rb +157 -0
  710. data/spec/units/plugins/compile_commands_json_db_spec.rb +145 -0
  711. data/spec/units/plugins/console_reportinator_spec.rb +370 -0
  712. data/spec/units/plugins/cppcheck_spec.rb +330 -4
  713. data/spec/units/plugins/cppunit_tests_reporter_spec.rb +118 -0
  714. data/spec/units/plugins/dependencies_spec.rb +295 -0
  715. data/spec/units/plugins/dependency_commands_spec.rb +83 -0
  716. data/spec/units/plugins/dependency_environment_spec.rb +64 -0
  717. data/spec/units/plugins/dependency_spec_spec.rb +170 -0
  718. data/spec/units/plugins/gcov_reportinator_spec.rb +272 -0
  719. data/spec/units/plugins/gcov_spec.rb +521 -0
  720. data/spec/units/plugins/gcovr_reportinator_spec.rb +795 -0
  721. data/spec/units/plugins/gtestlike_report_spec.rb +363 -0
  722. data/spec/units/plugins/html_tests_reporter_spec.rb +158 -0
  723. data/spec/units/plugins/ide_report_lines_spec.rb +229 -0
  724. data/spec/units/plugins/json_tests_reporter_spec.rb +87 -0
  725. data/spec/units/plugins/junit_tests_reporter_spec.rb +237 -0
  726. data/spec/units/plugins/module_generator_options_spec.rb +185 -0
  727. data/spec/units/plugins/module_generator_project_spec.rb +55 -0
  728. data/spec/units/plugins/module_generator_request_spec.rb +107 -0
  729. data/spec/units/plugins/module_generator_spec.rb +214 -0
  730. data/spec/units/plugins/module_generator_test_file_spec.rb +102 -0
  731. data/spec/units/plugins/module_generator_unity_spec.rb +37 -0
  732. data/spec/units/plugins/report_build_warnings_log_spec.rb +199 -0
  733. data/spec/units/plugins/report_log_writer_plugin_spec.rb +94 -0
  734. data/spec/units/plugins/report_tests_gtestlike_stdout_spec.rb +274 -0
  735. data/spec/units/plugins/report_tests_ide_stdout_spec.rb +140 -0
  736. data/spec/units/plugins/report_tests_log_factory_spec.rb +210 -0
  737. data/spec/units/plugins/report_tests_pretty_stdout_spec.rb +83 -0
  738. data/spec/units/plugins/report_tests_raw_output_log_spec.rb +98 -0
  739. data/spec/units/plugins/report_tests_stdout_plugin_spec.rb +145 -0
  740. data/spec/units/plugins/report_tests_teamcity_stdout_spec.rb +121 -0
  741. data/spec/units/plugins/reportgenerator_reportinator_spec.rb +410 -0
  742. data/spec/units/plugins/sanitize_config_spec.rb +119 -0
  743. data/spec/units/plugins/sanitize_findings_spec.rb +69 -0
  744. data/spec/units/plugins/sanitize_records_spec.rb +114 -0
  745. data/spec/units/plugins/sanitize_reports_spec.rb +84 -0
  746. data/spec/units/plugins/sanitize_spec.rb +300 -0
  747. data/spec/units/plugins/tests_reporter_spec.rb +89 -0
  748. data/spec/units/plugins/valgrind_spec.rb +560 -0
  749. data/spec/units/plugins/warning_collector_spec.rb +185 -0
  750. data/spec/units/plugins/warning_reports_spec.rb +150 -0
  751. data/spec/units/preprocess/c_comment_scanner_spec.rb +17 -17
  752. data/spec/units/preprocess/c_preprocessor_conditionals_spec.rb +94 -0
  753. data/spec/units/preprocess/preprocessinator_bare_includes_extractor_spec.rb +73 -0
  754. data/spec/units/preprocess/preprocessinator_code_finder_spec.rb +35 -16
  755. data/spec/units/preprocess/preprocessinator_comment_stripper_spec.rb +129 -48
  756. data/spec/units/preprocess/preprocessinator_file_assembler_spec.rb +292 -9
  757. data/spec/units/preprocess/preprocessinator_includes_handler_spec.rb +294 -16
  758. data/spec/units/preprocess/preprocessinator_line_marker_includes_extractor_spec.rb +356 -6
  759. data/spec/units/preprocess/preprocessinator_reconstructor_spec.rb +58 -4
  760. data/spec/units/preprocess/preprocessinator_spec.rb +693 -5
  761. data/spec/units/quote_include_isolator_spec.rb +176 -0
  762. data/spec/units/rake_app/rake_invocation_tracker_spec.rb +94 -0
  763. data/spec/units/rake_app/rake_task_registry_spec.rb +263 -0
  764. data/spec/units/rake_app/rake_utils_spec.rb +54 -0
  765. data/spec/units/rake_app/rake_wrapper_spec.rb +64 -0
  766. data/spec/units/rake_app/rakefile_component_resolver_spec.rb +182 -0
  767. data/spec/units/release_build_executor_spec.rb +404 -0
  768. data/spec/units/release_build_planner_spec.rb +144 -0
  769. data/spec/units/release_invoker_spec.rb +127 -0
  770. data/spec/units/reportinator_spec.rb +35 -0
  771. data/spec/units/ruby_expandinator_spec.rb +36 -0
  772. data/spec/units/standin_headerinator_spec.rb +168 -0
  773. data/spec/units/system_wrapper_spec.rb +16 -0
  774. data/spec/units/test_build_executor_spec.rb +1653 -8
  775. data/spec/units/test_build_planner_spec.rb +878 -0
  776. data/spec/units/test_build_setup_spec.rb +583 -0
  777. data/spec/units/test_context_extractor_spec.rb +51 -3
  778. data/spec/units/test_file_preprocessinator_spec.rb +206 -0
  779. data/spec/units/test_includes_extractinator_spec.rb +764 -0
  780. data/spec/units/test_invoker/objects_wiring_spec.rb +31 -0
  781. data/spec/units/test_invoker_spec.rb +147 -0
  782. data/spec/units/test_invoker_types_spec.rb +182 -0
  783. data/spec/units/test_pipeline_helpers_spec.rb +100 -0
  784. data/spec/units/test_pipeline_manager_spec.rb +415 -0
  785. data/spec/units/test_runner_generatinator_spec.rb +215 -0
  786. data/spec/units/test_runner_manager_spec.rb +70 -0
  787. data/spec/units/test_search_paths_spec.rb +84 -0
  788. data/spec/units/test_source_file_directive_resolver_spec.rb +239 -0
  789. data/spec/units/tool_executor_helper_spec.rb +1 -1
  790. data/spec/units/tool_executor_spec.rb +571 -2
  791. data/spec/units/tool_validator_spec.rb +303 -24
  792. data/spec/units/version_spec.rb +74 -0
  793. data/spec/units/yaml_wrapper_spec.rb +4 -1
  794. data/vendor/cmock/docs/CMock_Summary.md +11 -0
  795. data/vendor/cmock/lib/cmock_config.rb +1 -0
  796. data/vendor/cmock/lib/cmock_generator.rb +5 -1
  797. data/vendor/cmock/test/unit/cmock_generator_main_test.rb +31 -0
  798. data/vendor/cmock/vendor/unity/auto/generate_module.rb +4 -4
  799. data/vendor/cmock/vendor/unity/auto/generate_test_runner.rb +8 -2
  800. data/vendor/cmock/vendor/unity/auto/unity_test_summary.rb +2 -2
  801. data/vendor/cmock/vendor/unity/docs/UnityChangeLog.md +7 -0
  802. data/vendor/cmock/vendor/unity/docs/UnityConfigurationGuide.md +4 -0
  803. data/vendor/cmock/vendor/unity/docs/UnityHelperScriptsGuide.md +9 -0
  804. data/vendor/cmock/vendor/unity/src/unity_internals.h +21 -7
  805. data/vendor/cmock/vendor/unity/test/Makefile +9 -2
  806. data/vendor/cmock/vendor/unity/test/rakefile_helper.rb +1 -0
  807. data/vendor/cmock/vendor/unity/test/spec/generate_module_naming_spec.rb +38 -0
  808. data/vendor/cmock/vendor/unity/test/testdata/spi/MockConfig.h +19 -0
  809. data/vendor/cmock/vendor/unity/test/testdata/testRunnerGeneratorWithSameNamedMocks.c +42 -0
  810. data/vendor/cmock/vendor/unity/test/testdata/uart/MockConfig.h +19 -0
  811. data/vendor/cmock/vendor/unity/test/tests/test_generate_test_runner.rb +78 -0
  812. data/vendor/cmock/vendor/unity/test/tests/test_unity_test_summary.rb +58 -0
  813. data/vendor/diy/lib/diy/factory.rb +5 -4
  814. data/vendor/diy/lib/diy.rb +5 -4
  815. data/vendor/diy/sample_code/car.rb +5 -4
  816. data/vendor/diy/sample_code/chassis.rb +5 -4
  817. data/vendor/diy/sample_code/diy_example.rb +5 -4
  818. data/vendor/diy/sample_code/engine.rb +5 -4
  819. data/vendor/diy/sample_code/objects.yml +5 -4
  820. data/vendor/diy/test/constructor.rb +5 -4
  821. data/vendor/diy/test/diy_test.rb +5 -4
  822. data/vendor/diy/test/factory_test.rb +5 -4
  823. data/vendor/diy/test/files/broken_construction.yml +5 -4
  824. data/vendor/diy/test/files/cat/cat.rb +5 -4
  825. data/vendor/diy/test/files/cat/extra_conflict.yml +5 -4
  826. data/vendor/diy/test/files/cat/heritage.rb +5 -4
  827. data/vendor/diy/test/files/cat/needs_input.yml +5 -4
  828. data/vendor/diy/test/files/cat/the_cat_lineage.rb +5 -4
  829. data/vendor/diy/test/files/dog/dog_model.rb +5 -4
  830. data/vendor/diy/test/files/dog/dog_presenter.rb +5 -4
  831. data/vendor/diy/test/files/dog/dog_view.rb +5 -4
  832. data/vendor/diy/test/files/dog/file_resolver.rb +5 -4
  833. data/vendor/diy/test/files/dog/other_thing.rb +5 -4
  834. data/vendor/diy/test/files/dog/simple.yml +5 -4
  835. data/vendor/diy/test/files/donkey/foo/bar/qux.rb +5 -4
  836. data/vendor/diy/test/files/donkey/foo.rb +5 -4
  837. data/vendor/diy/test/files/factory/beef.rb +5 -4
  838. data/vendor/diy/test/files/factory/dog.rb +5 -4
  839. data/vendor/diy/test/files/factory/factory.yml +5 -4
  840. data/vendor/diy/test/files/factory/farm/llama.rb +5 -4
  841. data/vendor/diy/test/files/factory/farm/pork.rb +5 -4
  842. data/vendor/diy/test/files/factory/kitten.rb +5 -4
  843. data/vendor/diy/test/files/fud/objects.yml +5 -4
  844. data/vendor/diy/test/files/fud/toy.rb +5 -4
  845. data/vendor/diy/test/files/functions/attached_things_builder.rb +5 -4
  846. data/vendor/diy/test/files/functions/invalid_method.yml +5 -4
  847. data/vendor/diy/test/files/functions/method_extractor.rb +5 -4
  848. data/vendor/diy/test/files/functions/nonsingleton_objects.yml +5 -4
  849. data/vendor/diy/test/files/functions/objects.yml +5 -4
  850. data/vendor/diy/test/files/functions/thing.rb +5 -4
  851. data/vendor/diy/test/files/functions/thing_builder.rb +5 -4
  852. data/vendor/diy/test/files/functions/things_builder.rb +5 -4
  853. data/vendor/diy/test/files/gnu/objects.yml +5 -4
  854. data/vendor/diy/test/files/gnu/thinger.rb +5 -4
  855. data/vendor/diy/test/files/goat/base.rb +5 -4
  856. data/vendor/diy/test/files/goat/can.rb +5 -4
  857. data/vendor/diy/test/files/goat/goat.rb +5 -4
  858. data/vendor/diy/test/files/goat/objects.yml +5 -4
  859. data/vendor/diy/test/files/goat/paper.rb +5 -4
  860. data/vendor/diy/test/files/goat/plane.rb +5 -4
  861. data/vendor/diy/test/files/goat/shirt.rb +5 -4
  862. data/vendor/diy/test/files/goat/wings.rb +5 -4
  863. data/vendor/diy/test/files/horse/holder_thing.rb +5 -4
  864. data/vendor/diy/test/files/horse/objects.yml +5 -4
  865. data/vendor/diy/test/files/namespace/animal/bird.rb +5 -4
  866. data/vendor/diy/test/files/namespace/animal/cat.rb +5 -4
  867. data/vendor/diy/test/files/namespace/animal/reptile/hardshell/turtle.rb +5 -4
  868. data/vendor/diy/test/files/namespace/animal/reptile/lizard.rb +5 -4
  869. data/vendor/diy/test/files/namespace/bad_module_specified.yml +5 -4
  870. data/vendor/diy/test/files/namespace/class_name_combine.yml +5 -4
  871. data/vendor/diy/test/files/namespace/no_module_specified.yml +5 -4
  872. data/vendor/diy/test/files/namespace/objects.yml +5 -4
  873. data/vendor/diy/test/files/namespace/road.rb +5 -4
  874. data/vendor/diy/test/files/namespace/sky.rb +5 -4
  875. data/vendor/diy/test/files/namespace/subcontext.yml +5 -4
  876. data/vendor/diy/test/files/non_singleton/air.rb +5 -4
  877. data/vendor/diy/test/files/non_singleton/fat_cat.rb +5 -4
  878. data/vendor/diy/test/files/non_singleton/objects.yml +5 -4
  879. data/vendor/diy/test/files/non_singleton/pig.rb +5 -4
  880. data/vendor/diy/test/files/non_singleton/thread_spinner.rb +5 -4
  881. data/vendor/diy/test/files/non_singleton/tick.rb +5 -4
  882. data/vendor/diy/test/files/non_singleton/yard.rb +5 -4
  883. data/vendor/diy/test/files/yak/core_model.rb +5 -4
  884. data/vendor/diy/test/files/yak/core_presenter.rb +5 -4
  885. data/vendor/diy/test/files/yak/core_view.rb +5 -4
  886. data/vendor/diy/test/files/yak/data_source.rb +5 -4
  887. data/vendor/diy/test/files/yak/fringe_model.rb +5 -4
  888. data/vendor/diy/test/files/yak/fringe_presenter.rb +5 -4
  889. data/vendor/diy/test/files/yak/fringe_view.rb +5 -4
  890. data/vendor/diy/test/files/yak/giant_squid.rb +5 -4
  891. data/vendor/diy/test/files/yak/krill.rb +5 -4
  892. data/vendor/diy/test/files/yak/my_objects.yml +5 -4
  893. data/vendor/diy/test/files/yak/sub_sub_context_test.yml +5 -4
  894. data/vendor/diy/test/test_helper.rb +5 -4
  895. data/vendor/unity/auto/generate_module.rb +4 -4
  896. data/vendor/unity/auto/generate_test_runner.rb +5 -1
  897. data/vendor/unity/docs/UnityHelperScriptsGuide.md +9 -0
  898. data/vendor/unity/test/spec/generate_module_naming_spec.rb +38 -0
  899. data/vendor/unity/test/testdata/spi/MockConfig.h +19 -0
  900. data/vendor/unity/test/testdata/testRunnerGeneratorWithSameNamedMocks.c +42 -0
  901. data/vendor/unity/test/testdata/uart/MockConfig.h +19 -0
  902. data/vendor/unity/test/tests/test_generate_test_runner.rb +29 -0
  903. metadata +770 -287
  904. data/assets/tests_with_fallback_conditionals/src/conditional_module.c +0 -18
  905. data/bin/actions_wrapper.rb +0 -51
  906. data/docs/mkdocs/assets/images/ceedling-logo-circle.png +0 -0
  907. data/docs/mkdocs/assets/images/ceedling.svg +0 -90
  908. data/docs/mkdocs/assets/images/favicon.png +0 -0
  909. data/docs/mkdocs/assets/stylesheets/admonitions.css +0 -152
  910. data/docs/mkdocs/assets/stylesheets/fixes-local.css +0 -15
  911. data/docs/mkdocs/assets/stylesheets/styling.css +0 -102
  912. data/docs/mkdocs/configuration/environment-vars.md +0 -14
  913. data/docs/mkdocs/configuration/global-collections.md +0 -156
  914. data/docs/mkdocs/configuration/index.md +0 -75
  915. data/docs/mkdocs/configuration/loading.md +0 -89
  916. data/docs/mkdocs/configuration/mixins.md +0 -607
  917. data/docs/mkdocs/configuration/parallel-builds.md +0 -97
  918. data/docs/mkdocs/configuration/project-file.md +0 -216
  919. data/docs/mkdocs/configuration/reference/cexception.md +0 -35
  920. data/docs/mkdocs/configuration/reference/cmock.md +0 -106
  921. data/docs/mkdocs/configuration/reference/defines.md +0 -352
  922. data/docs/mkdocs/configuration/reference/environment.md +0 -55
  923. data/docs/mkdocs/configuration/reference/extension.md +0 -63
  924. data/docs/mkdocs/configuration/reference/files.md +0 -154
  925. data/docs/mkdocs/configuration/reference/flags.md +0 -296
  926. data/docs/mkdocs/configuration/reference/index.md +0 -176
  927. data/docs/mkdocs/configuration/reference/libraries.md +0 -82
  928. data/docs/mkdocs/configuration/reference/mixins.md +0 -24
  929. data/docs/mkdocs/configuration/reference/partials.md +0 -38
  930. data/docs/mkdocs/configuration/reference/paths.md +0 -276
  931. data/docs/mkdocs/configuration/reference/plugins.md +0 -60
  932. data/docs/mkdocs/configuration/reference/project.md +0 -333
  933. data/docs/mkdocs/configuration/reference/release-build.md +0 -62
  934. data/docs/mkdocs/configuration/reference/test-build.md +0 -55
  935. data/docs/mkdocs/configuration/reference/test-runner.md +0 -61
  936. data/docs/mkdocs/configuration/reference/tools.md +0 -457
  937. data/docs/mkdocs/configuration/reference/unity.md +0 -49
  938. data/docs/mkdocs/configuration/which-ceedling.md +0 -77
  939. data/docs/mkdocs/development/index.md +0 -61
  940. data/docs/mkdocs/development/plugins/configuration.md +0 -164
  941. data/docs/mkdocs/development/plugins/index.md +0 -84
  942. data/docs/mkdocs/development/plugins/plugin-subclass.md +0 -513
  943. data/docs/mkdocs/development/plugins/rake-tasks.md +0 -54
  944. data/docs/mkdocs/development/workflow.md +0 -284
  945. data/docs/mkdocs/getting-started/command-line.md +0 -477
  946. data/docs/mkdocs/getting-started/example-projects/cipher-quest.md +0 -65
  947. data/docs/mkdocs/getting-started/example-projects/index.md +0 -49
  948. data/docs/mkdocs/getting-started/example-projects/temp-sensor.md +0 -60
  949. data/docs/mkdocs/getting-started/example-projects/wondrous-forest.md +0 -45
  950. data/docs/mkdocs/getting-started/index.md +0 -41
  951. data/docs/mkdocs/getting-started/installation.md +0 -179
  952. data/docs/mkdocs/getting-started/quick-start.md +0 -86
  953. data/docs/mkdocs/help.md +0 -49
  954. data/docs/mkdocs/index.md +0 -222
  955. data/docs/mkdocs/overview/build-system.md +0 -115
  956. data/docs/mkdocs/overview/index.md +0 -29
  957. data/docs/mkdocs/overview/test-environments.md +0 -33
  958. data/docs/mkdocs/overview/tools-and-frameworks.md +0 -115
  959. data/docs/mkdocs/plugins/beep.md +0 -134
  960. data/docs/mkdocs/plugins/bullseye.md +0 -83
  961. data/docs/mkdocs/plugins/command-hooks.md +0 -268
  962. data/docs/mkdocs/plugins/compile-commands-json-db.md +0 -42
  963. data/docs/mkdocs/plugins/cppcheck.md +0 -377
  964. data/docs/mkdocs/plugins/dependencies.md +0 -310
  965. data/docs/mkdocs/plugins/fff.md +0 -247
  966. data/docs/mkdocs/plugins/gcov/examples.md +0 -92
  967. data/docs/mkdocs/plugins/gcov/gcovr.md +0 -526
  968. data/docs/mkdocs/plugins/gcov/index.md +0 -74
  969. data/docs/mkdocs/plugins/gcov/overview.md +0 -145
  970. data/docs/mkdocs/plugins/gcov/reportgenerator.md +0 -246
  971. data/docs/mkdocs/plugins/gcov/reporting.md +0 -147
  972. data/docs/mkdocs/plugins/gcov/setup.md +0 -232
  973. data/docs/mkdocs/plugins/gcov/tool-versions.md +0 -60
  974. data/docs/mkdocs/plugins/gcov/troubleshooting.md +0 -78
  975. data/docs/mkdocs/plugins/index.md +0 -261
  976. data/docs/mkdocs/plugins/module-generator.md +0 -267
  977. data/docs/mkdocs/plugins/report-build-warnings-log.md +0 -42
  978. data/docs/mkdocs/plugins/report-tests-gtestlike-stdout.md +0 -98
  979. data/docs/mkdocs/plugins/report-tests-ide-stdout.md +0 -63
  980. data/docs/mkdocs/plugins/report-tests-log-factory.md +0 -454
  981. data/docs/mkdocs/plugins/report-tests-pretty-stdout.md +0 -56
  982. data/docs/mkdocs/plugins/report-tests-raw-output-log.md +0 -52
  983. data/docs/mkdocs/plugins/report-tests-teamcity-stdout.md +0 -96
  984. data/docs/mkdocs/plugins/sample_html_report.png +0 -0
  985. data/docs/mkdocs/plugins/valgrind.md +0 -198
  986. data/docs/mkdocs/project/release-history.md +0 -61
  987. data/docs/mkdocs/project/upgrade.md +0 -85
  988. data/docs/mkdocs/reference/build-directives.md +0 -37
  989. data/docs/mkdocs/reference/command-line.md +0 -323
  990. data/docs/mkdocs/reference/environment-vars.md +0 -60
  991. data/docs/mkdocs/reference/gcov-plugin.md +0 -600
  992. data/docs/mkdocs/reference/global-collections.md +0 -160
  993. data/docs/mkdocs/reference/index.md +0 -65
  994. data/docs/mkdocs/reference/partials-macros.md +0 -79
  995. data/docs/mkdocs/reference/project-configuration.md +0 -46
  996. data/docs/mkdocs/snapshot/examples/cipher_quest/README.md +0 -210
  997. data/docs/mkdocs/snapshot/examples/temp_sensor/README.md +0 -283
  998. data/docs/mkdocs/snapshot/examples/wondrous_forest/README.md +0 -92
  999. data/docs/mkdocs/snapshot/plugins/gcov/config/defaults.yml +0 -32
  1000. data/docs/mkdocs/snapshot/plugins/gcov/config/defaults_gcov.rb +0 -136
  1001. data/docs/mkdocs/snapshot.yml +0 -20
  1002. data/docs/mkdocs/testing-guide/build-directives.md +0 -153
  1003. data/docs/mkdocs/testing-guide/conventions.md +0 -616
  1004. data/docs/mkdocs/testing-guide/frameworks.md +0 -192
  1005. data/docs/mkdocs/testing-guide/index.md +0 -80
  1006. data/docs/mkdocs/testing-guide/partials/configuration.md +0 -67
  1007. data/docs/mkdocs/testing-guide/partials/conventions.md +0 -68
  1008. data/docs/mkdocs/testing-guide/partials/directives.md +0 -212
  1009. data/docs/mkdocs/testing-guide/partials/example.md +0 -149
  1010. data/docs/mkdocs/testing-guide/partials/index.md +0 -88
  1011. data/docs/mkdocs/testing-guide/partials/overview.md +0 -81
  1012. data/docs/mkdocs/testing-guide/partials/variables.md +0 -244
  1013. data/docs/mkdocs/testing-guide/test-cases.md +0 -194
  1014. data/docs/mkdocs/testing-guide/test-sample.md +0 -94
  1015. data/docs/mkdocs/testing-guide/test-suite-anatomy.md +0 -58
  1016. data/lib/ceedling/cacheinator.rb +0 -53
  1017. data/lib/ceedling/cacheinator_helper.rb +0 -60
  1018. data/lib/ceedling/dependinator.rb +0 -31
  1019. data/lib/ceedling/makefile.rb +0 -52
  1020. data/lib/ceedling/release_invoker.rb +0 -112
  1021. data/lib/ceedling/rules_release.rake +0 -109
  1022. data/lib/ceedling/rules_tests.rake +0 -40
  1023. data/lib/ceedling/tasks_release.rake +0 -36
  1024. data/plugins/fff/vendor/fff/Makefile +0 -10
  1025. data/plugins/fff/vendor/fff/buildandtest +0 -15
  1026. data/plugins/fff/vendor/fff/examples/Makefile +0 -7
  1027. data/plugins/fff/vendor/fff/examples/driver_testing/Makefile +0 -64
  1028. data/plugins/fff/vendor/fff/examples/driver_testing/driver.c +0 -32
  1029. data/plugins/fff/vendor/fff/examples/driver_testing/driver.h +0 -21
  1030. data/plugins/fff/vendor/fff/examples/driver_testing/driver.test.cpp +0 -58
  1031. data/plugins/fff/vendor/fff/examples/driver_testing/driver.test.fff.cpp +0 -70
  1032. data/plugins/fff/vendor/fff/examples/driver_testing/hardware_abstraction.h +0 -25
  1033. data/plugins/fff/vendor/fff/examples/driver_testing/registers.h +0 -23
  1034. data/plugins/fff/vendor/fff/examples/embedded_ui/DISPLAY.h +0 -27
  1035. data/plugins/fff/vendor/fff/examples/embedded_ui/Kata.txt +0 -25
  1036. data/plugins/fff/vendor/fff/examples/embedded_ui/Makefile +0 -67
  1037. data/plugins/fff/vendor/fff/examples/embedded_ui/SYSTEM.h +0 -31
  1038. data/plugins/fff/vendor/fff/examples/embedded_ui/UI.c +0 -56
  1039. data/plugins/fff/vendor/fff/examples/embedded_ui/UI.h +0 -22
  1040. data/plugins/fff/vendor/fff/examples/embedded_ui/UI_test_ansic.c +0 -191
  1041. data/plugins/fff/vendor/fff/examples/embedded_ui/UI_test_cpp.cpp +0 -144
  1042. data/plugins/fff/vendor/fff/examples/embedded_ui/test_suite_template.c +0 -42
  1043. data/plugins/fff/vendor/fff/gtest/Makefile +0 -22
  1044. data/plugins/fff/vendor/fff/gtest/gtest-all.cc +0 -9118
  1045. data/plugins/fff/vendor/fff/gtest/gtest-main.cc +0 -6
  1046. data/plugins/fff/vendor/fff/gtest/gtest.h +0 -19547
  1047. data/plugins/fff/vendor/fff/test/Makefile +0 -81
  1048. data/plugins/fff/vendor/fff/test/c_test_framework.h +0 -25
  1049. data/plugins/fff/vendor/fff/test/fff_test_c.c +0 -116
  1050. data/plugins/fff/vendor/fff/test/fff_test_cpp.cpp +0 -53
  1051. data/plugins/fff/vendor/fff/test/fff_test_global_c.c +0 -84
  1052. data/plugins/fff/vendor/fff/test/fff_test_global_cpp.cpp +0 -31
  1053. data/plugins/fff/vendor/fff/test/global_fakes.c +0 -21
  1054. data/plugins/fff/vendor/fff/test/global_fakes.h +0 -47
  1055. data/plugins/fff/vendor/fff/test/test_cases.include +0 -276
  1056. data/plugins/report_tests_gtestlike_stdout/assets/template.erb +0 -83
  1057. data/site-local/snapshot/assets/project.yml +0 -404
  1058. data/spec/system/partials_types_header_spec.rb +0 -166
  1059. data/spec/units/configurator_spec.rb +0 -232
  1060. /data/assets/{ceedling → features/ceedling} +0 -0
  1061. /data/assets/{ceedling.cmd → features/ceedling.cmd} +0 -0
  1062. /data/assets/{default_gitignore → features/default_gitignore} +0 -0
  1063. /data/assets/{broken_uncovered_file.c → fixtures/broken_uncovered_file.c} +0 -0
  1064. /data/assets/{example_file.c → fixtures/example_file.c} +0 -0
  1065. /data/assets/{example_file.h → fixtures/example_file.h} +0 -0
  1066. /data/assets/{example_file_call.c → fixtures/example_file_call.c} +0 -0
  1067. /data/assets/{example_file_call.h → fixtures/example_file_call.h} +0 -0
  1068. /data/assets/{example_file_with_statics.c → fixtures/example_file_with_statics.c} +0 -0
  1069. /data/assets/{example_file_with_stdio.c → fixtures/example_file_with_stdio.c} +0 -0
  1070. /data/assets/{example_file_with_stdio.h → fixtures/example_file_with_stdio.h} +0 -0
  1071. /data/assets/{fake_crash_test_fixture.rb → fixtures/fake_crash_test_fixture.rb} +0 -0
  1072. /data/assets/{partial_all_module.h → fixtures/partial_all_module.h} +0 -0
  1073. /data/assets/{run_with_ubsan.rb → fixtures/run_with_ubsan.rb} +0 -0
  1074. /data/assets/{same_dir_pairing_module.c → fixtures/same_dir_pairing_module.c} +0 -0
  1075. /data/assets/{same_dir_pairing_module.h → fixtures/same_dir_pairing_module.h} +0 -0
  1076. /data/assets/{same_dir_pairing_module_func.h → fixtures/same_dir_pairing_module_func.h} +0 -0
  1077. /data/assets/{same_dir_pairing_other.c → fixtures/same_dir_pairing_other.c} +0 -0
  1078. /data/assets/{same_dir_pairing_other.h → fixtures/same_dir_pairing_other.h} +0 -0
  1079. /data/assets/{test_example_file.c → fixtures/test_example_file.c} +0 -0
  1080. /data/assets/{test_example_file_2.c → fixtures/test_example_file_2.c} +0 -0
  1081. /data/assets/{test_example_file_source_include.c → fixtures/test_example_file_source_include.c} +0 -0
  1082. /data/assets/{test_example_file_success.c → fixtures/test_example_file_success.c} +0 -0
  1083. /data/assets/{test_example_file_unity_printf.c → fixtures/test_example_file_unity_printf.c} +0 -0
  1084. /data/assets/{test_example_file_verbose.c → fixtures/test_example_file_verbose.c} +0 -0
  1085. /data/assets/{test_example_file_with_mock.c → fixtures/test_example_file_with_mock.c} +0 -0
  1086. /data/assets/{test_example_file_with_stdio.c → fixtures/test_example_file_with_stdio.c} +0 -0
  1087. /data/assets/{test_example_with_parameterized_tests.c → fixtures/test_example_with_parameterized_tests.c} +0 -0
  1088. /data/assets/{test_partial_all_module.c → fixtures/test_partial_all_module.c} +0 -0
  1089. /data/assets/{test_same_dir_pairing.c → fixtures/test_same_dir_pairing.c} +0 -0
  1090. /data/assets/{tests_with_conditional_includes → fixtures/tests_with_conditional_includes}/src/feature_config.h +0 -0
  1091. /data/assets/{tests_with_conditional_includes → fixtures/tests_with_conditional_includes}/src/feature_extra.h +0 -0
  1092. /data/assets/{tests_with_conditional_includes → fixtures/tests_with_conditional_includes}/src/local_flag_extra.h +0 -0
  1093. /data/assets/{tests_with_conditional_includes → fixtures/tests_with_conditional_includes}/src/nested_extra.h +0 -0
  1094. /data/assets/{tests_with_conditional_includes → fixtures/tests_with_conditional_includes}/src/nested_wrapper.h +0 -0
  1095. /data/assets/{tests_with_conditional_includes → fixtures/tests_with_conditional_includes}/src/project_flag_extra.h +0 -0
  1096. /data/assets/{tests_with_conditional_includes → fixtures/tests_with_conditional_includes}/src/widget_feature.h +0 -0
  1097. /data/assets/{tests_with_defines → fixtures/tests_with_defines}/src/adc_hardware.c +0 -0
  1098. /data/assets/{tests_with_defines → fixtures/tests_with_defines}/src/adc_hardware.h +0 -0
  1099. /data/assets/{tests_with_defines → fixtures/tests_with_defines}/src/adc_hardware_configurator.c +0 -0
  1100. /data/assets/{tests_with_defines → fixtures/tests_with_defines}/src/adc_hardware_configurator.h +0 -0
  1101. /data/assets/{tests_with_defines → fixtures/tests_with_defines}/test/test_adc_hardware.c +0 -0
  1102. /data/assets/{tests_with_defines → fixtures/tests_with_defines}/test/test_adc_hardware_special.c +0 -0
  1103. /data/assets/{tests_with_encoding → fixtures/tests_with_encoding}/src/unicoder.c +0 -0
  1104. /data/assets/{tests_with_encoding → fixtures/tests_with_encoding}/src/unicoder.h +0 -0
  1105. /data/assets/{tests_with_encoding → fixtures/tests_with_encoding}/test/test_unicoder.c +0 -0
  1106. /data/assets/{tests_with_encoding → fixtures/tests_with_encoding}/test/test_unicoder_partial.c +0 -0
  1107. /data/assets/{tests_with_fallback_conditionals → fixtures/tests_with_fallback_conditionals}/src/conditional_module.h +0 -0
  1108. /data/assets/{tests_with_fallback_conditionals → fixtures/tests_with_fallback_conditionals}/src/optional_dep.h +0 -0
  1109. /data/assets/{tests_with_partials_coverage → fixtures/tests_with_partials_coverage}/src/blanks.c +0 -0
  1110. /data/assets/{tests_with_partials_coverage → fixtures/tests_with_partials_coverage}/src/blanks.h +0 -0
  1111. /data/assets/{tests_with_partials_coverage → fixtures/tests_with_partials_coverage}/src/counter.c +0 -0
  1112. /data/assets/{tests_with_partials_coverage → fixtures/tests_with_partials_coverage}/src/counter.h +0 -0
  1113. /data/assets/{tests_with_partials_coverage → fixtures/tests_with_partials_coverage}/src/decorators.c +0 -0
  1114. /data/assets/{tests_with_partials_coverage → fixtures/tests_with_partials_coverage}/src/decorators.h +0 -0
  1115. /data/assets/{tests_with_partials_coverage → fixtures/tests_with_partials_coverage}/test/test_blanks.c +0 -0
  1116. /data/assets/{tests_with_partials_coverage → fixtures/tests_with_partials_coverage}/test/test_counter.c +0 -0
  1117. /data/assets/{tests_with_partials_coverage → fixtures/tests_with_partials_coverage}/test/test_decorators.c +0 -0
  1118. /data/assets/{tests_with_preprocessing → fixtures/tests_with_preprocessing}/src/adc_hardwareA.c +0 -0
  1119. /data/assets/{tests_with_preprocessing → fixtures/tests_with_preprocessing}/src/adc_hardwareA.h +0 -0
  1120. /data/assets/{tests_with_preprocessing → fixtures/tests_with_preprocessing}/src/adc_hardwareB.c +0 -0
  1121. /data/assets/{tests_with_preprocessing → fixtures/tests_with_preprocessing}/src/adc_hardwareB.h +0 -0
  1122. /data/assets/{tests_with_preprocessing → fixtures/tests_with_preprocessing}/src/adc_hardwareC.c +0 -0
  1123. /data/assets/{tests_with_preprocessing → fixtures/tests_with_preprocessing}/src/adc_hardwareC.h +0 -0
  1124. /data/assets/{tests_with_preprocessing → fixtures/tests_with_preprocessing}/src/adc_hardware_configuratorA.h +0 -0
  1125. /data/assets/{tests_with_preprocessing → fixtures/tests_with_preprocessing}/src/adc_hardware_configuratorB.h +0 -0
  1126. /data/assets/{tests_with_preprocessing → fixtures/tests_with_preprocessing}/src/adc_hardware_configuratorC.h +0 -0
  1127. /data/assets/{tests_with_preprocessing → fixtures/tests_with_preprocessing}/test/test_adc_hardwareA.c +0 -0
  1128. /data/assets/{tests_with_preprocessing → fixtures/tests_with_preprocessing}/test/test_adc_hardwareB.c +0 -0
  1129. /data/assets/{tests_with_preprocessing → fixtures/tests_with_preprocessing}/test/test_adc_hardwareC.c +0 -0
  1130. /data/assets/{uncovered_example_file.c → fixtures/uncovered_example_file.c} +0 -0
  1131. /data/plugins/bullseye/assets/{template.erb → coverage.template} +0 -0
data/Rakefile CHANGED
@@ -11,6 +11,55 @@ require 'rspec/core/rake_task'
11
11
  require 'fileutils'
12
12
  require 'open3'
13
13
 
14
+ ##
15
+ ## Shared task helpers
16
+ ##
17
+
18
+ # Several Gemfile entries are declared with `install_if:`. That predicate is
19
+ # Bundler's runtime activation check as well as its install-time one, so a gated
20
+ # gem is invisible to this process no matter what is installed. Bundler fixed this
21
+ # process's load path at boot, before this Rakefile assigned anything. Tasks that
22
+ # need a gated gem therefore run it in a child process through this helper.
23
+ #
24
+ # with_unbundled_env strips the parent's Bundler environment, including the
25
+ # RUBYOPT=-rbundler/setup that `bundle exec` exports. Without that strip, a nested
26
+ # bundler command boots bundler/setup first, validates the whole dependency set,
27
+ # and dies on the gated gems before doing any work. The variables are seeded
28
+ # *inside* the block because with_unbundled_env restores ENV from the snapshot
29
+ # Bundler captured at load time, which predates anything assigned here.
30
+ #
31
+ # The command is yielded untouched and the block's value is returned. One helper
32
+ # therefore serves both `sh` callers, which raise, and `system` callers, which want
33
+ # the boolean. Yielding the string unsplit is also what preserves shell
34
+ # redirections in a caller's command.
35
+ def unbundled_sh(env, cmd)
36
+ Bundler.with_unbundled_env do
37
+ env.each { |name, value| ENV[name] = value }
38
+ yield cmd
39
+ end
40
+ end
41
+
42
+ # Marker separating a development checkout from an installed gem. The release gem
43
+ # deliberately ships this Rakefile, the Gemfile, and spec/ so external tooling can
44
+ # self-test the packaged gem. It carries none of the repository's own development
45
+ # files. `.gitmodules` is the sturdiest marker available: ceedling.gemspec builds
46
+ # its file list with Dir['**/*'], which skips dotfiles, and the few dotfiles added
47
+ # back are named one by one.
48
+ REPO_MARKER = File.join(__dir__, '.gitmodules')
49
+
50
+ # Tasks that cannot work outside the repository say so plainly rather than failing
51
+ # later on a missing file. __dir__ rather than Dir.pwd, since profile:run calls
52
+ # this from inside a Dir.chdir block.
53
+ def repo_only!(task)
54
+ return if File.exist?( REPO_MARKER )
55
+
56
+ raise "'#{task}' only runs from a Ceedling repository checkout.\n" \
57
+ "The released gem ships this Rakefile but none of the development files " \
58
+ "this task needs.\n" \
59
+ "Tasks that do work from an installed gem: specs:units, specs:integration, " \
60
+ "specs:system, and coverage:report."
61
+ end
62
+
14
63
  ##
15
64
  ## Testing tasks
16
65
  ##
@@ -19,21 +68,39 @@ require 'open3'
19
68
  # Most CI systems (GitHub Actions, GitLab CI, CircleCI, etc.) set CI=true automatically.
20
69
  RSPEC_FORMAT = ENV['CI_RSPEC_PROGRESS_FORMAT'] ? '--format progress' : '--format documentation'
21
70
 
71
+ # CI_RESULTS_DIR names where a suite also writes RSpec's JSON results, which the CI
72
+ # summary reads for its counts. Unset, a suite writes only its console output.
73
+ def rspec_opts_for(suite)
74
+ results_dir = ENV['CI_RESULTS_DIR'].to_s
75
+ return RSPEC_FORMAT if results_dir.empty?
76
+
77
+ return "#{RSPEC_FORMAT} --format json --out #{File.join( results_dir, "#{suite}.json" )}"
78
+ end
79
+
22
80
  desc "Run unit specs only"
23
81
  RSpec::Core::RakeTask.new('specs:units') do |t|
24
82
  t.pattern = 'spec/units/**/*_spec.rb'
25
- t.rspec_opts = RSPEC_FORMAT
83
+ t.rspec_opts = rspec_opts_for( 'units' )
84
+ end
85
+
86
+ # Integration specs sit between units and system: they compose real lib/ceedling
87
+ # objects and shell out to real tools (gcc), but exercise a single subsystem end
88
+ # to end rather than driving a whole `ceedling` build the way system specs do.
89
+ desc "Run integration specs only"
90
+ RSpec::Core::RakeTask.new('specs:integration') do |t|
91
+ t.pattern = 'spec/integration/**/*_spec.rb'
92
+ t.rspec_opts = rspec_opts_for( 'integration' )
26
93
  end
27
94
 
28
95
  desc "Run system specs only"
29
96
  RSpec::Core::RakeTask.new('specs:system') do |t|
30
97
  t.pattern = 'spec/system/**/*_spec.rb'
31
- t.rspec_opts = RSPEC_FORMAT
98
+ t.rspec_opts = rspec_opts_for( 'system' )
32
99
  end
33
100
 
34
- # Run unit tests first to fail on fast before running slower system tests
35
- desc "Run all specs: units first then system (non-debug)"
36
- task 'specs:all' => ['specs:units', 'specs:system']
101
+ # Ordered fastest to slowest so a failure surfaces as early as possible.
102
+ desc "Run all specs: units, then integration, then system (non-debug)"
103
+ task 'specs:all' => ['specs:units', 'specs:integration', 'specs:system']
37
104
 
38
105
  # CI batch debug mode: run all system specs, keeping only failure artifacts.
39
106
  # Passing project directories are deleted immediately; passing logs are never written.
@@ -43,6 +110,153 @@ task 'specs:system:debug' do
43
110
  Rake::Task['specs:system'].invoke
44
111
  end
45
112
 
113
+ # Dynamic analysis of the C Ceedling itself generates -- test runners, mocks,
114
+ # Partials -- plus the example projects. Each task selects a sanitizer flavor,
115
+ # which is a file in spec/support/system/sanitizers/; the harness turns that into
116
+ # a Ceedling mixin and the sanitizer's runtime options (see SystemContext).
117
+ #
118
+ # Set the variable and invoke the existing task, exactly as specs:system:debug
119
+ # above does, so a developer here and CI run identical wiring rather than two
120
+ # arrangements that can drift. CI instruments one matrix leg only (Linux, Ruby
121
+ # 3.5): instrumentation roughly doubles build time, and a sanitizer finding in
122
+ # generated code appears on every leg equally, so paying for it more than once
123
+ # buys nothing.
124
+ #
125
+ # Fixtures that fault on purpose are excluded by name -- see
126
+ # spec/support/system/sanitizers/asan_ubsan.yml.
127
+ #
128
+ # This flavor leaves leak detection off; specs:system:sanitize:leaks below is what
129
+ # CI runs. Reach for this one to tell a leak from a memory error or UB.
130
+ desc "Run all system specs with ASan+UBSan, leak detection off (triage)"
131
+ task 'specs:system:sanitize' do
132
+ ENV['CEEDLING_TEST_SANITIZERS'] = 'asan_ubsan'
133
+ Rake::Task['specs:system:debug'].invoke
134
+ end
135
+
136
+ # What CI runs. Leak detection was measured clean across the whole suite before
137
+ # being enabled -- see spec/support/system/sanitizers/asan_ubsan_leaks.yml.
138
+ desc "Run all system specs with ASan+UBSan and leak detection (what CI runs)"
139
+ task 'specs:system:sanitize:leaks' do
140
+ ENV['CEEDLING_TEST_SANITIZERS'] = 'asan_ubsan_leaks'
141
+ Rake::Task['specs:system:debug'].invoke
142
+ end
143
+
144
+ # Formats four HTML reports -- units alone, integration alone, system alone, and all
145
+ # combined -- from the raw coverage data that CEEDLING_TEST_COVERAGE test runs
146
+ # accumulate (see .simplecov and spec/support/system/simplecov_boot.rb). Run after
147
+ # `specs:units`, `specs:integration`, and `specs:system`/`specs:system:debug` have
148
+ # completed with that env var set -- this task only reads back what they already
149
+ # wrote, it doesn't run any specs itself. Sources, one per report:
150
+ # units -- coverage/.resultset.json, written directly by the one unit-test
151
+ # process (spec_helper.rb)
152
+ # integration -- coverage/raw/integration/.resultset.json, written directly by the
153
+ # one integration-test process (spec_helper.rb, its own coverage_dir)
154
+ # system -- coverage/raw/system-<pid>-<timestamp>/.resultset.json, one small
155
+ # file per system-test child process (simplecov_boot.rb). Each
156
+ # process gets its own file rather than all sharing one growing
157
+ # coverage/.resultset.json -- sharing one file means every single
158
+ # process's exit re-reads, re-merges, and rewrites the *entire*
159
+ # accumulated file so far, a cost that grows with every process
160
+ # that ran before it and compounds across a full system-test run.
161
+ # merge_results below reads each small file once, the same
162
+ # approach SimpleCov itself recommends for "big CI setups" with
163
+ # many result files.
164
+ # combined -- the units file plus the integration file plus every system file
165
+ #
166
+ # `require 'simplecov'` here briefly starts SimpleCov for this task's own process
167
+ # too (via .simplecov's own autoload) -- overriding at_exit to a no-op keeps that
168
+ # process's own trivial self-coverage from being written anywhere at all, since
169
+ # this task reformats coverage_dir multiple times over its own run and has
170
+ # nothing of its own worth preserving.
171
+ desc "Merge and format units-only, integration-only, system-only, and combined SimpleCov coverage reports"
172
+ task 'coverage:report' do
173
+ require 'simplecov'
174
+ require_relative 'tools/coverage/report_label'
175
+ SimpleCov.at_exit { }
176
+
177
+ units_file = File.join('coverage', '.resultset.json')
178
+ integration_files = Dir[File.join('coverage', 'raw', 'integration', '.resultset.json')]
179
+ system_files = Dir[File.join('coverage', 'raw', 'system-*', '.resultset.json')]
180
+
181
+ raise "No coverage data found under coverage/ -- " \
182
+ "run specs:units, specs:integration, and specs:system with CEEDLING_TEST_COVERAGE set first" \
183
+ if !File.exist?(units_file) && integration_files.empty? && system_files.empty?
184
+
185
+ units_files = File.exist?(units_file) ? [units_file] : []
186
+
187
+ # Resultsets merged from each suite, which name each report's runs
188
+ suite_runs = { 'units' => units_files.size, 'integration' => integration_files.size, 'system' => system_files.size }
189
+
190
+ reports = {
191
+ 'units' => units_files,
192
+ 'integration' => integration_files,
193
+ 'system' => system_files,
194
+ 'combined' => units_files + integration_files + system_files
195
+ }
196
+
197
+ summary = {}
198
+ line_hits = nil
199
+
200
+ reports.each do |label, files|
201
+ if files.empty?
202
+ want = label == 'combined' ? 'units/integration/system' : label
203
+ puts "Skipping #{label} report -- no matching coverage data (run with CEEDLING_TEST_COVERAGE=#{want} first)"
204
+ next
205
+ end
206
+
207
+ # ignore_timeout: SimpleCov's default 10-minute merge_timeout exists to keep
208
+ # live, in-process merges from combining coverage across unrelated runs -- it
209
+ # doesn't apply here, where every file being merged is one CI step's already-
210
+ # finished output, deliberately read back after the fact (the same reasoning
211
+ # SimpleCov.collate's own API uses this same override for). Without it, a
212
+ # system-test suite that legitimately runs longer than 10 minutes leaves the
213
+ # early "units" file (and any early "system" files) older than the cutoff by
214
+ # the time this task runs last, so they'd get silently dropped -- for units
215
+ # alone (only ever one file) that's a full wipeout, nil coverage, and a crash
216
+ # in HTMLFormatter#format on a nil result.
217
+ result = SimpleCov::ResultMerger.merge_results(*files, ignore_timeout: true)
218
+
219
+ # A merged result is named with every merged run's own name, and the system suite
220
+ # records hundreds of runs. The report prints that name in the footer of every
221
+ # source file view, where it buries the source, so each report names its suites.
222
+ result.command_name = CoverageReportLabel.for( label == 'combined' ? suite_runs : suite_runs.slice( label ) )
223
+
224
+ SimpleCov.coverage_dir(File.join('coverage', label))
225
+ # silent: true suppresses SimpleCov's own "Coverage report generated for
226
+ # <command_name> to ..." status line. The concise line this task prints next
227
+ # says the same with coverage figures.
228
+ SimpleCov::Formatter::HTMLFormatter.new(silent: true).format(result)
229
+ puts "#{label.capitalize} coverage: #{result.covered_percent.round(2)}% " \
230
+ "(#{result.covered_lines}/#{result.total_lines} lines)"
231
+
232
+ summary[label] = { 'covered' => result.covered_lines, 'total' => result.total_lines }
233
+ line_hits = combined_line_hits( result ) if label == 'combined'
234
+ end
235
+
236
+ write_ci_coverage( summary, line_hits )
237
+ end
238
+
239
+ # The combined result's per-line hit counts, keyed by repository-relative path, for
240
+ # the CI summary's diff coverage. A nil entry is a line Ruby never counts.
241
+ def combined_line_hits(result)
242
+ root = "#{SimpleCov.root}/"
243
+ return result.original_result.to_h do |path, coverage|
244
+ [path.delete_prefix( root ), coverage.is_a?( Hash ) ? coverage['lines'] : coverage]
245
+ end
246
+ end
247
+
248
+ # Per-suite line counts, plus the combined line hits, for the CI summary. Written only
249
+ # when CI_RESULTS_DIR names a destination.
250
+ def write_ci_coverage(summary, line_hits)
251
+ results_dir = ENV['CI_RESULTS_DIR'].to_s
252
+ return if results_dir.empty?
253
+
254
+ require 'json'
255
+ FileUtils.mkdir_p( results_dir )
256
+ File.write( File.join( results_dir, 'coverage.json' ), JSON.generate( summary ) )
257
+ File.write( File.join( results_dir, 'line_hits.json' ), JSON.generate( line_hits ) ) unless line_hits.nil?
258
+ end
259
+
46
260
  # Individual unit specs
47
261
  Dir['spec/units/**/*_spec.rb'].each do |p|
48
262
  base = File.basename(p,'.*').gsub('_spec','')
@@ -53,6 +267,16 @@ Dir['spec/units/**/*_spec.rb'].each do |p|
53
267
  end
54
268
  end
55
269
 
270
+ # Individual integration specs
271
+ Dir['spec/integration/**/*_spec.rb'].each do |p|
272
+ base = File.basename(p,'.*').gsub('_spec','')
273
+ desc "Run integration spec: #{base}"
274
+ RSpec::Core::RakeTask.new("spec:integration:#{base}") do |t|
275
+ t.pattern = p
276
+ t.rspec_opts = '--format documentation'
277
+ end
278
+ end
279
+
56
280
  # Individual system specs
57
281
  Dir['spec/system/**/*_spec.rb'].each do |p|
58
282
  base = File.basename(p,'.*').gsub('_spec','')
@@ -63,8 +287,12 @@ Dir['spec/system/**/*_spec.rb'].each do |p|
63
287
  end
64
288
  end
65
289
 
66
- # Individual system specs with full artifact retention (unadvertised).
67
- # Developer debug mode: preserve all artifacts — both pass and fail project directories and logs
290
+ # Individual system specs with full artifact retention. Developer debug mode:
291
+ # preserve all artifacts, both pass and fail project directories and logs.
292
+ #
293
+ # Deliberately undescribed one by one. There are forty of them, and advertising
294
+ # each would bury every other task in `rake -T`. The wildcard task below carries
295
+ # one description for the whole family.
68
296
  Dir['spec/system/**/*_spec.rb'].each do |p|
69
297
  base = File.basename(p,'.*').gsub('_spec','')
70
298
  task "spec:system:debug:#{base}" do
@@ -73,24 +301,68 @@ Dir['spec/system/**/*_spec.rb'].each do |p|
73
301
  end
74
302
  end
75
303
 
304
+ # Stand-in that documents the family above. It is a signpost in `rake -T` rather
305
+ # than something to run, so the description says what to put in place of the
306
+ # wildcard. The same technique carries the `test:*` and `gen:mocks:*` placeholders
307
+ # in lib/ceedling/rakefiles/.
308
+ desc "Run a system spec, retaining all artifacts (replace [*] with spec name)."
309
+ task 'spec:system:debug:*' do
310
+ message = "Oops! 'spec:system:debug:*' isn't a real task. " \
311
+ "Use a real system spec name in place of the wildcard.\n" \
312
+ "Example: `rake spec:system:debug:cli_surface`\n" \
313
+ "Run `rake -AT spec:system:debug` to list every available name.\n" \
314
+ "Artifact locations are printed when the suite starts."
315
+
316
+ $stderr.puts message
317
+ end
318
+
319
+ # Individual system specs under ASan+UBSan. Triage, not routine: when CI's
320
+ # instrumented leg reports a finding, chasing it in the one spec that produced it
321
+ # beats re-running the whole suite at roughly double build time.
322
+ #
323
+ # Undescribed one by one for the same reason as the debug family above -- the
324
+ # wildcard task below documents the whole family.
325
+ # Matches the flavor CI runs, so a finding reproduces here rather than changing
326
+ # shape. Switch to specs:system:sanitize above to ask whether it was a leak.
327
+ Dir['spec/system/**/*_spec.rb'].each do |p|
328
+ base = File.basename(p,'.*').gsub('_spec','')
329
+ task "spec:system:sanitize:#{base}" do
330
+ ENV['CEEDLING_TEST_SANITIZERS'] = 'asan_ubsan_leaks'
331
+ ENV['CEEDLING_SYSTEM_TEST_KEEP'] = 'all'
332
+ Rake::Task["spec:system:#{base}"].invoke
333
+ end
334
+ end
335
+
336
+ desc "Run a system spec with ASan+UBSan instrumentation (replace [*] with spec name)."
337
+ task 'spec:system:sanitize:*' do
338
+ message = "Oops! 'spec:system:sanitize:*' isn't a real task. " \
339
+ "Use a real system spec name in place of the wildcard.\n" \
340
+ "Example: `rake spec:system:sanitize:cli_surface`\n" \
341
+ "Run `rake -AT spec:system:sanitize` to list every available name.\n" \
342
+ "Requires a real GCC with ASan+UBSan support -- on macOS, run inside " \
343
+ "throwtheswitch/madsciencelab-plugins."
344
+
345
+ $stderr.puts message
346
+ end
347
+
76
348
  desc "Run specs by filename matching a substring (e.g., rake \"spec:filter:filename[<substring>]\")"
77
349
  RSpec::Core::RakeTask.new('spec:filter:filename', [:pattern]) do |t, args|
78
350
  pattern = args[:pattern] || '*'
79
- t.pattern = "spec/{units,system}/**/*#{pattern}*_spec.rb"
351
+ t.pattern = "spec/{units,integration,system}/**/*#{pattern}*_spec.rb"
80
352
  t.rspec_opts = '--format documentation'
81
353
  end
82
354
 
83
355
  desc "Run specs matching an example's description (e.g., rake \"spec:filter:example[Version reporting]\")"
84
356
  RSpec::Core::RakeTask.new('spec:filter:example', [:description]) do |t, args|
85
357
  description = args[:description] || ''
86
- t.pattern = 'spec/{units,system}/**/*_spec.rb'
358
+ t.pattern = 'spec/{units,integration,system}/**/*_spec.rb'
87
359
  t.rspec_opts = "--format documentation --example '#{description}'"
88
360
  end
89
361
 
90
362
  desc "Run specs whose example's description matches a regex pattern (e.g., rake \"spec:filter:match[version|help]\")"
91
363
  RSpec::Core::RakeTask.new('spec:filter:match', [:regex]) do |t, args|
92
364
  regex = args[:regex] || ''
93
- t.pattern = 'spec/{units,system}/**/*_spec.rb'
365
+ t.pattern = 'spec/{units,integration,system}/**/*_spec.rb'
94
366
  t.rspec_opts = "--format documentation --pattern '#{regex}'"
95
367
  end
96
368
 
@@ -101,11 +373,464 @@ end
101
373
  task :default => ['specs:all']
102
374
  task :ci => [:no_color, :default]
103
375
 
376
+ ##
377
+ ## Gem tasks
378
+ ##
379
+ ## Build the release gem the same way CI does, for inspecting what actually gets
380
+ ## packaged. ceedling.gemspec assembles its file list by sweeping the working tree
381
+ ## with Dir['**/*'], so a local build reflects whatever is lying around -- which is
382
+ ## most of the reason to run one by hand.
383
+ ##
384
+
385
+ desc "Remove built Ceedling gems from the repository root"
386
+ task 'gem:clean' do
387
+ repo_only!( 'gem:clean' )
388
+
389
+ gems = Dir[ File.join( __dir__, 'ceedling-*.gem' ) ]
390
+
391
+ if gems.empty?
392
+ puts "No built gems to remove."
393
+ next
394
+ end
395
+
396
+ # Named as they go, since a developer may have kept one deliberately for
397
+ # comparison against a new build.
398
+ gems.each do |path|
399
+ puts "Removing #{File.basename( path )}"
400
+ FileUtils.rm_f( path )
401
+ end
402
+ end
403
+
404
+ desc "Build the Ceedling gem into the repository root"
405
+ task 'gem:build' => 'gem:clean' do
406
+ repo_only!( 'gem:build' )
407
+
408
+ # The gemspec's file sweep has no *.gem exclusion, so a gem left from an earlier
409
+ # build would be packaged inside the next one. The gem:clean dependency is what
410
+ # prevents that.
411
+ #
412
+ # Invoked exactly as CI invokes it, with no --output, so the artifact lands in
413
+ # the repository root where CI's own `ceedling-*.gem` upload glob expects it.
414
+ sh 'gem build ceedling.gemspec'
415
+
416
+ $LOAD_PATH.unshift( File.join( __dir__, 'lib' ) )
417
+ require 'version'
418
+ expected = "ceedling-#{Ceedling::Version::GEM}.gem"
419
+
420
+ # Asserted rather than pinned with --output. A mismatch means lib/version.rb and
421
+ # the built gem disagree, which pinning the name would hide.
422
+ unless File.exist?( File.join( __dir__, expected ) )
423
+ raise "Expected #{expected}, which `gem build` did not produce. " \
424
+ "Check lib/version.rb against the built gem's name."
425
+ end
426
+
427
+ # site-local/ holds the offline documentation bundle and reaches the gem only
428
+ # through the gemspec's file sweep. CI downloads it before building. A local gem
429
+ # without it is still valid and still worth building, so this informs rather
430
+ # than fails.
431
+ unless File.directory?( File.join( __dir__, 'site-local' ) )
432
+ puts "\nNOTE: site-local/ is absent, so this gem carries no offline " \
433
+ "documentation bundle."
434
+ puts "Run `rake docs:build:local` first to match what CI packages."
435
+ end
436
+
437
+ puts "\nBuilt #{expected}"
438
+ end
439
+
440
+ ##
441
+ ## SBOM tasks
442
+ ##
443
+ ## Software Bill of Materials describing the Ceedling gem as installed: what ships
444
+ ## inside it, plus the transitive closure of its declared runtime dependencies.
445
+ ## CycloneDX and SPDX are rendered from one component model, so the two cannot
446
+ ## disagree about facts. Every component is identified by a PURL, and the vendored
447
+ ## C components by the commit they are pinned at -- the only identity that separates
448
+ ## the two Unity source trees a Ceedling gem carries, both of which report header
449
+ ## version 2.7.2.
450
+ ##
451
+ ## Generation lives in tools/, which the gemspec excludes from the gem, so none of
452
+ ## this reaches an installed Ceedling. Specs live beside it for the same reason:
453
+ ## spec/ ships for certification self-tests and would otherwise carry specs for
454
+ ## code the gem does not contain.
455
+ ##
456
+ ## The documents describe the gem as distributed. They do not describe the C code
457
+ ## Ceedling builds, nor the external tools an enabled plugin needs.
458
+
459
+ desc "Generate CycloneDX and SPDX SBOMs into the repository root"
460
+ task 'sbom:build' do
461
+ repo_only!( 'sbom:build' )
462
+
463
+ require_relative 'tools/sbom/generator'
464
+
465
+ written = Sbom::Generator.new( __dir__ ).build
466
+
467
+ puts "\nGenerated:"
468
+ written.each { |path| puts " #{File.basename( path )}" }
469
+ end
470
+
471
+ # Advisory, and deliberately not part of sbom:build. It reads gems installed on this
472
+ # machine, so its result depends on the environment in a way a generated document must
473
+ # not. What it catches is the one drift the structural checks cannot: a gem relicensing
474
+ # without changing version, where the recorded version still matches.
475
+ desc "Compare the curated gem license list against locally installed gems"
476
+ task 'sbom:licenses:audit' do
477
+ repo_only!( 'sbom:licenses:audit' )
478
+
479
+ require_relative 'tools/sbom/gem_licenses'
480
+
481
+ findings = []
482
+
483
+ Sbom::GemLicenses::GEMS.each do |name, entry|
484
+ installed = Gem::Specification.find_all_by_name( name ).max_by( &:version )
485
+
486
+ if installed.nil?
487
+ puts format( " %-24s %-22s not installed, cannot compare", name, entry[:license] )
488
+ next
489
+ end
490
+
491
+ declared = installed.licenses
492
+ agrees = declared.empty? || declared.any? { |l| entry[:license].to_s.include?( l ) }
493
+ status = declared.empty? ? 'gemspec declares none' : declared.join( ', ' )
494
+
495
+ findings << "#{name}: list says #{entry[:license]}, installed #{installed.version} says #{status}" unless agrees
496
+
497
+ puts format( " %-24s %-22s %s %s", name, entry[:license], agrees ? '✓' : '✗', status )
498
+ end
499
+
500
+ if findings.empty?
501
+ puts "\nNothing disagrees with the curated list."
502
+ else
503
+ puts "\nWorth re-reading:"
504
+ findings.each { |f| puts " - #{f}" }
505
+ puts "\nA gemspec declaring none is not a disagreement -- see each entry's source."
506
+ end
507
+ end
508
+
509
+ ##
510
+ ## CI summary tasks
511
+ ##
512
+ ## The CI summary lives in tools/, which the gemspec excludes from the gem, so these
513
+ ## tasks run only from the repository. Every input is a file the CI workflow gathered
514
+ ## beforehand; see tools/ci_summary/collector.rb.
515
+
516
+ desc "Render the CI summary markdown, and the baseline on a push run"
517
+ task 'ci:summary' do
518
+ repo_only!( 'ci:summary' )
519
+ require_relative 'tools/ci_summary/collector'
520
+
521
+ collector = CiSummary::Collector.new(
522
+ results_dir: ENV.fetch( 'CI_SUMMARY_RESULTS' ),
523
+ jobs_path: ENV['CI_SUMMARY_JOBS'],
524
+ baseline_path: ENV['CI_SUMMARY_BASELINE'],
525
+ diff_path: ENV['CI_SUMMARY_DIFF'],
526
+ merge_base: ENV['CI_SUMMARY_MERGE_BASE']
527
+ )
528
+
529
+ sha = ENV.fetch( 'CI_SUMMARY_SHA' )
530
+ collector.write_summary( ENV.fetch( 'CI_SUMMARY_OUT' ), sha: sha )
531
+
532
+ baseline_out = ENV['CI_SUMMARY_BASELINE_OUT'].to_s
533
+ collector.write_baseline( baseline_out, sha: sha, branch: ENV.fetch( 'CI_SUMMARY_BRANCH' ) ) unless baseline_out.empty?
534
+ end
535
+
536
+ desc "Run the CI summary's own specs"
537
+ task 'ci:summary:specs' do
538
+ repo_only!( 'ci:summary:specs' )
539
+ sh 'bundle exec rspec tools/ci_summary/spec --format documentation'
540
+ end
541
+
542
+ desc "Run the coverage report tooling's own specs"
543
+ task 'coverage:specs' do
544
+ repo_only!( 'coverage:specs' )
545
+ sh 'bundle exec rspec tools/coverage/spec --format documentation'
546
+ end
547
+
548
+ desc "Run the SBOM generator's own specs"
549
+ task 'sbom:specs' do
550
+ repo_only!( 'sbom:specs' )
551
+
552
+ # Not folded into specs:units or specs:integration. Those suites ship in the gem
553
+ # and run against an installed Ceedling, where tools/ does not exist.
554
+ sh 'bundle exec rspec tools/sbom/spec --format documentation'
555
+ end
556
+
557
+ ##
558
+ ## Profiling tasks
559
+ ##
560
+ ## On-demand stackprof-based profiling of a real Ceedling build/test run,
561
+ ## for ad hoc performance investigation. Runs against a scaffolded *copy* of
562
+ ## an example project (via `ceedling example`), never in-place under
563
+ ## examples/, so a profiling run touches nothing but tmp/profiling/ -- which
564
+ ## is entirely git-ignored. See tools/profiling/profile_ceedling.rb for the
565
+ ## harness this task shells out to.
566
+ ##
567
+
568
+ require 'yaml'
569
+
570
+ PROFILE_TMP_DIR = File.join(__dir__, 'tmp', 'profiling')
571
+ PROFILE_SCRIPT = File.join(__dir__, 'tools', 'profiling', 'profile_ceedling.rb')
572
+ PROFILE_CEEDLING_BIN = File.join(__dir__, 'bin', 'ceedling')
573
+
574
+ # Gate for stackprof, which is install_if:-gated in the Gemfile so an ordinary
575
+ # `bundle install` never attempts its native extension. See unbundled_sh for why
576
+ # the gate only ever reaches a child process.
577
+ #
578
+ # BUNDLE_GEMFILE is pinned because profile:run runs one command from inside the
579
+ # scaffolded project directory. Stripping the parent's Bundler environment also
580
+ # strips the absolute BUNDLE_GEMFILE that `bundle exec` exported, which would
581
+ # otherwise leave Bundler searching upward from a directory that is not the
582
+ # repository root.
583
+ PROFILE_ENV = {
584
+ 'CEEDLING_PROFILING' => 'true',
585
+ 'BUNDLE_GEMFILE' => File.join(__dir__, 'Gemfile'),
586
+ }.freeze
587
+
588
+ def profile_sh(cmd, &block)
589
+ unbundled_sh( PROFILE_ENV, cmd, &block )
590
+ end
591
+
592
+ # True when stackprof can actually be loaded under the gate. Probed in a child
593
+ # process because a `require` here could never succeed, whatever is installed.
594
+ def stackprof_available?
595
+ profile_sh( %q{bundle exec ruby -e "require 'stackprof'"} ) do |cmd|
596
+ system( cmd, out: File::NULL, err: File::NULL )
597
+ end
598
+ end
599
+
600
+ desc "Ensure profiling gems (stackprof) are installed"
601
+ task 'profile:setup' do
602
+ repo_only!( 'profile:setup' )
603
+
604
+ # stackprof's native extension fails to build on Windows (Gem::Ext::BuildError),
605
+ # and whether it can ever build there is untested. Declining early beats burying
606
+ # the developer in a failed compile. See the Gemfile's stackprof entry.
607
+ if Gem.win_platform?
608
+ raise "Profiling is not available on Windows -- stackprof's native extension " \
609
+ "does not build there. See the stackprof entry in the Gemfile."
610
+ end
611
+
612
+ puts "Probing for stackprof..."
613
+
614
+ if stackprof_available?
615
+ puts "stackprof is available."
616
+ next
617
+ end
618
+
619
+ puts "stackprof not found -- installing now via 'bundle install'..."
620
+
621
+ begin
622
+ profile_sh( 'bundle install' ) { |cmd| sh cmd }
623
+ rescue StandardError
624
+ raise "stackprof installation failed -- a native-extension build " \
625
+ "toolchain (e.g. the 'ruby-dev'/'ruby-devel' package on Linux) " \
626
+ "may be missing. See the error above for details."
627
+ end
628
+
629
+ # Re-probed rather than assumed, so a gem that installs but will not load is
630
+ # diagnosed here instead of surfacing as a LoadError from a grandchild process
631
+ # in the middle of a profiled build.
632
+ unless stackprof_available?
633
+ raise "stackprof installed but still will not load. Profiling cannot continue."
634
+ end
635
+
636
+ puts "stackprof installed."
637
+ end
638
+
639
+ desc "Profile a build task against an example project, generating flame graph."
640
+ task 'profile:run', [:project, :build_task] => 'profile:setup' do |_t, args|
641
+ # The scaffolded copy persists across successive runs for the same project (build/ and
642
+ # its dependency cache included), so e.g. a 'test:all' run followed by a
643
+ # 'test:all' run exercises a real delta/no-op rebuild, not two fresh full builds.
644
+ # Delete tmp/profiling/<project>/ by hand to force a from-scratch scaffold again.
645
+ # Usage: rake "profile:run[<example project>,<ceedling build task>]"
646
+ # Example: rake "profile:run[temp_sensor,clobber test:all]"
647
+
648
+ available_projects = Dir.children(File.join(__dir__, 'examples')).sort
649
+
650
+ project = args[:project]
651
+ if project.nil? || !available_projects.include?(project)
652
+ raise "Unknown example project '#{project}' -- available: #{available_projects.join(', ')}"
653
+ end
654
+
655
+ build_task = args[:build_task] || raise("A ceedling build task is required, e.g. 'clobber test:all'")
656
+
657
+ # Keyed on project alone (not timestamped) so this directory -- and the
658
+ # scaffolded project's build/ and dependency cache within it -- persists
659
+ # across successive profile:run calls for the same project.
660
+ scaffold_dir = File.join(PROFILE_TMP_DIR, project)
661
+ project_dir = File.join(scaffold_dir, project)
662
+
663
+ FileUtils.mkdir_p(scaffold_dir)
664
+
665
+ # Scaffold via Ceedling's own `example` command rather than running
666
+ # in-place under examples/ -- keeps profiling runs isolated from the
667
+ # checked-in example (no build/ artifacts polluting examples/<project>/).
668
+ # `ceedling example NAME DEST` places the scaffolded project at
669
+ # DEST/NAME/..., not directly in DEST -- hence project_dir above.
670
+ #
671
+ # Only scaffold if not already present: re-running `ceedling example`
672
+ # unconditionally would still be content-idempotent (delta builds are
673
+ # hash-based, not mtime-based), but skipping it here is simpler to reason
674
+ # about and is what actually lets build/ and the dependency cache persist
675
+ # untouched across successive runs, which is the whole point.
676
+ unless File.exist?(File.join(project_dir, 'project.yml'))
677
+ profile_sh( "bundle exec ruby \"#{PROFILE_CEEDLING_BIN}\" example #{project} \"#{scaffold_dir}\"" ) { |cmd| sh cmd }
678
+ raise "Expected scaffolded project at #{project_dir}, not found" unless File.directory?(project_dir)
679
+ end
680
+
681
+ # Hardcoded to 1: this is what makes Batchinator's serial fallback (see
682
+ # lib/ceedling/batchinator.rb) kick in, keeping the real work on the same
683
+ # thread StackProf is sampling instead of an unsampled worker thread. This
684
+ # task has no way to profile multi-threaded contention -- every flame
685
+ # graph it produces is single-threaded by design.
686
+ mixin_path = File.join(scaffold_dir, 'threads_mixin.yml')
687
+ File.write(mixin_path, { :project => { :test_threads => 1, :compile_threads => 1 } }.to_yaml)
688
+
689
+ # Timestamped, since project_dir/scaffold_dir are reused across runs --
690
+ # this is the one thing that has to be unique per invocation so successive
691
+ # reports (e.g. a full build, then a delta rebuild) don't overwrite each other.
692
+ reports_dir = File.join(scaffold_dir, 'reports')
693
+ FileUtils.mkdir_p(reports_dir)
694
+ timestamp = Time.now.strftime('%Y%m%d-%H%M%S')
695
+ dump_path = File.join(reports_dir, "#{timestamp}.dump")
696
+ text_path = File.join(reports_dir, "#{timestamp}.txt")
697
+ html_path = File.join(reports_dir, "#{timestamp}.html")
698
+
699
+ puts "Profiling 'ceedling #{build_task}' in #{project_dir}..."
700
+
701
+ Dir.chdir(project_dir) do
702
+ profile_sh( "bundle exec ruby \"#{PROFILE_SCRIPT}\" \"#{dump_path}\" \"#{PROFILE_CEEDLING_BIN}\" -- #{build_task} --mixin=\"#{mixin_path}\"" ) { |cmd| sh cmd }
703
+ end
704
+
705
+ # Both commands redirect, so each must reach `sh` as one string for a shell to
706
+ # interpret. profile_sh yields the command unsplit.
707
+ profile_sh( "bundle exec stackprof \"#{dump_path}\" --text > \"#{text_path}\"" ) { |cmd| sh cmd }
708
+ profile_sh( "bundle exec stackprof \"#{dump_path}\" --d3-flamegraph > \"#{html_path}\"" ) { |cmd| sh cmd }
709
+
710
+ puts "\nProfiling complete:"
711
+ puts " Project dir: #{project_dir}"
712
+ puts " Raw dump: #{dump_path}"
713
+ puts " Text report: #{text_path}"
714
+ puts " Flame graph: #{html_path}"
715
+ end
716
+
717
+ ##
718
+ ## Linting tasks
719
+ ##
720
+ ## RuboCop over Ceedling's own Ruby, limited to the Lint, Metrics, Security, and
721
+ ## Performance departments (see .rubocop.yml for why only those four). The gems
722
+ ## are install_if:-gated in the Gemfile, so `lint:setup` exists to install them on
723
+ ## demand and every other task here depends on it.
724
+ ##
725
+ ## `.rubocop_todo.yml` records the pre-existing offense backlog, so `lint` passing
726
+ ## means "no NEW offenses" rather than "no offenses." Regenerate it with
727
+ ## `lint:todo` only when deliberately re-baselining -- it is meant to shrink.
728
+ ##
729
+
730
+ # Local developer gets RuboCop's default output; CI gets GitHub workflow annotations
731
+ # so findings land inline on the pull request diff.
732
+ LINT_FORMAT = ENV['CI_LINT_GITHUB_FORMAT'] ? '--format github' : ''
733
+
734
+ # Gate for the RuboCop gems. See unbundled_sh for why every lint task runs RuboCop
735
+ # in a child process rather than loading it here.
736
+ LINT_ENV = { 'CEEDLING_LINT' => 'true' }.freeze
737
+
738
+ def lint_sh(cmd, &block)
739
+ unbundled_sh( LINT_ENV, cmd, &block )
740
+ end
741
+
742
+ # Shared runner so every lint task reports failure the same way. RuboCop exits
743
+ # non-zero when it finds offenses, which is the intended local signal, so the message
744
+ # says so rather than implying the tool broke.
745
+ def rubocop_sh(args)
746
+ cmd = "bundle exec rubocop #{LINT_FORMAT} #{args}".squeeze(' ').strip
747
+ puts "Running: #{cmd}"
748
+ lint_sh(cmd) do |c|
749
+ sh(c, verbose: false) do |ok, res|
750
+ next if ok
751
+ raise "RuboCop reported offenses or failed to run (exit #{res.exitstatus})"
752
+ end
753
+ end
754
+ end
755
+
756
+ desc "Ensure linting gems (rubocop, rubocop-performance) are installed"
757
+ task 'lint:setup' do
758
+ # .rubocop.yml and .rubocop_todo.yml are not packaged, so linting an installed
759
+ # gem would silently run against RuboCop's defaults instead. Every other lint
760
+ # task depends on this one and inherits the check.
761
+ repo_only!( 'lint:setup' )
762
+
763
+ puts "Probing for rubocop..."
764
+
765
+ available = lint_sh('bundle exec rubocop --version') do |c|
766
+ system(c, out: File::NULL, err: File::NULL)
767
+ end
768
+
769
+ if available
770
+ puts "rubocop is available."
771
+ else
772
+ puts "rubocop not found -- installing now via 'bundle install'..."
773
+ lint_sh('bundle install') { |c| sh c }
774
+ puts "rubocop installed."
775
+ end
776
+ end
777
+
778
+ desc "Lint Ceedling's Ruby source"
779
+ task 'lint' => 'lint:setup' do
780
+ rubocop_sh ''
781
+ end
782
+
783
+ desc "Lint only changed files, against a branch (e.g., rake \"lint:changed[master]\")"
784
+ task 'lint:changed', [:branch] => 'lint:setup' do |_t, args|
785
+ # next_version is the integration branch, so it is the comparison a contributor
786
+ # wants nearly always. Naming another branch or any revision overrides it.
787
+ branch = args[:branch] || 'next_version'
788
+
789
+ # Checked up front because an unresolvable revision makes `git diff` fail while
790
+ # the backticks below swallow the error, leaving an empty file list that reports
791
+ # as "nothing to lint." A typo would otherwise look like a clean branch.
792
+ unless system( 'git', 'rev-parse', '--verify', '--quiet', branch, out: File::NULL )
793
+ raise "Cannot compare against '#{branch}' -- no such branch or revision"
794
+ end
795
+
796
+ # Diff filter drops deletions; a removed file cannot be linted. Restricted to
797
+ # Ruby-ish paths so a run is not wasted on changed Markdown or YAML.
798
+ changed = `git diff --name-only --diff-filter=d #{branch}...HEAD`.split("\n")
799
+ changed += `git diff --name-only --diff-filter=d`.split("\n")
800
+ changed = changed.uniq.grep(/\.(rb|rake|gemspec)$|^Rakefile$|^bin\//)
801
+
802
+ if changed.empty?
803
+ puts "No changed Ruby files to lint against '#{branch}'."
804
+ next
805
+ end
806
+
807
+ puts "Linting #{changed.length} file(s) changed against '#{branch}'..."
808
+ # --force-exclusion so a named file that .rubocop.yml excludes stays excluded.
809
+ rubocop_sh "--force-exclusion #{changed.join(' ')}"
810
+ end
811
+
812
+ desc "Apply RuboCop's safe auto-corrections"
813
+ task 'lint:fix' => 'lint:setup' do
814
+ # Safe corrections only (-a, not -A). Review the diff before keeping it. Metrics
815
+ # offenses are never autocorrectable, so what this changes is mostly Performance
816
+ # and a handful of Lint cops.
817
+ rubocop_sh '--autocorrect'
818
+ end
819
+
820
+ desc "Regenerate .rubocop_todo.yml, the pre-existing offense backlog"
821
+ task 'lint:todo' => 'lint:setup' do
822
+ # --no-exclude-limit keeps per-file Exclude lists complete instead of collapsing a
823
+ # cop to a blanket override once it passes RuboCop's default threshold. Without it
824
+ # the backlog hides which files are involved, and that list is the only thing that
825
+ # makes the backlog actionable.
826
+ rubocop_sh '--auto-gen-config --no-exclude-limit'
827
+ end
828
+
104
829
  ##
105
830
  ## Documentation tasks
106
831
  ##
107
832
 
108
- task :no_color do
833
+ task :no_color do
109
834
  #doesn't do anything at the moment. will remove color from output for CI
110
835
  end
111
836
 
@@ -130,6 +855,8 @@ end
130
855
  namespace :docs do
131
856
  desc "Install documentation tooling (mkdocs-material, mike) in a Python virtual environment"
132
857
  task :install do
858
+ repo_only!( 'docs:install' )
859
+
133
860
  venv_dir = '.docsenv'
134
861
 
135
862
  if File.directory?(venv_dir)
@@ -163,6 +890,10 @@ namespace :docs do
163
890
 
164
891
  desc "Snapshot versioned project files into docs/snapshot/ for documentation"
165
892
  task :snapshot do
893
+ # docs/mkdocs/ is not packaged. Every docs build and deploy task depends on
894
+ # this one, so the whole namespace inherits the check from here.
895
+ repo_only!( 'docs:snapshot' )
896
+
166
897
  snapshot_dir = 'docs/mkdocs/snapshot/'
167
898
  # Ensure the snapshot directory is empty before writing new files (to clear out anything stale)
168
899
  FileUtils.rm_rf(snapshot_dir)
@@ -179,6 +910,11 @@ namespace :docs do
179
910
  task :local => [:snapshot] do
180
911
  venv_sh "mkdocs build -f mkdocs.local.yml --strict"
181
912
  end
913
+
914
+ desc "Build the prerelease documentation site for local validation"
915
+ task :prerelease => [:snapshot] do
916
+ venv_sh "mkdocs build -f mkdocs.prerelease.yml --strict"
917
+ end
182
918
  end
183
919
 
184
920
  desc "Serve web deploy docs site locally on port 8000"
@@ -186,21 +922,37 @@ namespace :docs do
186
922
  venv_sh "mkdocs serve"
187
923
  end
188
924
 
925
+ namespace :serve do
926
+ desc "Serve the prerelease documentation site locally on port 8000"
927
+ task :prerelease do
928
+ venv_sh "mkdocs serve -f mkdocs.prerelease.yml"
929
+ end
930
+ end
931
+
189
932
  desc "Browse versioned docs site locally on port 8000"
190
933
  task :preview do
191
934
  venv_sh "mike serve"
192
935
  end
193
936
 
194
937
  namespace :deploy do
195
- desc "Deploy 'dev' version to Github Pages"
196
- task :dev => [:snapshot] do
197
- venv_sh "mike deploy --push dev"
938
+ desc "Deploy prerelease docs to Github Pages"
939
+ task :prerelease, [:version] => [:snapshot] do |t, args|
940
+ version = args[:version] || raise("Version required: rake docs:deploy:prerelease[#.#.#]")
941
+ venv_sh "mike deploy --push --config-file mkdocs.prerelease.yml #{version}"
198
942
  end
199
943
 
200
- desc "Deploy a release version to Github Pages (usage: rake docs:deploy:release[1.1.0])"
944
+ desc "Deploy release docs to Github Pages without changing 'latest'"
201
945
  task :release, [:version] => [:snapshot] do |t, args|
202
946
  version = args[:version] || raise("Version required: rake docs:deploy:release[#.#.#]")
203
- venv_sh "mike deploy --push #{version} latest"
947
+ venv_sh "mike deploy --push #{version}"
948
+ end
949
+
950
+ namespace :release do
951
+ desc "Deploy release docs to Github Pages without and set it as 'latest'"
952
+ task :latest, [:version] => [:snapshot] do |t, args|
953
+ version = args[:version] || raise("Version required: rake docs:deploy:release:latest[#.#.#]")
954
+ venv_sh "mike deploy --push #{version} latest"
955
+ end
204
956
  end
205
957
  end
206
958
  end