ceedling 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (383) hide show
  1. checksums.yaml +4 -4
  2. data/GIT_COMMIT_SHA +1 -1
  3. data/README.md +57 -58
  4. data/Rakefile +5 -3
  5. data/assets/features/ceedling +1 -1
  6. data/assets/fixtures/test_source_file_duplicate_basenames/test_calc_typo.c +14 -0
  7. data/assets/fixtures/tests_with_duplicate_test_names/test_foo.c +21 -0
  8. data/bin/actionator.rb +6 -12
  9. data/bin/app_cfg.rb +35 -1
  10. data/bin/ceedling +13 -3
  11. data/bin/cli.rb +25 -6
  12. data/bin/cli_handler.rb +119 -73
  13. data/bin/cli_helper.rb +56 -78
  14. data/bin/installation_selector.rb +81 -0
  15. data/bin/launchinator.rb +69 -0
  16. data/bin/mixin_resolvinator.rb +26 -36
  17. data/bin/objects.yml +13 -0
  18. data/bin/path_validator.rb +25 -29
  19. data/bin/versionator.rb +47 -48
  20. data/ceedling.gemspec +19 -15
  21. data/docs/BreakingChanges.md +70 -1
  22. data/docs/Changelog.md +84 -3
  23. data/docs/KnownIssues.md +90 -4
  24. data/docs/ReleaseNotes.md +13 -0
  25. data/docs/overrides/main.html +11 -8
  26. data/lib/ceedling/build_log_writer.rb +33 -0
  27. data/lib/ceedling/config/build_root_policy.rb +70 -0
  28. data/lib/ceedling/config/configurator.rb +19 -18
  29. data/lib/ceedling/config/configurator_builder.rb +58 -28
  30. data/lib/ceedling/config/configurator_paths_validator.rb +179 -0
  31. data/lib/ceedling/config/configurator_plugins.rb +1 -1
  32. data/lib/ceedling/config/configurator_setup.rb +39 -41
  33. data/lib/ceedling/config/configurator_validator.rb +1 -110
  34. data/lib/ceedling/defaults.rb +4 -4
  35. data/lib/ceedling/dependencies/README.md +18 -16
  36. data/lib/ceedling/dependencies/dependency_cache_store.rb +20 -3
  37. data/lib/ceedling/dependencies/dependency_hasher.rb +35 -1
  38. data/lib/ceedling/filename_extension.rb +7 -1
  39. data/lib/ceedling/filesystem/FILE_TREE.md +253 -0
  40. data/lib/ceedling/filesystem/PATH_HANDLING.md +304 -0
  41. data/lib/ceedling/filesystem/README.md +41 -0
  42. data/lib/ceedling/filesystem/build_subpath.rb +102 -0
  43. data/lib/ceedling/filesystem/destination_collision.rb +25 -0
  44. data/lib/ceedling/{file_finder.rb → filesystem/file_finder.rb} +159 -104
  45. data/lib/ceedling/{file_finder_helper.rb → filesystem/file_finder_helper.rb} +36 -31
  46. data/lib/ceedling/filesystem/file_path_collection_utils.rb +183 -0
  47. data/lib/ceedling/{file_path_utils.rb → filesystem/file_path_utils.rb} +108 -97
  48. data/lib/ceedling/{file_system_wrapper.rb → filesystem/file_system_wrapper.rb} +6 -5
  49. data/lib/ceedling/filesystem/file_tree.rb +241 -0
  50. data/lib/ceedling/{file_wrapper.rb → filesystem/file_wrapper.rb} +65 -28
  51. data/lib/ceedling/filesystem/path_exclusions.rb +30 -0
  52. data/lib/ceedling/{path_matcher.rb → filesystem/path_matcher.rb} +27 -23
  53. data/lib/ceedling/{path_mirror.rb → filesystem/path_mirror.rb} +19 -18
  54. data/lib/ceedling/filesystem/path_spellings.rb +55 -0
  55. data/lib/ceedling/filesystem/project_paths.rb +184 -0
  56. data/lib/ceedling/filesystem/working_dir.rb +40 -0
  57. data/lib/ceedling/generators/generator.rb +5 -6
  58. data/lib/ceedling/generators/generator_partials.rb +1 -1
  59. data/lib/ceedling/generators/generator_test_results_backtrace.rb +7 -7
  60. data/lib/ceedling/handoff.rb +121 -0
  61. data/lib/ceedling/includes/include_factory.rb +3 -3
  62. data/lib/ceedling/includes/include_pathinator.rb +67 -10
  63. data/lib/ceedling/includes/includes.rb +1 -1
  64. data/lib/ceedling/installation.rb +92 -0
  65. data/lib/ceedling/library_resolver.rb +99 -0
  66. data/lib/ceedling/objects.yml +23 -2
  67. data/lib/ceedling/partials/partializer.rb +4 -4
  68. data/lib/ceedling/partials/partializer_config.rb +3 -1
  69. data/lib/ceedling/plugins/report_log_writer_plugin.rb +3 -5
  70. data/lib/ceedling/preprocess/preprocessinator_file_assembler.rb +1 -1
  71. data/lib/ceedling/preprocess/preprocessinator_includes_handler.rb +1 -1
  72. data/lib/ceedling/preprocess/preprocessinator_line_marker_includes_extractor.rb +1 -1
  73. data/lib/ceedling/rake_app/rakefile_component_resolver.rb +10 -17
  74. data/lib/ceedling/rake_app/test_task_name.rb +29 -0
  75. data/lib/ceedling/rakefile.rb +16 -1
  76. data/lib/ceedling/rakefiles/base/tasks_base.rake +1 -1
  77. data/lib/ceedling/rakefiles/release/rules_release.rake +4 -7
  78. data/lib/ceedling/rakefiles/tests/rules_tests.rake +3 -20
  79. data/lib/ceedling/rakefiles/tests/rules_tests_generate.rake +4 -30
  80. data/lib/ceedling/release_invoker/release_build_executor.rb +33 -44
  81. data/lib/ceedling/release_invoker/release_build_planner.rb +14 -6
  82. data/lib/ceedling/reportinator.rb +3 -4
  83. data/lib/ceedling/setupinator.rb +95 -87
  84. data/lib/ceedling/test_context_extractor.rb +5 -1
  85. data/lib/ceedling/test_invoker/PIPELINE.md +9 -7
  86. data/lib/ceedling/test_invoker/mock_locator.rb +60 -2
  87. data/lib/ceedling/test_invoker/partials_manager.rb +12 -0
  88. data/lib/ceedling/test_invoker/standin_headerinator.rb +22 -13
  89. data/lib/ceedling/test_invoker/test_build_executor.rb +42 -41
  90. data/lib/ceedling/test_invoker/test_build_planner.rb +37 -18
  91. data/lib/ceedling/test_invoker/test_build_setup.rb +17 -12
  92. data/lib/ceedling/test_invoker/test_build_validations.rb +16 -31
  93. data/lib/ceedling/test_invoker/test_file_preprocessinator.rb +1 -1
  94. data/lib/ceedling/test_invoker/test_invoker.rb +6 -1
  95. data/lib/ceedling/test_invoker/test_pipeline_helpers.rb +1 -1
  96. data/lib/ceedling/test_invoker/test_source_file_directive_resolver.rb +40 -20
  97. data/lib/ceedling/tool_executor.rb +9 -3
  98. data/lib/ceedling/yaml_wrapper.rb +3 -2
  99. data/lib/version.rb +1 -1
  100. data/plugins/bullseye/bullseye.rake +6 -9
  101. data/plugins/bullseye/config/defaults_bullseye.rb +1 -1
  102. data/plugins/bullseye/lib/bullseye.rb +9 -7
  103. data/plugins/cppcheck/config/defaults_cppcheck.rb +1 -1
  104. data/plugins/dependencies/config/defaults.yml +6 -6
  105. data/plugins/dependencies/dependencies.rake +4 -1
  106. data/plugins/dependencies/lib/dependencies.rb +18 -8
  107. data/plugins/dependencies/lib/dependency_spec.rb +17 -5
  108. data/plugins/fff/lib/fff.rb +45 -39
  109. data/plugins/fff/spec/fff_cmock_wrapper_spec.rb +128 -0
  110. data/plugins/gcov/config/defaults_gcov.rb +1 -1
  111. data/plugins/gcov/gcov.rake +6 -9
  112. data/plugins/gcov/lib/console_reportinator.rb +4 -18
  113. data/plugins/gcov/lib/gcov.rb +9 -2
  114. data/plugins/gcov/lib/gcovr_reportinator.rb +8 -40
  115. data/plugins/gcov/lib/gcovr_thresholds.rb +74 -0
  116. data/plugins/gcov/lib/reportgenerator_reportinator.rb +1 -1
  117. data/plugins/module_generator/lib/module_generator.rb +3 -3
  118. data/plugins/report_tests_teamcity_stdout/lib/report_tests_teamcity_stdout.rb +53 -80
  119. data/plugins/sanitize/lib/sanitize_records.rb +3 -6
  120. data/plugins/sanitize/sanitize.rake +6 -6
  121. data/plugins/valgrind/lib/valgrind.rb +14 -7
  122. data/plugins/valgrind/valgrind.rake +6 -6
  123. data/site-local/404.html +6 -20
  124. data/site-local/assets/javascripts/{bundle.d7400e89.min.js → bundle.c21346df.min.js} +3 -3
  125. data/site-local/assets/javascripts/{bundle.d7400e89.min.js.map → bundle.c21346df.min.js.map} +2 -2
  126. data/site-local/assets/javascripts/workers/{search.2c215733.min.js → search.a7633da7.min.js} +2 -2
  127. data/site-local/assets/javascripts/workers/{search.2c215733.min.js.map → search.a7633da7.min.js.map} +1 -1
  128. data/site-local/assets/stylesheets/main.57a0d79d.min.css +6 -0
  129. data/site-local/assets/stylesheets/main.57a0d79d.min.css.map +1 -0
  130. data/site-local/assets/stylesheets/palette.fb2fffe2.min.css +4 -0
  131. data/site-local/assets/stylesheets/palette.fb2fffe2.min.css.map +1 -0
  132. data/site-local/configuration/environment-vars.html +6 -20
  133. data/site-local/configuration/global-collections.html +6 -20
  134. data/site-local/configuration/index.html +6 -20
  135. data/site-local/configuration/loading.html +6 -20
  136. data/site-local/configuration/mixins.html +10 -24
  137. data/site-local/configuration/parallel-builds.html +6 -20
  138. data/site-local/configuration/project-file.html +8 -22
  139. data/site-local/configuration/reference/cexception.html +6 -20
  140. data/site-local/configuration/reference/cmock.html +8 -21
  141. data/site-local/configuration/reference/defines.html +16 -30
  142. data/site-local/configuration/reference/environment.html +10 -24
  143. data/site-local/configuration/reference/extension.html +6 -20
  144. data/site-local/configuration/reference/files.html +22 -30
  145. data/site-local/configuration/reference/flags.html +13 -27
  146. data/site-local/configuration/reference/index.html +6 -20
  147. data/site-local/configuration/reference/libraries.html +27 -23
  148. data/site-local/configuration/reference/mixins.html +6 -20
  149. data/site-local/configuration/reference/partials.html +6 -20
  150. data/site-local/configuration/reference/paths.html +38 -29
  151. data/site-local/configuration/reference/plugins.html +6 -20
  152. data/site-local/configuration/reference/project.html +32 -36
  153. data/site-local/configuration/reference/release-build.html +8 -20
  154. data/site-local/configuration/reference/test-build.html +6 -20
  155. data/site-local/configuration/reference/test-runner.html +6 -20
  156. data/site-local/configuration/reference/tools.html +27 -32
  157. data/site-local/configuration/reference/unity.html +6 -20
  158. data/site-local/configuration/which-ceedling.html +383 -37
  159. data/site-local/development/index.html +6 -20
  160. data/site-local/development/plugins/configuration.html +6 -20
  161. data/site-local/development/plugins/index.html +6 -20
  162. data/site-local/development/plugins/plugin-subclass.html +54 -68
  163. data/site-local/development/plugins/rake-tasks.html +8 -22
  164. data/site-local/development/releases.html +84 -29
  165. data/site-local/development/workflow.html +62 -71
  166. data/site-local/getting-started/builds.html +8 -20
  167. data/site-local/getting-started/command-line.html +62 -24
  168. data/site-local/getting-started/example-projects/cipher-quest.html +6 -20
  169. data/site-local/getting-started/example-projects/index.html +6 -20
  170. data/site-local/getting-started/example-projects/temp-sensor.html +6 -20
  171. data/site-local/getting-started/example-projects/wondrous-forest.html +6 -20
  172. data/site-local/getting-started/index.html +6 -20
  173. data/site-local/getting-started/installation.html +6 -20
  174. data/site-local/getting-started/quick-start.html +6 -20
  175. data/site-local/help.html +6 -20
  176. data/site-local/index.html +11 -24
  177. data/site-local/overview/build-system.html +6 -20
  178. data/site-local/overview/index.html +6 -20
  179. data/site-local/overview/test-environments.html +6 -20
  180. data/site-local/overview/tools-and-frameworks.html +6 -20
  181. data/site-local/plugins/beep.html +6 -20
  182. data/site-local/plugins/bullseye/index.html +13 -24
  183. data/site-local/plugins/bullseye/licensing.html +14 -28
  184. data/site-local/plugins/command-hooks.html +8 -22
  185. data/site-local/plugins/compile-commands-json-db.html +6 -20
  186. data/site-local/plugins/cppcheck.html +8 -22
  187. data/site-local/plugins/dependencies.html +16 -27
  188. data/site-local/plugins/fff.html +49 -32
  189. data/site-local/plugins/gcov/examples.html +7 -21
  190. data/site-local/plugins/gcov/gcovr.html +22 -33
  191. data/site-local/plugins/gcov/index.html +6 -20
  192. data/site-local/plugins/gcov/overview.html +9 -20
  193. data/site-local/plugins/gcov/reportgenerator.html +9 -23
  194. data/site-local/plugins/gcov/reporting.html +6 -20
  195. data/site-local/plugins/gcov/setup.html +8 -21
  196. data/site-local/plugins/gcov/tool-versions.html +6 -20
  197. data/site-local/plugins/gcov/troubleshooting.html +10 -24
  198. data/site-local/plugins/index.html +6 -20
  199. data/site-local/plugins/module-generator.html +21 -35
  200. data/site-local/plugins/report-build-warnings-log.html +53 -67
  201. data/site-local/plugins/report-tests-gtestlike-stdout.html +6 -20
  202. data/site-local/plugins/report-tests-ide-stdout.html +43 -57
  203. data/site-local/plugins/report-tests-log-factory.html +50 -64
  204. data/site-local/plugins/report-tests-pretty-stdout.html +7 -21
  205. data/site-local/plugins/report-tests-raw-output-log.html +9 -21
  206. data/site-local/plugins/report-tests-teamcity-stdout.html +20 -31
  207. data/site-local/plugins/sanitize.html +56 -65
  208. data/site-local/plugins/valgrind.html +49 -58
  209. data/site-local/project/index.html +6 -20
  210. data/site-local/project/release-history.html +6 -20
  211. data/site-local/project/sbom.html +6 -20
  212. data/site-local/project/upgrade.html +9 -20
  213. data/site-local/reference/build-directives.html +6 -20
  214. data/site-local/reference/command-line.html +15 -22
  215. data/site-local/reference/environment-vars.html +6 -20
  216. data/site-local/reference/gcov-plugin.html +6 -20
  217. data/site-local/reference/global-collections.html +6 -20
  218. data/site-local/reference/index.html +6 -20
  219. data/site-local/reference/partials-macros.html +6 -20
  220. data/site-local/reference/project-configuration.html +6 -20
  221. data/site-local/sitemap.xml.gz +0 -0
  222. data/site-local/snapshot/examples/cipher_quest/index.html +16 -30
  223. data/site-local/snapshot/examples/temp_sensor/index.html +8 -22
  224. data/site-local/snapshot/examples/wondrous_forest/index.html +6 -20
  225. data/site-local/snapshot/plugins/bullseye/config/defaults_bullseye.rb +1 -1
  226. data/site-local/snapshot/plugins/gcov/config/defaults_gcov.rb +1 -1
  227. data/site-local/testing-guide/build-directives.html +14 -28
  228. data/site-local/testing-guide/conventions.html +66 -27
  229. data/site-local/testing-guide/frameworks.html +11 -25
  230. data/site-local/testing-guide/index.html +6 -20
  231. data/site-local/testing-guide/partials/configuration.html +8 -22
  232. data/site-local/testing-guide/partials/conventions.html +8 -22
  233. data/site-local/testing-guide/partials/directives.html +16 -30
  234. data/site-local/testing-guide/partials/example.html +14 -28
  235. data/site-local/testing-guide/partials/index.html +6 -20
  236. data/site-local/testing-guide/partials/overview.html +6 -20
  237. data/site-local/testing-guide/partials/variables.html +11 -25
  238. data/site-local/testing-guide/test-cases.html +13 -27
  239. data/site-local/testing-guide/test-sample.html +12 -26
  240. data/site-local/testing-guide/test-suite-anatomy.html +6 -20
  241. data/spec/integration/actionator_file_operations_spec.rb +91 -1
  242. data/spec/integration/compile_commands_json_db_spec.rb +1 -1
  243. data/spec/integration/configurator_pipeline_spec.rb +10 -0
  244. data/spec/integration/configurator_validation_spec.rb +1 -1
  245. data/spec/integration/dependencies/dependency_tracker_cache_hardening_spec.rb +26 -0
  246. data/spec/integration/dependencies/dependency_tracker_core_spec.rb +62 -0
  247. data/spec/integration/launcher_handoff_spec.rb +297 -0
  248. data/spec/integration/mixin_loading_spec.rb +1 -1
  249. data/spec/integration/module_generator_spec.rb +3 -3
  250. data/spec/integration/nested_test_artifacts_spec.rb +99 -0
  251. data/spec/integration/partials_module_resolution_spec.rb +7 -4
  252. data/spec/integration/path_intake_scenarios_spec.rb +101 -0
  253. data/spec/integration/path_scenarios_spec.rb +322 -0
  254. data/spec/integration/quote_include_isolator_spec.rb +1 -1
  255. data/spec/integration/rake_task_registry_plugins_spec.rb +95 -0
  256. data/spec/integration/report_build_warnings_log_spec.rb +1 -1
  257. data/spec/integration/report_tests_log_factory_spec.rb +1 -1
  258. data/spec/integration/test_executable_manifest_spec.rb +1 -1
  259. data/spec/integration/test_includes_extractinator_spec.rb +2 -1
  260. data/spec/integration/test_naming_spec.rb +198 -0
  261. data/spec/integration/test_source_file_checks_spec.rb +166 -0
  262. data/spec/integration/tool_validator_spec.rb +1 -1
  263. data/spec/integration/upgrade_docs_spec.rb +84 -0
  264. data/spec/integration/vendor_copy_transient_io_retry_spec.rb +192 -75
  265. data/spec/support/file_tree_helper.rb +88 -0
  266. data/spec/support/integration/configurator_integration_helper.rb +10 -7
  267. data/spec/support/integration/dependency_tracker_integration_helper.rb +1 -1
  268. data/spec/support/integration/partials_generation_integration_helper.rb +2 -2
  269. data/spec/support/integration/path_scenario_harness.rb +173 -0
  270. data/spec/support/integration/spec_integration_helper.rb +1 -1
  271. data/spec/support/integration/test_includes_harness.rb +13 -2
  272. data/spec/support/spec_helper.rb +2 -0
  273. data/spec/support/system/spec_system_helper.rb +7 -6
  274. data/spec/support/system/system_context.rb +21 -3
  275. data/spec/support/working_dir_tracking.rb +49 -0
  276. data/spec/system/build_output_mirroring_spec.rb +2 -2
  277. data/spec/system/conditional_mock_includes_spec.rb +1 -1
  278. data/spec/system/delta_builds_spec.rb +137 -11
  279. data/spec/system/gcov_deployment_spec.rb +1 -0
  280. data/spec/system/header_include_path_validation_spec.rb +4 -4
  281. data/spec/system/launcher_handoff_spec.rb +82 -0
  282. data/spec/system/mock_include_folders_spec.rb +91 -0
  283. data/spec/system/parent_directory_reference_spec.rb +5 -3
  284. data/spec/system/path_handling_probes_spec.rb +192 -0
  285. data/spec/system/preprocessing_parameterized_tests_spec.rb +1 -1
  286. data/spec/system/rake_release_task_path_disambiguation_spec.rb +6 -6
  287. data/spec/system/rake_test_task_path_disambiguation_spec.rb +85 -0
  288. data/spec/system/special_path_characters_spec.rb +86 -0
  289. data/spec/system/support/common_test_cases.rb +23 -21
  290. data/spec/system/support/gcov_common_test_cases.rb +37 -9
  291. data/spec/system/support/sanitize_common_test_cases.rb +2 -2
  292. data/spec/system/support/valgrind_common_test_cases.rb +12 -12
  293. data/spec/system/test_pipeline_stop_points_spec.rb +4 -4
  294. data/spec/system/test_runner_system_include_spec.rb +1 -1
  295. data/spec/system/test_source_file_directive_spec.rb +34 -5
  296. data/spec/units/bin/actionator_spec.rb +14 -17
  297. data/spec/units/bin/app_cfg_spec.rb +47 -0
  298. data/spec/units/bin/cli_handler_spec.rb +284 -7
  299. data/spec/units/bin/cli_helper_spec.rb +126 -45
  300. data/spec/units/bin/installation_selector_spec.rb +114 -0
  301. data/spec/units/bin/launchinator_spec.rb +171 -0
  302. data/spec/units/bin/path_validator_spec.rb +10 -0
  303. data/spec/units/bin/versionator_spec.rb +38 -6
  304. data/spec/units/build_log_writer_spec.rb +57 -0
  305. data/spec/units/config/build_root_policy_spec.rb +61 -0
  306. data/spec/units/config/configurator_builder_spec.rb +37 -6
  307. data/spec/units/config/configurator_paths_validator_spec.rb +292 -0
  308. data/spec/units/config/configurator_setup_spec.rb +65 -103
  309. data/spec/units/config/configurator_spec.rb +37 -6
  310. data/spec/units/config/configurator_validator_spec.rb +1 -172
  311. data/spec/units/default_tools_quoting_spec.rb +83 -0
  312. data/spec/units/dependencies/dependency_cache_store_spec.rb +33 -2
  313. data/spec/units/dependencies/dependency_debug_tree_spec.rb +1 -1
  314. data/spec/units/dependencies/dependency_hasher_spec.rb +42 -1
  315. data/spec/units/dependencies/dependency_path_normalizer_spec.rb +1 -1
  316. data/spec/units/dependencies/dependency_tracker_spec.rb +3 -1
  317. data/spec/units/filename_extension_spec.rb +11 -0
  318. data/spec/units/filesystem/build_subpath_spec.rb +122 -0
  319. data/spec/units/filesystem/destination_collision_spec.rb +30 -0
  320. data/spec/units/{file_finder_helper_spec.rb → filesystem/file_finder_helper_spec.rb} +46 -1
  321. data/spec/units/{file_finder_spec.rb → filesystem/file_finder_spec.rb} +188 -22
  322. data/spec/units/{file_path_collection_utils_spec.rb → filesystem/file_path_collection_utils_spec.rb} +181 -1
  323. data/spec/units/{file_path_utils_spec.rb → filesystem/file_path_utils_spec.rb} +204 -87
  324. data/spec/units/filesystem/file_system_wrapper_spec.rb +33 -0
  325. data/spec/units/filesystem/file_tree_spec.rb +511 -0
  326. data/spec/units/filesystem/file_tree_windows_spec.rb +78 -0
  327. data/spec/units/{file_wrapper_spec.rb → filesystem/file_wrapper_spec.rb} +154 -32
  328. data/spec/units/{path_matcher_spec.rb → filesystem/path_matcher_spec.rb} +12 -1
  329. data/spec/units/{path_mirror_spec.rb → filesystem/path_mirror_spec.rb} +32 -4
  330. data/spec/units/filesystem/project_paths_spec.rb +147 -0
  331. data/spec/units/filesystem/working_dir_spec.rb +71 -0
  332. data/spec/units/generators/generator_spec.rb +12 -6
  333. data/spec/units/generators/generator_test_results_backtrace_spec.rb +50 -46
  334. data/spec/units/generators/generator_test_results_spec.rb +1 -1
  335. data/spec/units/handoff_spec.rb +205 -0
  336. data/spec/units/includes/include_factory_spec.rb +3 -3
  337. data/spec/units/includes/include_pathinator_spec.rb +46 -0
  338. data/spec/units/installation_spec.rb +228 -0
  339. data/spec/units/library_resolver_spec.rb +157 -0
  340. data/spec/units/mock_locator_spec.rb +76 -1
  341. data/spec/units/partials/partializer_config_spec.rb +7 -0
  342. data/spec/units/partials/partializer_spec.rb +1 -0
  343. data/spec/units/partials_manager_spec.rb +17 -0
  344. data/spec/units/plugins/bullseye_spec.rb +15 -2
  345. data/spec/units/plugins/console_reportinator_spec.rb +18 -20
  346. data/spec/units/plugins/dependencies_spec.rb +33 -7
  347. data/spec/units/plugins/dependency_spec_spec.rb +17 -0
  348. data/spec/units/plugins/gcov_spec.rb +28 -3
  349. data/spec/units/plugins/gcovr_reportinator_spec.rb +19 -47
  350. data/spec/units/plugins/gcovr_thresholds_spec.rb +95 -0
  351. data/spec/units/plugins/module_generator_spec.rb +5 -5
  352. data/spec/units/plugins/report_build_warnings_log_spec.rb +3 -3
  353. data/spec/units/plugins/report_log_writer_plugin_spec.rb +10 -1
  354. data/spec/units/plugins/report_tests_raw_output_log_spec.rb +13 -2
  355. data/spec/units/plugins/report_tests_teamcity_stdout_spec.rb +77 -3
  356. data/spec/units/plugins/reportgenerator_reportinator_spec.rb +1 -1
  357. data/spec/units/plugins/sanitize_records_spec.rb +3 -1
  358. data/spec/units/plugins/sanitize_spec.rb +1 -1
  359. data/spec/units/plugins/valgrind_spec.rb +23 -8
  360. data/spec/units/preprocess/preprocessinator_comment_stripper_spec.rb +1 -1
  361. data/spec/units/rake_app/rakefile_component_resolver_spec.rb +21 -0
  362. data/spec/units/rake_app/test_task_name_spec.rb +47 -0
  363. data/spec/units/release_build_executor_spec.rb +53 -14
  364. data/spec/units/release_build_planner_spec.rb +15 -3
  365. data/spec/units/reportinator_spec.rb +5 -5
  366. data/spec/units/standin_headerinator_spec.rb +31 -1
  367. data/spec/units/test_build_executor_spec.rb +107 -5
  368. data/spec/units/test_build_planner_spec.rb +104 -2
  369. data/spec/units/test_build_setup_spec.rb +96 -12
  370. data/spec/units/test_context_extractor_spec.rb +25 -0
  371. data/spec/units/test_file_preprocessinator_spec.rb +17 -1
  372. data/spec/units/test_includes_extractinator_spec.rb +5 -1
  373. data/spec/units/test_invoker/objects_wiring_spec.rb +6 -3
  374. data/spec/units/test_invoker_spec.rb +14 -1
  375. data/spec/units/test_source_file_directive_resolver_spec.rb +38 -7
  376. data/spec/units/tool_executor_spec.rb +26 -0
  377. data/spec/units/yaml_wrapper_spec.rb +11 -0
  378. metadata +122 -33
  379. data/lib/ceedling/file_path_collection_utils.rb +0 -164
  380. data/site-local/assets/stylesheets/main.ec1eaa64.min.css +0 -1
  381. data/site-local/assets/stylesheets/main.ec1eaa64.min.css.map +0 -1
  382. data/site-local/assets/stylesheets/palette.ab4e12ef.min.css +0 -1
  383. data/site-local/assets/stylesheets/palette.ab4e12ef.min.css.map +0 -1
data/bin/cli_handler.rb CHANGED
@@ -10,12 +10,13 @@ require 'mixins' # Built-in Mixins
10
10
  require 'ceedling/constants' # From Ceedling application
11
11
  require 'ceedling/rake_app/rake_task_registry' # From Ceedling application
12
12
  require 'versionator' # Outside DIY context
13
+ require 'ceedling/installation'
13
14
 
14
15
  class CliHandler
15
16
 
16
17
  DOCS_SUBDIR = 'docs'
17
18
 
18
- constructor :composinator, :projectinator, :cli_helper, :path_validator, :rake_task_registry, :actionator, :loginator
19
+ constructor :composinator, :projectinator, :cli_helper, :path_validator, :rake_task_registry, :actionator, :launchinator, :loginator
19
20
 
20
21
  # Override to prevent exception handling from walking & stringifying the object variables.
21
22
  # Object variables are lengthy and produce a flood of output.
@@ -44,6 +45,23 @@ class CliHandler
44
45
  verbosity = @helper.set_verbosity( options[:verbosity] )
45
46
  @helper.set_ruby_replacement( options[:ruby_replacement] )
46
47
 
48
+ # Help comes from the installation the project (if any) selects, so hand off before printing any
49
+ options[:project], options[:mixin] = standardize_project_and_mixins( options[:project], options[:mixin] )
50
+ config, rakefile_path = nil, nil
51
+ if @projectinator.config_available?( filepath:options[:project], env:env )
52
+ begin
53
+ # Silent Ceedling loading unless debug verbosity
54
+ config, rakefile_path = load_project_and_launch( env:env, app_cfg:app_cfg, options:options, silent:!(verbosity == Verbosity::DEBUG) )
55
+ rescue StandardError
56
+ # Help for one command needs no project, so a project that fails to load does not block it
57
+ raise if command.nil?
58
+
59
+ @launchinator.launch( env:env, app_cfg:app_cfg, config:{} )
60
+ end
61
+ else
62
+ @launchinator.launch( env:env, app_cfg:app_cfg, config:{} )
63
+ end
64
+
47
65
  # If help requested for a command, show it and skip listing build tasks
48
66
  if !command.nil?
49
67
  # Block handler
@@ -55,16 +73,8 @@ class CliHandler
55
73
  yield( command ) if block_given?
56
74
 
57
75
  # If project configuration is available, also display Rake tasks
58
- options[:project], options[:mixin] = standardize_project_and_mixins( options[:project], options[:mixin] )
59
- if @projectinator.config_available?( filepath:options[:project], env:env )
60
- list_rake_tasks(
61
- env:env,
62
- app_cfg: app_cfg,
63
- filepath: options[:project],
64
- mixins: options[:mixin],
65
- # Silent Ceedling loading unless debug verbosity
66
- silent: !(verbosity == Verbosity::DEBUG)
67
- )
76
+ if !config.nil?
77
+ list_rake_tasks( app_cfg:app_cfg, config:config, rakefile_path:rakefile_path )
68
78
  else
69
79
  # If no project configuration is available then note why we aren't displaying more
70
80
  msg = "Run help commands in a directory with a project file to list additional options\n\n"
@@ -81,13 +91,18 @@ class CliHandler
81
91
  def rake_help(env:, app_cfg:)
82
92
  @helper.set_verbosity( Verbosity::ERRORS )
83
93
 
84
- list_rake_tasks( env:env, app_cfg:app_cfg )
94
+ config, rakefile_path = load_project_and_launch( env:env, app_cfg:app_cfg, options:{:project => nil, :mixin => []} )
95
+
96
+ list_rake_tasks( app_cfg:app_cfg, config:config, rakefile_path:rakefile_path )
85
97
  end
86
98
 
87
99
 
88
100
  def new_project(env, app_cfg, ceedling_tag, options, dest)
89
101
  @helper.set_verbosity( options[:verbosity] )
90
102
 
103
+ # The selected installation creates the project with its own code and contents
104
+ @launchinator.launch( env:env, app_cfg:app_cfg )
105
+
91
106
  dest = @path_validator.standardize_paths( dest ).first
92
107
 
93
108
  # If destination is nil, assume it's the working directory
@@ -101,9 +116,6 @@ class CliHandler
101
116
  raise msg
102
117
  end unless options[:force]
103
118
 
104
- # Update app_cfg paths (ignore return values)
105
- @helper.which_ceedling?( env:env, app_cfg:app_cfg )
106
-
107
119
  # Source paths for project tasks resolve in relation to this path
108
120
  @actions.source_root = app_cfg[:ceedling_root_path]
109
121
 
@@ -143,18 +155,21 @@ class CliHandler
143
155
 
144
156
  path, options[:project] = @path_validator.standardize_paths( path, options[:project] )
145
157
 
158
+ # The source is the Ceedling running or WHICH_CEEDLING. A detected vendor/ceedling/ is
159
+ # likely the very copy being replaced. A source that is that copy is refused before any
160
+ # hand-off, since an older copy would delete itself.
161
+ source = @launchinator.resolve( env:env, app_cfg:app_cfg, detect_vendor:false )
162
+ if source == Installation.new( File.join( path, 'vendor', 'ceedling' ) )
163
+ raise CeedlingException.new( "Cannot upgrade #{source.root}/ from itself. Run `upgrade` with the Ceedling to upgrade to, or set WHICH_CEEDLING." )
164
+ end
165
+ @launchinator.proceed( target:source, app_cfg:app_cfg )
166
+
146
167
  # Check for existing project
147
168
  if !@helper.project_exists?( path, :&, options[:project], 'vendor/ceedling/lib/version.rb' )
148
169
  msg = "Could not find an existing project at #{path}/."
149
170
  raise msg
150
171
  end
151
172
 
152
- which, _ = @helper.which_ceedling?( env:env, app_cfg:app_cfg )
153
- if (which == :gem)
154
- msg = "Project configuration specifies the Ceedling gem, not vendored Ceedling"
155
- @loginator.console( msg, LogLabels::NOTICE )
156
- end
157
-
158
173
  # Source paths for project tasks resolve in relation to this path
159
174
  @actions.source_root = app_cfg[:ceedling_root_path]
160
175
 
@@ -163,12 +178,11 @@ class CliHandler
163
178
  @actions.remove_directory( vendor_path )
164
179
  @helper.vendor_tools( app_cfg[:ceedling_root_path], path )
165
180
 
166
- # Recreate documentation if we find docs/ subdirectory
167
- docs_path = File.join( path, 'docs' )
168
- founds_docs = @helper.project_exists?( path, :&, File.join( 'docs', 'CeedlingPacket.md' ) )
169
- if founds_docs
170
- @actions.remove_directory( docs_path )
171
- @helper.copy_docs( app_cfg[:ceedling_root_path], File.join( path, DOCS_SUBDIR ) )
181
+ # Refresh documentation an export wrote, leaving the project's own files in docs/
182
+ docs_path = File.join( path, DOCS_SUBDIR )
183
+ if @helper.exported_docs?( docs_path )
184
+ @helper.remove_exported_docs( docs_path, keep_bundle: !@helper.docs_bundle?( app_cfg[:ceedling_root_path] ) )
185
+ @helper.copy_docs( app_cfg[:ceedling_root_path], docs_path )
172
186
  end
173
187
 
174
188
  @loginator.console( "\nUpgraded project at #{path}/\n", LogLabels::TITLE )
@@ -182,10 +196,9 @@ class CliHandler
182
196
  @helper.set_verbosity( _verbosity, override: false )
183
197
  @helper.set_ruby_replacement( options[:ruby_replacement] )
184
198
 
185
- options[:project], options[:mixin] = standardize_project_and_mixins( options[:project], options[:mixin] )
186
199
  options[:logfile] = @path_validator.standardize_paths( options[:logfile] ).first
187
200
 
188
- _, config = @composinator.loadinate( builtin_load_paths:BUILTIN_MIXIN_LOAD_PATHS, filepath:options[:project], mixins:options[:mixin], env:env )
201
+ config, rakefile_path = load_project_and_launch( env:env, app_cfg:app_cfg, options:options )
189
202
 
190
203
  @cli_helper.log_project_name( config )
191
204
 
@@ -234,12 +247,16 @@ class CliHandler
234
247
  )
235
248
 
236
249
  # Look up if any tasks we will execute are build tasks
237
- build_tasks = @helper.build_task?( tasks: (tasks.empty? ? default_tasks : tasks ) )
250
+ requested = (tasks.empty? ? default_tasks : tasks)
251
+ build_tasks = @helper.build_task?( tasks: requested )
238
252
 
239
253
  # Enable setup / operations duration logging in Rake context if build tasks are being invoked
240
254
  app_cfg.set_build_tasks( build_tasks )
241
255
 
242
- _, path = @helper.which_ceedling?( env:env, config:config, app_cfg:app_cfg )
256
+ # Only a build populates build/vendor, so a command that only reads the project leaves a
257
+ # concurrent build's vendored files alone
258
+ app_cfg.set_test_build_tasks( @helper.test_task?( tasks: requested ) )
259
+ app_cfg.set_release_build_tasks( @helper.release_task?( tasks: requested ) )
243
260
 
244
261
  # Log Ceedling Application version information
245
262
  _version = Versionator.new(
@@ -266,7 +283,7 @@ class CliHandler
266
283
 
267
284
  @helper.load_ceedling(
268
285
  config: config,
269
- rakefile_path: path,
286
+ rakefile_path: rakefile_path,
270
287
  default_tasks: default_tasks
271
288
  )
272
289
 
@@ -283,9 +300,9 @@ class CliHandler
283
300
  @helper.set_ruby_replacement( options[:ruby_replacement] )
284
301
 
285
302
  filepath = @path_validator.standardize_paths( filepath ).first
286
- options[:project], options[:mixin] = standardize_project_and_mixins( options[:project], options[:mixin] )
287
303
 
288
- _, config = @composinator.loadinate( builtin_load_paths:BUILTIN_MIXIN_LOAD_PATHS, filepath:options[:project], mixins:options[:mixin], env:env )
304
+ # Even without --app, the selected installation merges the configuration by its own rules
305
+ config, rakefile_path = load_project_and_launch( env:env, app_cfg:app_cfg, options:options )
289
306
 
290
307
  # A nil filepath means --stdout was set -- the YAML itself is the only thing
291
308
  # that may reach stdout in that case, for a consuming tool to parse cleanly,
@@ -304,11 +321,9 @@ class CliHandler
304
321
  app_cfg.set_project_config( config )
305
322
  app_cfg.set_logging_path( @helper.process_logging_path( config ) )
306
323
 
307
- _, path = @helper.which_ceedling?( env:env, config:config, app_cfg:app_cfg )
308
-
309
324
  config = @helper.load_ceedling(
310
325
  config: config,
311
- rakefile_path: path,
326
+ rakefile_path: rakefile_path,
312
327
  default_tasks: default_tasks
313
328
  )
314
329
  else
@@ -327,9 +342,7 @@ class CliHandler
327
342
  @helper.set_verbosity( options[:verbosity] )
328
343
  @helper.set_ruby_replacement( options[:ruby_replacement] )
329
344
 
330
- options[:project], options[:mixin] = standardize_project_and_mixins( options[:project], options[:mixin] )
331
-
332
- _, config = @composinator.loadinate( builtin_load_paths:BUILTIN_MIXIN_LOAD_PATHS, filepath:options[:project], mixins:options[:mixin], env:env )
345
+ config, rakefile_path = load_project_and_launch( env:env, app_cfg:app_cfg, options:options )
333
346
 
334
347
  @cli_helper.log_project_name( config )
335
348
 
@@ -340,12 +353,10 @@ class CliHandler
340
353
  app_cfg.set_logging_path( @helper.process_logging_path( config ) )
341
354
  app_cfg.set_log_filepath( '' )
342
355
 
343
- _, path = @helper.which_ceedling?( env:env, config:config, app_cfg:app_cfg )
344
-
345
356
  begin
346
357
  @helper.load_ceedling(
347
358
  config: config,
348
- rakefile_path: path,
359
+ rakefile_path: rakefile_path,
349
360
  default_tasks: default_tasks
350
361
  )
351
362
  ensure
@@ -358,9 +369,7 @@ class CliHandler
358
369
  @helper.set_verbosity( options[:verbosity] )
359
370
  @helper.set_ruby_replacement( options[:ruby_replacement] )
360
371
 
361
- options[:project], options[:mixin] = standardize_project_and_mixins( options[:project], options[:mixin] )
362
-
363
- _, config = @composinator.loadinate( builtin_load_paths:BUILTIN_MIXIN_LOAD_PATHS, filepath:options[:project], mixins:options[:mixin], env:env )
372
+ config, rakefile_path = load_project_and_launch( env:env, app_cfg:app_cfg, options:options )
364
373
 
365
374
  @cli_helper.console_project_name( config )
366
375
 
@@ -368,11 +377,9 @@ class CliHandler
368
377
  app_cfg.set_project_config( config )
369
378
  app_cfg.set_logging_path( @helper.process_logging_path( config ) )
370
379
 
371
- _, path = @helper.which_ceedling?( env:env, config:config, app_cfg:app_cfg )
372
-
373
380
  config = @helper.load_ceedling(
374
381
  config: config,
375
- rakefile_path: path
382
+ rakefile_path: rakefile_path
376
383
  )
377
384
 
378
385
  env_list = []
@@ -411,8 +418,8 @@ class CliHandler
411
418
  def list_examples(env, app_cfg, options)
412
419
  @helper.set_verbosity( options[:verbosity] )
413
420
 
414
- # Process which_ceedling for app_cfg modifications but ignore return values
415
- @helper.which_ceedling?( env:env, app_cfg:app_cfg )
421
+ # The selected installation lists its own examples
422
+ @launchinator.launch( env:env, app_cfg:app_cfg )
416
423
 
417
424
  examples = @helper.lookup_example_projects( app_cfg[:ceedling_examples_path] )
418
425
 
@@ -437,10 +444,10 @@ class CliHandler
437
444
  def create_example(env, app_cfg, options, name, dest)
438
445
  @helper.set_verbosity( options[:verbosity] )
439
446
 
440
- dest = @path_validator.standardize_paths( dest ).first
447
+ # The selected installation creates the example with its own code and contents
448
+ @launchinator.launch( env:env, app_cfg:app_cfg )
441
449
 
442
- # Process which_ceedling for app_cfg modifications but ignore return values
443
- @helper.which_ceedling?( env:env, app_cfg:app_cfg )
450
+ dest = @path_validator.standardize_paths( dest ).first
444
451
 
445
452
  examples = @helper.lookup_example_projects( app_cfg[:ceedling_examples_path] )
446
453
 
@@ -485,7 +492,19 @@ class CliHandler
485
492
  end
486
493
 
487
494
 
488
- def docs(app_cfg, dest)
495
+ def docs(env, app_cfg, dest)
496
+ # The selected installation exports its own documentation, if it has any to export
497
+ target = @launchinator.resolve( env:env, app_cfg:app_cfg )
498
+ launcher = Installation.new( app_cfg[:launcher_root_path] )
499
+ if target == launcher or @helper.docs_bundle?( target.root )
500
+ @launchinator.proceed( target:target, app_cfg:app_cfg )
501
+ else
502
+ app_cfg.set_paths( launcher.root )
503
+ msg = "#{target.describe()} holds no documentation bundle to export. " +
504
+ "Exporting the documentation of #{launcher.describe( 'Ceedling launcher' )} instead."
505
+ @loginator.console( msg, LogLabels::NOTICE )
506
+ end
507
+
489
508
  # File operations require an anchored source root
490
509
  @actions.source_root = app_cfg[:ceedling_root_path]
491
510
 
@@ -497,16 +516,17 @@ class CliHandler
497
516
  end
498
517
 
499
518
 
500
- def version(env, app_cfg)
519
+ def version(env, app_cfg, options={})
501
520
  # Versionator is not needed to persist. So, it's not built in the DIY collection.
502
521
 
503
- @helper.set_verbosity( Verbosity::ERRORS )
522
+ @helper.set_verbosity( options[:verbosity] || Verbosity::ERRORS )
504
523
 
505
524
  # Ceedling bootloader
506
- launcher = Versionator.new( app_cfg[:ceedling_root_path] )
525
+ launcher = Versionator.new( app_cfg[:launcher_root_path] )
507
526
 
508
- # This call updates Ceedling paths in app_cfg if which Ceedling has been modified
509
- @helper.which_ceedling?( env:env, app_cfg:app_cfg )
527
+ # This call updates Ceedling paths in app_cfg if the project or environment selects another Ceedling
528
+ config = version_project_config( env, options )
529
+ @launchinator.resolve( env:env, app_cfg:app_cfg, config:config )
510
530
 
511
531
  # Ceedling application
512
532
  application = @helper.manufacture_app_version( app_cfg )
@@ -515,7 +535,7 @@ class CliHandler
515
535
  ceedling = nil
516
536
 
517
537
  # A simple Ceedling version block because launcher and application are the same
518
- if launcher.ceedling_install_path == application.ceedling_install_path
538
+ if Installation.new( launcher.ceedling_install_path ) == Installation.new( application.ceedling_install_path )
519
539
  ceedling = <<~CEEDLING
520
540
  Ceedling => #{application.ceedling_build}
521
541
  ----------------------
@@ -560,6 +580,25 @@ class CliHandler
560
580
 
561
581
  private
562
582
 
583
+ # The project configuration `version` resolves which Ceedling from. A --project or
584
+ # --mixin the user names must load. The default project file is read only when it
585
+ # loads cleanly, so `version` still answers for a broken or absent project.
586
+ def version_project_config(env, options)
587
+ project, mixins = standardize_project_and_mixins( options[:project], options[:mixin] || [] )
588
+ explicit = !project.nil? || !mixins.empty?
589
+
590
+ return {} if !explicit and !@projectinator.config_available?( env:env )
591
+
592
+ begin
593
+ _, config = @composinator.loadinate( builtin_load_paths:BUILTIN_MIXIN_LOAD_PATHS, filepath:project, mixins:mixins, env:env, silent:true )
594
+ rescue StandardError
595
+ raise if explicit
596
+ config = {}
597
+ end
598
+
599
+ return config
600
+ end
601
+
563
602
  # Standardizes a project filepath and a mixins list together. PathValidator's
564
603
  # standardize_paths() returns new values rather than updating its arguments in
565
604
  # place, so the mixins list can't just be passed through it directly -- inline
@@ -580,25 +619,32 @@ class CliHandler
580
619
  return _project, _mixins
581
620
  end
582
621
 
583
- def list_rake_tasks(env:, app_cfg:, filepath:nil, mixins:[], silent:false)
584
- _, config =
585
- @composinator.loadinate(
586
- builtin_load_paths:BUILTIN_MIXIN_LOAD_PATHS,
587
- filepath: filepath,
588
- mixins: mixins,
589
- env: env,
590
- silent: silent
591
- )
622
+ # Loads the project configuration, then runs this command in the installation it selects.
623
+ # Returns the configuration and the rakefile to load, unless another installation took over.
624
+ def load_project_and_launch(env:, app_cfg:, options:, silent:false)
625
+ options[:project], options[:mixin] = standardize_project_and_mixins( options[:project], options[:mixin] )
592
626
 
627
+ _, config = @composinator.loadinate(
628
+ builtin_load_paths: BUILTIN_MIXIN_LOAD_PATHS,
629
+ filepath: options[:project],
630
+ mixins: options[:mixin],
631
+ env: env,
632
+ silent: silent
633
+ )
634
+
635
+ rakefile_path = @launchinator.launch( env:env, app_cfg:app_cfg, config:config )
636
+
637
+ return config, rakefile_path
638
+ end
639
+
640
+ def list_rake_tasks(app_cfg:, config:, rakefile_path:)
593
641
  # Save reference to loaded configuration
594
642
  app_cfg.set_project_config( config )
595
643
  app_cfg.set_logging_path( @helper.process_logging_path( config ) )
596
644
 
597
- _, path = @helper.which_ceedling?( env:env, config:config, app_cfg:app_cfg )
598
-
599
645
  @helper.load_ceedling(
600
646
  config: config,
601
- rakefile_path: path,
647
+ rakefile_path: rakefile_path,
602
648
  default_tasks: app_cfg[:default_tasks]
603
649
  )
604
650
 
data/bin/cli_helper.rb CHANGED
@@ -11,10 +11,24 @@ require 'app_cfg'
11
11
  require 'ceedling/constants'
12
12
  require 'ceedling/exceptions'
13
13
  require 'ceedling/rake_app/rakefile_component_resolver'
14
+ require 'ceedling/filesystem/project_paths'
15
+ require 'ceedling/config/build_root_policy'
14
16
  require 'versionator' # Outside DIY context
15
17
 
16
18
  class CliHelper
17
19
 
20
+ # Where a documentation export writes the HTML bundle, within a project's docs/
21
+ DOCS_BUNDLE_DIR = 'ceedling'
22
+
23
+ # Directories a documentation export writes into a project's docs/, beside Ceedling's license
24
+ EXPORTED_DOCS_DIRS = [DOCS_BUNDLE_DIR, 'unity', 'cmock', 'c_exception'].freeze
25
+
26
+ # What a 1.0.x export also wrote into docs/: Ceedling's own pages, and its plugins' pages
27
+ LEGACY_EXPORTED_DOCS = %w[
28
+ BreakingChanges.md CODE_OF_CONDUCT.md CONTRIBUTING.md CeedlingPacket.md CeedlingUpgrade.md
29
+ Changelog.md PluginDevelopmentGuide.md ReleaseNotes.md ThrowTheSwitchCodingStandard.md plugins
30
+ ].freeze
31
+
18
32
  constructor :file_wrapper, :actionator, :config_walkinator, :path_validator, :rake_task_registry, :loginator, :reportinator, :system_wrapper, :ruby_expandinator
19
33
 
20
34
  def setup
@@ -106,84 +120,12 @@ class CliHelper
106
120
  end
107
121
 
108
122
 
109
- # Returns two value: (1) symbol :gem or :path and (2) path for Ceedling installation
110
- def which_ceedling?(env:, config:{}, app_cfg:)
111
- # Determine which Ceedling we're running (in priority)
112
- # 1. If there's an environment variable set, validate it, and return :gem or a path
113
- # 2. If :project ↳ :which_ceedling exists in the config, validate it, and return :gem or a path
114
- # 3. If there's a vendor/ceedling/ path in our working directory, return it as a path
115
- # 4. If nothing is set, default to :gem and return it
116
- # 5. Update app_cfg paths if not the gem
117
-
118
- # Nil for prioritized case checking logic blocks that follow
119
- which_ceedling = nil
120
-
121
- # Environment variable
122
- if !env['WHICH_CEEDLING'].nil?
123
- @loginator.console( " > Set which Ceedling using environment variable WHICH_CEEDLING" )
124
- which_ceedling = env['WHICH_CEEDLING'].strip()
125
- which_ceedling = :gem if (which_ceedling.casecmp( 'gem' ) == 0)
126
- end
127
-
128
- # Configuration file
129
- if which_ceedling.nil?
130
- value, _ = @config_walkinator.fetch_value( :project, :which_ceedling, hash:config )
131
- if !value.nil?
132
- which_ceedling = value.strip()
133
- @loginator.lazy( Verbosity::OBNOXIOUS ) { " > Set which Ceedling from config :project ↳ :which_ceedling => #{which_ceedling}" }
134
- which_ceedling = :gem if (which_ceedling.casecmp( 'gem' ) == 0)
135
- end
136
- end
137
-
138
- # Working directory
139
- if which_ceedling.nil?
140
- if @file_wrapper.directory?( 'vendor/ceedling' )
141
- which_ceedling = 'vendor/ceedling'
142
- @loginator.log( " > Set which Ceedling to be vendored installation", Verbosity::OBNOXIOUS )
143
- end
144
- end
145
-
146
- # Default to gem
147
- if which_ceedling.nil?
148
- which_ceedling = :gem
149
- @loginator.log( " > Defaulting to running Ceedling from Gem", Verbosity::OBNOXIOUS )
150
- end
151
-
152
- # If we're launching from the gem, return :gem and initial Rakefile path
153
- if which_ceedling == :gem
154
- @loginator.log( " > Launching Ceedling from #{app_cfg[:ceedling_root_path]}/", Verbosity::OBNOXIOUS )
155
- return which_ceedling, app_cfg[:ceedling_rakefile_filepath]
156
- end
157
-
158
- # Otherwise, handle which_ceedling as a base path
159
- ceedling_path = which_ceedling.dup()
160
- @path_validator.standardize_paths( ceedling_path )
161
- if !@file_wrapper.directory?( ceedling_path )
162
- raise "Configured Ceedling launch path #{ceedling_path}/ does not exist"
163
- end
164
-
165
- # Update Ceedling installation paths
166
- app_cfg.set_paths( ceedling_path )
167
-
168
- # Check updated Ceedling paths
169
- if !@file_wrapper.exist?( app_cfg[:ceedling_rakefile_filepath] )
170
- raise "Configured Ceedling launch path #{ceedling_path}/ contains no Ceedling installation"
171
- end
172
-
173
- # Update variable to full application start path
174
- ceedling_path = app_cfg[:ceedling_rakefile_filepath]
175
-
176
- @loginator.log( " > Launching Ceedling from #{app_cfg[:ceedling_root_path]}/", Verbosity::OBNOXIOUS )
177
-
178
- return :path, ceedling_path
179
- end
180
-
181
-
182
123
  def build_rake_task_registry(config:)
183
124
  paths = RakefileComponentResolver.resolve(
184
125
  config,
185
126
  CEEDLING_APPCFG[:ceedling_lib_path],
186
- CEEDLING_APPCFG[:ceedling_plugins_path]
127
+ CEEDLING_APPCFG[:ceedling_plugins_path],
128
+ expand: ->(path) { @ruby_expandinator.expand( path, source: ":plugins ↳ :load_paths" ) }
187
129
  )
188
130
 
189
131
  @registry.register_test_tasks( paths )
@@ -276,6 +218,11 @@ class CliHelper
276
218
 
277
219
  return '' if build_root.nil?
278
220
 
221
+ # Read as configuration reads it, after inline Ruby string expansion. One that expands to
222
+ # nothing would put the logs at the filesystem root, so it is refused here already.
223
+ build_root = ProjectPaths.standardize( @ruby_expandinator.expand( build_root.to_s, source: ':project ↳ :build_root' ) )
224
+ raise CeedlingException.new( BuildRootPolicy.message( build_root, 'names no directory' ) ) if build_root.empty?
225
+
279
226
  return File.join( build_root, DEFAULT_BUILD_LOGS_PATH )
280
227
  end
281
228
 
@@ -329,6 +276,11 @@ class CliHelper
329
276
  end
330
277
 
331
278
 
279
+ def release_task?(tasks:)
280
+ return tasks.any? { |task| @registry.task_is?( task, RakeTaskRegistry::TAG_RELEASE ) }
281
+ end
282
+
283
+
332
284
  def print_rake_tasks()
333
285
  # This all required digging into Rake internals a bit.
334
286
 
@@ -486,7 +438,7 @@ class CliHelper
486
438
 
487
439
 
488
440
  def copy_docs(ceedling_root, dest)
489
- docs_path_ceedling = File.join( dest, 'ceedling' )
441
+ docs_path_ceedling = File.join( dest, DOCS_BUNDLE_DIR )
490
442
 
491
443
  # Hash that will hold documentation copy paths
492
444
  # - Key: (modified) destination documentation path
@@ -532,9 +484,8 @@ class CliHelper
532
484
  end
533
485
 
534
486
  # If present copy internl HTML documentation bundle (site-local/) to docs/ceedling/
535
- site_local_path = File.join( ceedling_root, DOCS_SITE_LOCAL_PATH )
536
- if @file_wrapper.directory?( site_local_path )
537
- @actions.copy_directory( site_local_path, docs_path_ceedling, force: true )
487
+ if docs_bundle?( ceedling_root )
488
+ @actions.copy_directory( File.join( ceedling_root, DOCS_SITE_LOCAL_PATH ), docs_path_ceedling, force: true )
538
489
  else
539
490
  @loginator.console( "Internal HTML documentation bundle not found", LogLabels::WARNING )
540
491
  return
@@ -551,6 +502,32 @@ class CliHelper
551
502
  end
552
503
 
553
504
 
505
+ # Whether an installation holds the HTML documentation bundle. A `--local` copy carries none.
506
+ def docs_bundle?(ceedling_root)
507
+ return @file_wrapper.directory?( File.join( ceedling_root, DOCS_SITE_LOCAL_PATH ) )
508
+ end
509
+
510
+
511
+ # Whether a project's docs/ holds documentation an export wrote, in the layout of 1.1.0
512
+ # and later or of 1.0.x
513
+ def exported_docs?(docs_path)
514
+ return (EXPORTED_DOCS_DIRS + ['CeedlingPacket.md']).any? { |entry| @file_wrapper.exist?( File.join( docs_path, entry ) ) }
515
+ end
516
+
517
+
518
+ # Removes what an export wrote into a project's docs/, leaving everything else. An HTML
519
+ # bundle the source cannot replace is kept. The export overwrites its own license, so a
520
+ # license file here, which may be the project's, stays.
521
+ def remove_exported_docs(docs_path, keep_bundle:)
522
+ entries = EXPORTED_DOCS_DIRS + LEGACY_EXPORTED_DOCS
523
+ entries -= [DOCS_BUNDLE_DIR] if keep_bundle
524
+
525
+ entries.map { |entry| File.join( docs_path, entry ) }.each do |path|
526
+ @actions.remove_directory( path ) if @file_wrapper.exist?( path )
527
+ end
528
+ end
529
+
530
+
554
531
  def vendor_tools(ceedling_root, dest)
555
532
  vendor_path = File.join( dest, 'vendor', 'ceedling' )
556
533
 
@@ -575,6 +552,7 @@ class CliHelper
575
552
  'vendor/diy/lib/',
576
553
  'vendor/unity/auto/',
577
554
  'vendor/unity/src/',
555
+ 'vendor/unity/test/targets/', # Built-in mixins, which the vendored launcher validates
578
556
  ]
579
557
 
580
558
  # Copy necessary subcomponent dirs into project
@@ -0,0 +1,81 @@
1
+ # =========================================================================
2
+ # Ceedling - Test-Centered Build System for C
3
+ # ThrowTheSwitch.org
4
+ # Copyright (c) 2010-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
5
+ # SPDX-License-Identifier: MIT
6
+ # =========================================================================
7
+
8
+ require 'ceedling/constants'
9
+ require 'ceedling/installation'
10
+
11
+ # Decides which Ceedling installation runs a command, and points app_cfg's paths at it
12
+ class InstallationSelector
13
+
14
+ VENDOR_PATH = 'vendor/ceedling'
15
+
16
+ constructor :file_wrapper, :config_walkinator, :path_validator, :loginator
17
+
18
+ # Precedence:
19
+ # 1. The WHICH_CEEDLING environment variable
20
+ # 2. :project ↳ :which_ceedling in the configuration
21
+ # 3. A vendor/ceedling/ directory in the working directory, unless detect_vendor is off
22
+ # 4. The launcher's own installation
23
+ # Each is a path to an installation or `gem`, meaning the launcher's own.
24
+ def select(env:, app_cfg:, config: {}, detect_vendor: true)
25
+ which = from_environment( env ) || from_config( config )
26
+ which ||= from_vendor_directory() if detect_vendor
27
+
28
+ if which.nil? or which.casecmp?( 'gem' )
29
+ @loginator.log( " > Defaulting to running Ceedling from Gem", Verbosity::OBNOXIOUS ) if which.nil?
30
+ return use( app_cfg[:launcher_root_path], app_cfg )
31
+ end
32
+
33
+ return use( validate( which ), app_cfg )
34
+ end
35
+
36
+ private
37
+
38
+ def from_environment(env)
39
+ return nil if env['WHICH_CEEDLING'].nil?
40
+
41
+ @loginator.log( " > Set which Ceedling using environment variable WHICH_CEEDLING", Verbosity::OBNOXIOUS )
42
+ return env['WHICH_CEEDLING'].strip()
43
+ end
44
+
45
+ def from_config(config)
46
+ value, _ = @config_walkinator.fetch_value( :project, :which_ceedling, hash:config )
47
+ return nil if value.nil?
48
+
49
+ @loginator.lazy( Verbosity::OBNOXIOUS ) { " > Set which Ceedling from config :project ↳ :which_ceedling => #{value.strip()}" }
50
+ return value.strip()
51
+ end
52
+
53
+ def from_vendor_directory()
54
+ return nil if !@file_wrapper.directory?( VENDOR_PATH )
55
+
56
+ @loginator.log( " > Set which Ceedling to be vendored installation", Verbosity::OBNOXIOUS )
57
+ return VENDOR_PATH
58
+ end
59
+
60
+ # Returns the standardized path of an installation, raising if it holds none
61
+ def validate(which)
62
+ path = @path_validator.standardize_paths( which ).first
63
+ if !@file_wrapper.directory?( path )
64
+ raise "Configured Ceedling launch path #{path}/ does not exist"
65
+ end
66
+
67
+ if !@file_wrapper.exist?( Installation.new( path ).rakefile_path )
68
+ raise "Configured Ceedling launch path #{path}/ contains no Ceedling installation"
69
+ end
70
+
71
+ return path
72
+ end
73
+
74
+ def use(root, app_cfg)
75
+ app_cfg.set_paths( root )
76
+ @loginator.log( " > Launching Ceedling from #{app_cfg[:ceedling_root_path]}/", Verbosity::OBNOXIOUS )
77
+
78
+ return Installation.new( root )
79
+ end
80
+
81
+ end