ceedling 1.2.1 → 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.
- checksums.yaml +4 -4
- data/GIT_COMMIT_SHA +1 -1
- data/README.md +11 -9
- data/Rakefile +2 -1
- data/assets/features/ceedling +1 -1
- data/assets/fixtures/test_source_file_duplicate_basenames/test_calc_typo.c +14 -0
- data/assets/fixtures/tests_with_duplicate_test_names/test_foo.c +21 -0
- data/bin/actionator.rb +6 -12
- data/bin/app_cfg.rb +14 -1
- data/bin/ceedling +13 -3
- data/bin/cli.rb +25 -6
- data/bin/cli_handler.rb +113 -73
- data/bin/cli_helper.rb +51 -78
- data/bin/installation_selector.rb +81 -0
- data/bin/launchinator.rb +69 -0
- data/bin/mixin_resolvinator.rb +26 -36
- data/bin/objects.yml +13 -0
- data/bin/path_validator.rb +25 -29
- data/bin/versionator.rb +47 -48
- data/ceedling.gemspec +19 -15
- data/docs/BreakingChanges.md +70 -1
- data/docs/Changelog.md +74 -3
- data/docs/KnownIssues.md +90 -4
- data/docs/ReleaseNotes.md +13 -0
- data/lib/ceedling/build_log_writer.rb +33 -0
- data/lib/ceedling/config/build_root_policy.rb +70 -0
- data/lib/ceedling/config/configurator.rb +14 -16
- data/lib/ceedling/config/configurator_builder.rb +58 -28
- data/lib/ceedling/config/configurator_paths_validator.rb +179 -0
- data/lib/ceedling/config/configurator_plugins.rb +1 -1
- data/lib/ceedling/config/configurator_setup.rb +15 -28
- data/lib/ceedling/config/configurator_validator.rb +1 -110
- data/lib/ceedling/defaults.rb +4 -4
- data/lib/ceedling/dependencies/README.md +18 -16
- data/lib/ceedling/dependencies/dependency_cache_store.rb +20 -3
- data/lib/ceedling/dependencies/dependency_hasher.rb +35 -1
- data/lib/ceedling/filename_extension.rb +7 -1
- data/lib/ceedling/filesystem/FILE_TREE.md +253 -0
- data/lib/ceedling/filesystem/PATH_HANDLING.md +304 -0
- data/lib/ceedling/filesystem/README.md +41 -0
- data/lib/ceedling/filesystem/build_subpath.rb +102 -0
- data/lib/ceedling/filesystem/destination_collision.rb +25 -0
- data/lib/ceedling/{file_finder.rb → filesystem/file_finder.rb} +159 -104
- data/lib/ceedling/{file_finder_helper.rb → filesystem/file_finder_helper.rb} +36 -31
- data/lib/ceedling/filesystem/file_path_collection_utils.rb +183 -0
- data/lib/ceedling/{file_path_utils.rb → filesystem/file_path_utils.rb} +108 -97
- data/lib/ceedling/{file_system_wrapper.rb → filesystem/file_system_wrapper.rb} +6 -5
- data/lib/ceedling/filesystem/file_tree.rb +241 -0
- data/lib/ceedling/{file_wrapper.rb → filesystem/file_wrapper.rb} +45 -38
- data/lib/ceedling/filesystem/path_exclusions.rb +30 -0
- data/lib/ceedling/{path_matcher.rb → filesystem/path_matcher.rb} +27 -23
- data/lib/ceedling/{path_mirror.rb → filesystem/path_mirror.rb} +19 -18
- data/lib/ceedling/filesystem/path_spellings.rb +55 -0
- data/lib/ceedling/filesystem/project_paths.rb +184 -0
- data/lib/ceedling/filesystem/working_dir.rb +40 -0
- data/lib/ceedling/generators/generator.rb +5 -6
- data/lib/ceedling/generators/generator_partials.rb +1 -1
- data/lib/ceedling/generators/generator_test_results_backtrace.rb +7 -7
- data/lib/ceedling/handoff.rb +121 -0
- data/lib/ceedling/includes/include_factory.rb +3 -3
- data/lib/ceedling/includes/include_pathinator.rb +67 -10
- data/lib/ceedling/includes/includes.rb +1 -1
- data/lib/ceedling/installation.rb +92 -0
- data/lib/ceedling/library_resolver.rb +99 -0
- data/lib/ceedling/objects.yml +23 -2
- data/lib/ceedling/partials/partializer.rb +4 -4
- data/lib/ceedling/partials/partializer_config.rb +3 -1
- data/lib/ceedling/plugins/report_log_writer_plugin.rb +3 -5
- data/lib/ceedling/preprocess/preprocessinator_file_assembler.rb +1 -1
- data/lib/ceedling/preprocess/preprocessinator_includes_handler.rb +1 -1
- data/lib/ceedling/preprocess/preprocessinator_line_marker_includes_extractor.rb +1 -1
- data/lib/ceedling/rake_app/rakefile_component_resolver.rb +10 -17
- data/lib/ceedling/rakefile.rb +15 -1
- data/lib/ceedling/rakefiles/base/tasks_base.rake +1 -1
- data/lib/ceedling/rakefiles/release/rules_release.rake +4 -7
- data/lib/ceedling/release_invoker/release_build_executor.rb +33 -44
- data/lib/ceedling/release_invoker/release_build_planner.rb +14 -6
- data/lib/ceedling/reportinator.rb +3 -4
- data/lib/ceedling/setupinator.rb +94 -90
- data/lib/ceedling/test_context_extractor.rb +5 -1
- data/lib/ceedling/test_invoker/PIPELINE.md +9 -7
- data/lib/ceedling/test_invoker/mock_locator.rb +60 -2
- data/lib/ceedling/test_invoker/partials_manager.rb +12 -0
- data/lib/ceedling/test_invoker/standin_headerinator.rb +22 -13
- data/lib/ceedling/test_invoker/test_build_executor.rb +24 -40
- data/lib/ceedling/test_invoker/test_build_planner.rb +37 -18
- data/lib/ceedling/test_invoker/test_build_setup.rb +17 -12
- data/lib/ceedling/test_invoker/test_build_validations.rb +16 -31
- data/lib/ceedling/test_invoker/test_file_preprocessinator.rb +1 -1
- data/lib/ceedling/test_invoker/test_invoker.rb +6 -1
- data/lib/ceedling/test_invoker/test_pipeline_helpers.rb +1 -1
- data/lib/ceedling/test_invoker/test_source_file_directive_resolver.rb +40 -20
- data/lib/ceedling/tool_executor.rb +9 -3
- data/lib/ceedling/yaml_wrapper.rb +3 -2
- data/lib/version.rb +1 -1
- data/plugins/bullseye/config/defaults_bullseye.rb +1 -1
- data/plugins/bullseye/lib/bullseye.rb +9 -7
- data/plugins/cppcheck/config/defaults_cppcheck.rb +1 -1
- data/plugins/dependencies/config/defaults.yml +6 -6
- data/plugins/dependencies/dependencies.rake +4 -1
- data/plugins/dependencies/lib/dependencies.rb +18 -8
- data/plugins/dependencies/lib/dependency_spec.rb +17 -5
- data/plugins/fff/lib/fff.rb +45 -39
- data/plugins/fff/spec/fff_cmock_wrapper_spec.rb +128 -0
- data/plugins/gcov/config/defaults_gcov.rb +1 -1
- data/plugins/gcov/lib/console_reportinator.rb +4 -18
- data/plugins/gcov/lib/gcov.rb +9 -2
- data/plugins/gcov/lib/gcovr_reportinator.rb +8 -40
- data/plugins/gcov/lib/gcovr_thresholds.rb +74 -0
- data/plugins/gcov/lib/reportgenerator_reportinator.rb +1 -1
- data/plugins/module_generator/lib/module_generator.rb +3 -3
- data/plugins/report_tests_teamcity_stdout/lib/report_tests_teamcity_stdout.rb +53 -80
- data/plugins/sanitize/lib/sanitize_records.rb +3 -6
- data/plugins/valgrind/lib/valgrind.rb +14 -7
- data/site-local/configuration/reference/cmock.html +2 -1
- data/site-local/configuration/reference/files.html +9 -3
- data/site-local/configuration/reference/libraries.html +21 -3
- data/site-local/configuration/reference/paths.html +29 -6
- data/site-local/configuration/reference/project.html +17 -7
- data/site-local/configuration/reference/release-build.html +2 -0
- data/site-local/configuration/reference/tools.html +9 -0
- data/site-local/configuration/which-ceedling.html +377 -17
- data/site-local/development/releases.html +5 -1
- data/site-local/development/workflow.html +48 -43
- data/site-local/getting-started/builds.html +2 -0
- data/site-local/getting-started/command-line.html +56 -4
- data/site-local/plugins/dependencies.html +6 -3
- data/site-local/plugins/fff.html +42 -11
- data/site-local/plugins/gcov/gcovr.html +15 -12
- data/site-local/plugins/gcov/setup.html +2 -1
- data/site-local/plugins/report-tests-raw-output-log.html +3 -1
- data/site-local/plugins/report-tests-teamcity-stdout.html +6 -3
- data/site-local/plugins/sanitize.html +7 -6
- data/site-local/plugins/valgrind.html +8 -7
- data/site-local/project/upgrade.html +3 -0
- data/site-local/reference/command-line.html +9 -2
- data/site-local/sitemap.xml.gz +0 -0
- data/site-local/snapshot/plugins/bullseye/config/defaults_bullseye.rb +1 -1
- data/site-local/snapshot/plugins/gcov/config/defaults_gcov.rb +1 -1
- data/site-local/testing-guide/conventions.html +53 -0
- data/spec/integration/actionator_file_operations_spec.rb +91 -1
- data/spec/integration/compile_commands_json_db_spec.rb +1 -1
- data/spec/integration/configurator_validation_spec.rb +1 -1
- data/spec/integration/dependencies/dependency_tracker_cache_hardening_spec.rb +26 -0
- data/spec/integration/dependencies/dependency_tracker_core_spec.rb +22 -0
- data/spec/integration/launcher_handoff_spec.rb +297 -0
- data/spec/integration/mixin_loading_spec.rb +1 -1
- data/spec/integration/module_generator_spec.rb +3 -3
- data/spec/integration/nested_test_artifacts_spec.rb +99 -0
- data/spec/integration/partials_module_resolution_spec.rb +7 -4
- data/spec/integration/path_intake_scenarios_spec.rb +101 -0
- data/spec/integration/path_scenarios_spec.rb +322 -0
- data/spec/integration/quote_include_isolator_spec.rb +1 -1
- data/spec/integration/report_build_warnings_log_spec.rb +1 -1
- data/spec/integration/report_tests_log_factory_spec.rb +1 -1
- data/spec/integration/test_executable_manifest_spec.rb +1 -1
- data/spec/integration/test_includes_extractinator_spec.rb +2 -1
- data/spec/integration/test_naming_spec.rb +198 -0
- data/spec/integration/test_source_file_checks_spec.rb +166 -0
- data/spec/integration/tool_validator_spec.rb +1 -1
- data/spec/integration/upgrade_docs_spec.rb +84 -0
- data/spec/integration/vendor_copy_transient_io_retry_spec.rb +74 -5
- data/spec/support/file_tree_helper.rb +88 -0
- data/spec/support/integration/configurator_integration_helper.rb +6 -6
- data/spec/support/integration/dependency_tracker_integration_helper.rb +1 -1
- data/spec/support/integration/partials_generation_integration_helper.rb +2 -2
- data/spec/support/integration/path_scenario_harness.rb +173 -0
- data/spec/support/integration/spec_integration_helper.rb +1 -1
- data/spec/support/integration/test_includes_harness.rb +13 -2
- data/spec/support/spec_helper.rb +2 -0
- data/spec/support/system/spec_system_helper.rb +7 -6
- data/spec/support/system/system_context.rb +21 -3
- data/spec/support/working_dir_tracking.rb +49 -0
- data/spec/system/build_output_mirroring_spec.rb +2 -2
- data/spec/system/conditional_mock_includes_spec.rb +1 -1
- data/spec/system/delta_builds_spec.rb +137 -11
- data/spec/system/gcov_deployment_spec.rb +1 -0
- data/spec/system/header_include_path_validation_spec.rb +4 -4
- data/spec/system/launcher_handoff_spec.rb +82 -0
- data/spec/system/mock_include_folders_spec.rb +91 -0
- data/spec/system/parent_directory_reference_spec.rb +5 -3
- data/spec/system/path_handling_probes_spec.rb +192 -0
- data/spec/system/preprocessing_parameterized_tests_spec.rb +1 -1
- data/spec/system/rake_release_task_path_disambiguation_spec.rb +6 -6
- data/spec/system/rake_test_task_path_disambiguation_spec.rb +85 -0
- data/spec/system/special_path_characters_spec.rb +86 -0
- data/spec/system/support/common_test_cases.rb +23 -21
- data/spec/system/support/gcov_common_test_cases.rb +37 -9
- data/spec/system/support/sanitize_common_test_cases.rb +2 -2
- data/spec/system/support/valgrind_common_test_cases.rb +12 -12
- data/spec/system/test_pipeline_stop_points_spec.rb +4 -4
- data/spec/system/test_runner_system_include_spec.rb +1 -1
- data/spec/system/test_source_file_directive_spec.rb +34 -5
- data/spec/units/bin/actionator_spec.rb +14 -17
- data/spec/units/bin/app_cfg_spec.rb +37 -0
- data/spec/units/bin/cli_handler_spec.rb +282 -6
- data/spec/units/bin/cli_helper_spec.rb +116 -45
- data/spec/units/bin/installation_selector_spec.rb +114 -0
- data/spec/units/bin/launchinator_spec.rb +171 -0
- data/spec/units/bin/path_validator_spec.rb +10 -0
- data/spec/units/bin/versionator_spec.rb +38 -6
- data/spec/units/build_log_writer_spec.rb +57 -0
- data/spec/units/config/build_root_policy_spec.rb +61 -0
- data/spec/units/config/configurator_builder_spec.rb +37 -6
- data/spec/units/config/configurator_paths_validator_spec.rb +292 -0
- data/spec/units/config/configurator_setup_spec.rb +9 -65
- data/spec/units/config/configurator_spec.rb +27 -5
- data/spec/units/config/configurator_validator_spec.rb +1 -172
- data/spec/units/default_tools_quoting_spec.rb +83 -0
- data/spec/units/dependencies/dependency_cache_store_spec.rb +33 -2
- data/spec/units/dependencies/dependency_debug_tree_spec.rb +1 -1
- data/spec/units/dependencies/dependency_hasher_spec.rb +42 -1
- data/spec/units/dependencies/dependency_path_normalizer_spec.rb +1 -1
- data/spec/units/dependencies/dependency_tracker_spec.rb +3 -1
- data/spec/units/filename_extension_spec.rb +11 -0
- data/spec/units/filesystem/build_subpath_spec.rb +122 -0
- data/spec/units/filesystem/destination_collision_spec.rb +30 -0
- data/spec/units/{file_finder_helper_spec.rb → filesystem/file_finder_helper_spec.rb} +46 -1
- data/spec/units/{file_finder_spec.rb → filesystem/file_finder_spec.rb} +188 -22
- data/spec/units/{file_path_collection_utils_spec.rb → filesystem/file_path_collection_utils_spec.rb} +181 -1
- data/spec/units/{file_path_utils_spec.rb → filesystem/file_path_utils_spec.rb} +204 -87
- data/spec/units/filesystem/file_system_wrapper_spec.rb +33 -0
- data/spec/units/filesystem/file_tree_spec.rb +511 -0
- data/spec/units/filesystem/file_tree_windows_spec.rb +78 -0
- data/spec/units/{file_wrapper_spec.rb → filesystem/file_wrapper_spec.rb} +95 -12
- data/spec/units/{path_matcher_spec.rb → filesystem/path_matcher_spec.rb} +12 -1
- data/spec/units/{path_mirror_spec.rb → filesystem/path_mirror_spec.rb} +32 -4
- data/spec/units/filesystem/project_paths_spec.rb +147 -0
- data/spec/units/filesystem/working_dir_spec.rb +71 -0
- data/spec/units/generators/generator_spec.rb +12 -6
- data/spec/units/generators/generator_test_results_backtrace_spec.rb +50 -46
- data/spec/units/generators/generator_test_results_spec.rb +1 -1
- data/spec/units/handoff_spec.rb +205 -0
- data/spec/units/includes/include_factory_spec.rb +3 -3
- data/spec/units/includes/include_pathinator_spec.rb +46 -0
- data/spec/units/installation_spec.rb +228 -0
- data/spec/units/library_resolver_spec.rb +157 -0
- data/spec/units/mock_locator_spec.rb +76 -1
- data/spec/units/partials/partializer_config_spec.rb +7 -0
- data/spec/units/partials/partializer_spec.rb +1 -0
- data/spec/units/partials_manager_spec.rb +17 -0
- data/spec/units/plugins/bullseye_spec.rb +15 -2
- data/spec/units/plugins/console_reportinator_spec.rb +18 -20
- data/spec/units/plugins/dependencies_spec.rb +33 -7
- data/spec/units/plugins/dependency_spec_spec.rb +17 -0
- data/spec/units/plugins/gcov_spec.rb +28 -3
- data/spec/units/plugins/gcovr_reportinator_spec.rb +19 -47
- data/spec/units/plugins/gcovr_thresholds_spec.rb +95 -0
- data/spec/units/plugins/module_generator_spec.rb +5 -5
- data/spec/units/plugins/report_build_warnings_log_spec.rb +3 -3
- data/spec/units/plugins/report_log_writer_plugin_spec.rb +10 -1
- data/spec/units/plugins/report_tests_raw_output_log_spec.rb +13 -2
- data/spec/units/plugins/report_tests_teamcity_stdout_spec.rb +77 -3
- data/spec/units/plugins/reportgenerator_reportinator_spec.rb +1 -1
- data/spec/units/plugins/sanitize_records_spec.rb +3 -1
- data/spec/units/plugins/sanitize_spec.rb +1 -1
- data/spec/units/plugins/valgrind_spec.rb +23 -8
- data/spec/units/preprocess/preprocessinator_comment_stripper_spec.rb +1 -1
- data/spec/units/rake_app/rakefile_component_resolver_spec.rb +21 -0
- data/spec/units/release_build_executor_spec.rb +53 -14
- data/spec/units/release_build_planner_spec.rb +15 -3
- data/spec/units/reportinator_spec.rb +5 -5
- data/spec/units/standin_headerinator_spec.rb +31 -1
- data/spec/units/test_build_executor_spec.rb +65 -3
- data/spec/units/test_build_planner_spec.rb +104 -2
- data/spec/units/test_build_setup_spec.rb +96 -12
- data/spec/units/test_context_extractor_spec.rb +25 -0
- data/spec/units/test_file_preprocessinator_spec.rb +17 -1
- data/spec/units/test_includes_extractinator_spec.rb +5 -1
- data/spec/units/test_invoker/objects_wiring_spec.rb +6 -3
- data/spec/units/test_invoker_spec.rb +14 -1
- data/spec/units/test_source_file_directive_resolver_spec.rb +38 -7
- data/spec/units/tool_executor_spec.rb +26 -0
- data/spec/units/yaml_wrapper_spec.rb +11 -0
- metadata +109 -25
- data/lib/ceedling/file_path_collection_utils.rb +0 -164
|
@@ -7,11 +7,13 @@
|
|
|
7
7
|
|
|
8
8
|
require 'rubygems'
|
|
9
9
|
require 'rake' # for ext() method
|
|
10
|
-
require 'ceedling/file_path_utils' # for class methods
|
|
10
|
+
require 'ceedling/filesystem/file_path_utils' # for class methods
|
|
11
|
+
require 'ceedling/filesystem/project_paths'
|
|
11
12
|
require 'ceedling/defaults'
|
|
12
13
|
require 'ceedling/constants' # for Verbosity constants class & base file paths
|
|
13
14
|
require 'ceedling/filename_extension'
|
|
14
15
|
require 'ceedling/rake_app/rakefile_component_resolver'
|
|
16
|
+
require 'ceedling/config/build_root_policy'
|
|
15
17
|
|
|
16
18
|
class ConfiguratorBuilder
|
|
17
19
|
|
|
@@ -130,17 +132,18 @@ class ConfiguratorBuilder
|
|
|
130
132
|
|
|
131
133
|
|
|
132
134
|
# A release is named by :release_build ↳ :output, or by default and the executable
|
|
133
|
-
# extension. Its map file shares its name.
|
|
135
|
+
# extension. Its map file shares its name. A relative name is below the release build root,
|
|
136
|
+
# and an absolute one names the release itself.
|
|
134
137
|
def set_release_target(in_hash)
|
|
135
138
|
return {} if (not in_hash[:project_release_build])
|
|
136
139
|
|
|
137
|
-
output = in_hash[:release_build_output]
|
|
140
|
+
output = in_hash[:release_build_output]&.then { |name| ProjectPaths.standardize( name ) }
|
|
138
141
|
target = output || DEFAULT_RELEASE_TARGET_NAME.ext( in_hash[:extension_executable].primary )
|
|
139
142
|
map = (output || DEFAULT_RELEASE_TARGET_NAME).ext( in_hash[:extension_map].primary )
|
|
140
143
|
|
|
141
144
|
# tempted to make a helper method in file_path_utils? stop right there, pal. you'll introduce a cyclical dependency
|
|
142
145
|
root = in_hash[:project_build_release_root]
|
|
143
|
-
return { project_release_build_target:
|
|
146
|
+
return { project_release_build_target: release_place( root, target ), project_release_build_map: release_place( root, map ) }
|
|
144
147
|
end
|
|
145
148
|
|
|
146
149
|
|
|
@@ -163,14 +166,28 @@ class ConfiguratorBuilder
|
|
|
163
166
|
end
|
|
164
167
|
|
|
165
168
|
|
|
166
|
-
# Every :paths entry becomes a collection of the directories its globs name
|
|
169
|
+
# Every :paths entry becomes a collection of the directories its globs name, leaving out
|
|
170
|
+
# the build root, which a root above it (`../**`, `./**`) would otherwise sweep in, and
|
|
171
|
+
# the directories Ceedling creates
|
|
167
172
|
def expand_all_path_globs(in_hash)
|
|
168
173
|
path_keys = in_hash.keys.select { |key| key.to_s.start_with?( 'paths' ) }
|
|
169
174
|
|
|
170
|
-
return path_keys.to_h { |key| [:"collection_#{key}", @file_path_collection_utils.collect_paths( in_hash[key] )] }
|
|
175
|
+
return path_keys.to_h { |key| [:"collection_#{key}", @file_path_collection_utils.collect_paths( in_hash[key], **build_exclusions( in_hash ) )] }
|
|
171
176
|
end
|
|
172
177
|
|
|
173
178
|
|
|
179
|
+
# The roots build files mirror below, each spelled canonically: those of :paths ↳ :include,
|
|
180
|
+
# for a header's source by convention, and those every header is collected from
|
|
181
|
+
def collect_mirror_roots(in_hash)
|
|
182
|
+
include = Array( in_hash[:paths_include] )
|
|
183
|
+
headers = Array( in_hash[:paths_test] ) + Array( in_hash[:paths_support] ) + include
|
|
184
|
+
|
|
185
|
+
return {
|
|
186
|
+
:collection_mirror_roots_include => @file_path_collection_utils.collect_mirror_roots( include ),
|
|
187
|
+
:collection_mirror_roots_headers => @file_path_collection_utils.collect_mirror_roots( headers )
|
|
188
|
+
}
|
|
189
|
+
end
|
|
190
|
+
|
|
174
191
|
def collect_source_and_include_paths(in_hash)
|
|
175
192
|
return {
|
|
176
193
|
:collection_paths_source_and_include =>
|
|
@@ -228,7 +245,7 @@ class ConfiguratorBuilder
|
|
|
228
245
|
end
|
|
229
246
|
|
|
230
247
|
# Add / subtract files via :files ↳ :test
|
|
231
|
-
tests = file_collection( patterns, in_hash[:files_test] )
|
|
248
|
+
tests = file_collection( in_hash, patterns, in_hash[:files_test] )
|
|
232
249
|
return { :collection_all_tests => tests }, tests
|
|
233
250
|
end
|
|
234
251
|
|
|
@@ -242,19 +259,16 @@ class ConfiguratorBuilder
|
|
|
242
259
|
paths = in_hash[:collection_paths_source] + in_hash[:collection_paths_support]
|
|
243
260
|
|
|
244
261
|
# Add / subtract files via :files ↳ :assembly
|
|
245
|
-
return { :collection_all_assembly => file_collection( code_patterns( paths, in_hash[:extension_assembly] ), in_hash[:files_assembly] ) }
|
|
262
|
+
return { :collection_all_assembly => file_collection( in_hash, code_patterns( paths, in_hash[:extension_assembly] ), in_hash[:files_assembly] ) }
|
|
246
263
|
end
|
|
247
264
|
|
|
248
265
|
|
|
249
|
-
# Source files, less any test files that overlapping test and source paths
|
|
266
|
+
# Source files, less any test files that overlapping test and source paths, or :files
|
|
267
|
+
# revisions, also matched
|
|
250
268
|
def collect_source(in_hash, test_list)
|
|
251
|
-
sources = file_list( code_patterns( in_hash[:collection_paths_source], in_hash[:extension_source] ) )
|
|
252
|
-
|
|
253
|
-
mixed_in = test_list.select { |test| sources.include?( test ) }
|
|
254
|
-
exclude_tests( sources, mixed_in ) unless mixed_in.empty?
|
|
255
|
-
|
|
256
269
|
# Add / subtract files via :files ↳ :source
|
|
257
|
-
|
|
270
|
+
sources = file_collection( in_hash, code_patterns( in_hash[:collection_paths_source], in_hash[:extension_source] ), in_hash[:files_source] )
|
|
271
|
+
return { :collection_all_source => without_tests( sources, test_list ) }
|
|
258
272
|
end
|
|
259
273
|
|
|
260
274
|
|
|
@@ -262,12 +276,12 @@ class ConfiguratorBuilder
|
|
|
262
276
|
paths = in_hash[:collection_paths_test] + in_hash[:collection_paths_support] + in_hash[:collection_paths_include]
|
|
263
277
|
|
|
264
278
|
# Add / subtract files via :files ↳ :include
|
|
265
|
-
return { :collection_all_headers => file_collection( code_patterns( paths, in_hash[:extension_header] ), in_hash[:files_include] ) }
|
|
279
|
+
return { :collection_all_headers => file_collection( in_hash, code_patterns( paths, in_hash[:extension_header] ), in_hash[:files_include] ) }
|
|
266
280
|
end
|
|
267
281
|
|
|
268
282
|
|
|
269
283
|
# Source files, plus CException's when exceptions are in use and assembly files when the
|
|
270
|
-
# release build assembles
|
|
284
|
+
# release build assembles, less any test file. Source collection already warned of those.
|
|
271
285
|
def collect_release_build_input(in_hash)
|
|
272
286
|
assembly = in_hash[:release_build_use_assembly]
|
|
273
287
|
vendor = in_hash[:project_use_exceptions] ? [in_hash[:project_build_vendor_cexception_path]] : []
|
|
@@ -275,7 +289,7 @@ class ConfiguratorBuilder
|
|
|
275
289
|
|
|
276
290
|
# Add / subtract files via :files ↳ :source & :files ↳ :assembly
|
|
277
291
|
revisions = in_hash[:files_source] + (assembly ? in_hash[:files_assembly] : [])
|
|
278
|
-
return { :collection_release_build_input => file_collection( patterns, revisions ) }
|
|
292
|
+
return { :collection_release_build_input => without_tests( file_collection( in_hash, patterns, revisions ), in_hash[:collection_all_tests], warn: false ) }
|
|
279
293
|
end
|
|
280
294
|
|
|
281
295
|
|
|
@@ -285,7 +299,7 @@ class ConfiguratorBuilder
|
|
|
285
299
|
paths = in_hash[:collection_paths_test] + in_hash[:collection_paths_support] + in_hash[:collection_paths_source]
|
|
286
300
|
patterns = vendor_patterns( test_vendor_paths( in_hash ) ) + code_patterns( paths, *code_extensions( in_hash, assembly ) )
|
|
287
301
|
|
|
288
|
-
return { :collection_existing_test_build_input => file_collection( patterns, test_build_revisions( in_hash, assembly ) ) }
|
|
302
|
+
return { :collection_existing_test_build_input => file_collection( in_hash, patterns, test_build_revisions( in_hash, assembly ) ) }
|
|
289
303
|
end
|
|
290
304
|
|
|
291
305
|
|
|
@@ -306,7 +320,7 @@ class ConfiguratorBuilder
|
|
|
306
320
|
patterns = code_patterns( in_hash[:collection_paths_support], *extensions )
|
|
307
321
|
|
|
308
322
|
# Add / subtract files via :files ↳ :support
|
|
309
|
-
sources = file_collection( patterns, in_hash[:files_support] ).to_a
|
|
323
|
+
sources = file_collection( in_hash, patterns, in_hash[:files_support] ).to_a
|
|
310
324
|
objects = sources.map { |file| File.basename( file ).ext( in_hash[:extension_object].primary ) }
|
|
311
325
|
|
|
312
326
|
return { :collection_all_support => sources, :collection_test_fixture_extra_link_objects => objects }
|
|
@@ -325,6 +339,11 @@ class ConfiguratorBuilder
|
|
|
325
339
|
|
|
326
340
|
private
|
|
327
341
|
|
|
342
|
+
# A relative release name is below the release build root, and an absolute one names itself
|
|
343
|
+
def release_place(root, name)
|
|
344
|
+
return ProjectPaths.absolute?( name ) ? name : File.join( root, name )
|
|
345
|
+
end
|
|
346
|
+
|
|
328
347
|
def flatten_section(section, value)
|
|
329
348
|
case value
|
|
330
349
|
when nil then {}
|
|
@@ -443,8 +462,18 @@ class ConfiguratorBuilder
|
|
|
443
462
|
end
|
|
444
463
|
|
|
445
464
|
# Files matching `patterns`, revised by a :files list of additions and removals
|
|
446
|
-
def file_collection(patterns, revisions)
|
|
447
|
-
return
|
|
465
|
+
def file_collection(in_hash, patterns, revisions)
|
|
466
|
+
return revised( in_hash, file_list( patterns ), revisions )
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
# A :files glob adds nothing from the build root it is based above, and no :files entry
|
|
470
|
+
# adds anything from the directories Ceedling creates
|
|
471
|
+
def revised(in_hash, list, revisions)
|
|
472
|
+
return @file_path_collection_utils.revise_filelist( list, revisions, **build_exclusions( in_hash ) )
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
def build_exclusions(in_hash)
|
|
476
|
+
return { exclude: [in_hash[:project_build_root]].compact, reserved: BuildRootPolicy.reserved( in_hash ) }
|
|
448
477
|
end
|
|
449
478
|
|
|
450
479
|
# FileList expands its patterns lazily, so they are expanded here
|
|
@@ -454,12 +483,13 @@ class ConfiguratorBuilder
|
|
|
454
483
|
return list.resolve()
|
|
455
484
|
end
|
|
456
485
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
)
|
|
486
|
+
# `files` less any of `tests`, compared as collected, warning of any
|
|
487
|
+
def without_tests(files, tests, warn: true)
|
|
488
|
+
mixed_in = files.to_a & tests.to_a
|
|
489
|
+
return files if mixed_in.empty?
|
|
490
|
+
|
|
491
|
+
@loginator.log( 'Test file paths and source file paths overlap -- test files have been filtered out of the source file collection', Verbosity::COMPLAIN ) if warn
|
|
492
|
+
return @file_wrapper.instantiate_file_list_literal( files.to_a - mixed_in ).resolve()
|
|
463
493
|
end
|
|
464
494
|
|
|
465
495
|
end
|
|
@@ -0,0 +1,179 @@
|
|
|
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/filesystem/file_path_utils' # for glob handling class methods
|
|
10
|
+
require 'ceedling/filesystem/project_paths'
|
|
11
|
+
require 'ceedling/config/build_root_policy'
|
|
12
|
+
|
|
13
|
+
# Checks the paths a project file names against the filesystem: each :paths and :files
|
|
14
|
+
# entry, and paths named singly
|
|
15
|
+
class ConfiguratorPathsValidator
|
|
16
|
+
|
|
17
|
+
constructor :config_walkinator, :file_wrapper, :loginator, :reportinator
|
|
18
|
+
|
|
19
|
+
# Walk into config hash. verify existence of path(s) at given key depth.
|
|
20
|
+
# Paths are either full simple paths or a simple portion of a path up to a glob.
|
|
21
|
+
def validate_path_list(config, *keys)
|
|
22
|
+
list, depth = @config_walkinator.fetch_value( *keys, hash:config )
|
|
23
|
+
return false if list.nil?
|
|
24
|
+
|
|
25
|
+
# Trimming add/subtract notation and glob specifiers leaves nothing of a path that
|
|
26
|
+
# begins with a glob, so there is nothing to check
|
|
27
|
+
missing = checked_bases( list ).reject { |path| path.empty? or @file_wrapper.exist?( path ) }
|
|
28
|
+
|
|
29
|
+
walk = @reportinator.generate_config_walk( keys, depth )
|
|
30
|
+
missing.each { |path| log_error( "Config path #{walk} => '#{path}' does not exist in the filesystem." ) }
|
|
31
|
+
|
|
32
|
+
return missing.empty?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# Validate :paths entries, exercising each entry as Ceedling directory glob (variation of Ruby glob)
|
|
37
|
+
def validate_paths_entries(config, key)
|
|
38
|
+
return validate_entries( config, :paths, key ) { |entry, walk, build_root| valid_paths_entry?( entry, walk, build_root ) }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# Validate :files entries, exercising each entry as FileList glob
|
|
43
|
+
def validate_files_entries(config, key)
|
|
44
|
+
return validate_entries( config, :files, key ) { |entry, walk, build_root| valid_files_entry?( entry, walk, build_root ) }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# A build root of its own, warning of each :paths and :files entry within it (BuildRootPolicy)
|
|
49
|
+
def validate_build_root(config)
|
|
50
|
+
root = config[:project][:build_root].to_s
|
|
51
|
+
problem = BuildRootPolicy.problem( root )
|
|
52
|
+
log_error( BuildRootPolicy.message( root, problem ) ) unless problem.nil?
|
|
53
|
+
return false unless problem.nil?
|
|
54
|
+
|
|
55
|
+
BuildRootPolicy.warnings( root, config ) { |keys| @reportinator.generate_config_walk( keys ) }.each { |warning| log_complaint( warning ) }
|
|
56
|
+
return true
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
# Simple path verification
|
|
61
|
+
def validate_filepath_simple(path, *keys)
|
|
62
|
+
return true if @file_wrapper.exist?( path )
|
|
63
|
+
|
|
64
|
+
walk = @reportinator.generate_config_walk( keys, keys.size )
|
|
65
|
+
log_error( "Config path '#{path}' associated with #{walk} does not exist in the filesystem." )
|
|
66
|
+
return false
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
### Private ###
|
|
70
|
+
|
|
71
|
+
private
|
|
72
|
+
|
|
73
|
+
# Each entry of one :paths or :files list, usable and passing `check`
|
|
74
|
+
def validate_entries(config, section, key)
|
|
75
|
+
list, _ = @config_walkinator.fetch_value( section, key, hash:config )
|
|
76
|
+
return false if list.nil?
|
|
77
|
+
|
|
78
|
+
walk = @reportinator.generate_config_walk( [section, key] )
|
|
79
|
+
build_root = config.dig( :project, :build_root )
|
|
80
|
+
return list.map { |entry| usable_entry?( entry, walk ) && yield( entry, walk, build_root ) }.all?
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Each additive entry's path up to its first glob. An entry YAML read as something other
|
|
84
|
+
# than a string, and a `-:` entry, which may name nothing, are left to the entries validation.
|
|
85
|
+
def checked_bases(list)
|
|
86
|
+
return list.grep( String ).select { |path| FilePathUtils.add_path?( path ) }.map { |path| FilePathUtils::no_decorators( path ) }
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# A :paths or :files entry that names no path, or wraps its path in quotes, usually
|
|
90
|
+
# quotes only the path after its decoration. YAML keeps those quote marks as part of
|
|
91
|
+
# the value, so the hint points at quoting the whole entry. YAML also reads an unquoted
|
|
92
|
+
# decoration with nothing after it (`- -:`) as a one-key mapping rather than a string.
|
|
93
|
+
ENTRY_QUOTING_HINT = 'Quote the whole entry, decoration included (e.g. "-:path/to/file.c"), ' +
|
|
94
|
+
'not only the path after its +: or -: decoration.'
|
|
95
|
+
|
|
96
|
+
def usable_entry?(entry, walk)
|
|
97
|
+
path = entry.is_a?( String ) ? FilePathUtils::no_aggregation_decorators( entry ) : ''
|
|
98
|
+
|
|
99
|
+
problem =
|
|
100
|
+
if !entry.nil? and !entry.is_a?( String ) then "is not a path (YAML read it as a #{entry.class})"
|
|
101
|
+
elsif path.empty? then 'names no path'
|
|
102
|
+
elsif path.start_with?( '"', "'" ) then 'wraps its path in quotes'
|
|
103
|
+
end
|
|
104
|
+
return true if problem.nil?
|
|
105
|
+
|
|
106
|
+
log_error( "#{walk} => '#{entry}' #{problem}" )
|
|
107
|
+
log_error( ENTRY_QUOTING_HINT )
|
|
108
|
+
return false
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# A path naming a file is ignored with a warning. Any other entry must yield directories,
|
|
112
|
+
# except a subdirectories glob of a directory that has none, and a `-:` entry.
|
|
113
|
+
def valid_paths_entry?(entry, walk, build_root)
|
|
114
|
+
path = FilePathUtils::no_aggregation_decorators( entry )
|
|
115
|
+
|
|
116
|
+
if @file_wrapper.exist?( path ) and !@file_wrapper.directory?( path )
|
|
117
|
+
log_complaint( "#{walk} => '#{path}' is a filepath and will be ignored (FYI :paths is directory-oriented while :files is file-oriented)" )
|
|
118
|
+
return true
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
return valid_subtraction?( entry, path, walk, build_root ) unless FilePathUtils.add_path?( entry )
|
|
122
|
+
return true if globbed_directories?( path ) or path =~ /\/\*{1,2}$/
|
|
123
|
+
|
|
124
|
+
log_error( "#{walk} => '#{path}' yielded no directories -- matching glob is malformed or directories do not exist" )
|
|
125
|
+
return false
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# A `-:` entry leaves out what it names, or warns of naming nothing. A subdirectories glob
|
|
129
|
+
# names its directory too.
|
|
130
|
+
def valid_subtraction?(entry, path, walk, build_root)
|
|
131
|
+
named = path.match?( %r{/\*{1,2}\z} ) ? @file_wrapper.exist?( FilePathUtils.no_decorators( entry ) ) : @file_wrapper.exist?( path )
|
|
132
|
+
return true if named or globbed_directories?( path )
|
|
133
|
+
|
|
134
|
+
return subtracts_nothing( entry, walk, build_root, 'directory' )
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# A `-:` entry names what a build leaves out, so naming nothing is no error. Below the build
|
|
138
|
+
# root, where nothing exists before a first build, it passes without a word.
|
|
139
|
+
def subtracts_nothing(entry, walk, build_root, kind)
|
|
140
|
+
unless build_root and ProjectPaths.contains?( build_root, FilePathUtils.no_decorators( entry ) )
|
|
141
|
+
log_complaint( "#{walk} => '#{entry.strip}' leaves out nothing; no #{kind} matches it" )
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
return true
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# #104 -- FilePathUtils.subdirectory_glob escapes literal brackets in the path, so they
|
|
148
|
+
# are matched rather than read as a glob character class
|
|
149
|
+
def globbed_directories?(path)
|
|
150
|
+
return @file_wrapper.directory_listing( FilePathUtils.subdirectory_glob( path ) ).any? { |entry| @file_wrapper.directory?( entry ) }
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# A path naming a directory is ignored with a warning. Any other entry must yield files,
|
|
154
|
+
# except a `-:` entry.
|
|
155
|
+
def valid_files_entry?(entry, walk, build_root)
|
|
156
|
+
path = FilePathUtils::no_aggregation_decorators( entry )
|
|
157
|
+
|
|
158
|
+
if @file_wrapper.exist?( path ) and @file_wrapper.directory?( path )
|
|
159
|
+
log_complaint( "#{walk} => '#{path}' is a directory path and will be ignored (FYI :files is file-oriented while :paths is directory-oriented)" )
|
|
160
|
+
return true
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# #104 -- literal brackets are escaped so they are matched rather than read as a glob
|
|
164
|
+
return true unless @file_wrapper.instantiate_file_list( FilePathUtils.escape_glob_brackets( path ) ).size.zero?
|
|
165
|
+
return subtracts_nothing( entry, walk, build_root, 'file' ) unless FilePathUtils.add_path?( entry )
|
|
166
|
+
|
|
167
|
+
log_error( "#{walk} => '#{path}' yielded no files -- matching glob is malformed or files do not exist" )
|
|
168
|
+
return false
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def log_error(message)
|
|
172
|
+
@loginator.log( message, Verbosity::ERRORS )
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def log_complaint(message)
|
|
176
|
+
@loginator.log( message, Verbosity::COMPLAIN )
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
end
|
|
@@ -12,12 +12,13 @@ require 'ceedling/config/line_marker_suppressors'
|
|
|
12
12
|
|
|
13
13
|
class ConfiguratorSetup
|
|
14
14
|
|
|
15
|
-
constructor :configurator_builder, :configurator_validator, :loginator, :reportinator, :file_wrapper,
|
|
15
|
+
constructor :configurator_builder, :configurator_validator, :configurator_paths_validator, :loginator, :reportinator, :file_wrapper,
|
|
16
16
|
:system_wrapper, :tool_executor
|
|
17
17
|
|
|
18
18
|
# Path collections, in order, since each builds on those before it
|
|
19
19
|
PATH_COLLECTIONS = [
|
|
20
20
|
:expand_all_path_globs,
|
|
21
|
+
:collect_mirror_roots,
|
|
21
22
|
:collect_vendor_paths,
|
|
22
23
|
:collect_source_and_include_paths,
|
|
23
24
|
:collect_source_include_vendor_paths,
|
|
@@ -72,17 +73,6 @@ class ConfiguratorSetup
|
|
|
72
73
|
end
|
|
73
74
|
end
|
|
74
75
|
|
|
75
|
-
# A vendor destination must be a directory, and the marker file inside it (unity.c,
|
|
76
|
-
# cmock.c, CException.c) a plain file. An interrupted run, or a second Ceedling run racing
|
|
77
|
-
# this one, can leave either as the wrong type, and the copy would then fail on every
|
|
78
|
-
# later build. The whole destination is cleared, so the copy recreates it.
|
|
79
|
-
def heal_vendor_path(path, marker_file)
|
|
80
|
-
return unless corrupted_vendor_path?( path, marker_file )
|
|
81
|
-
|
|
82
|
-
@loginator.log( "Removing corrupted vendor path (unexpected file/directory type): #{path}", Verbosity::COMPLAIN, LogLabels::NOTICE )
|
|
83
|
-
@file_wrapper.rm_rf( path )
|
|
84
|
-
end
|
|
85
|
-
|
|
86
76
|
# Brings build/vendor up to date with the frameworks and support files a build needs. Only
|
|
87
77
|
# a build does this, so a command that only reads the project leaves a concurrent build's
|
|
88
78
|
# files alone. A file that already matches its source is not written, and one that differs,
|
|
@@ -90,8 +80,7 @@ class ConfiguratorSetup
|
|
|
90
80
|
#
|
|
91
81
|
# A release build needs only CException, and that only when exceptions are enabled.
|
|
92
82
|
def vendor_frameworks_and_support_files(ceedling_lib_path, flattened_config, test_build:, release_build:)
|
|
93
|
-
frameworks_for_build( flattened_config, test_build: test_build, release_build: release_build ).each do |source, destination
|
|
94
|
-
heal_vendor_path( destination, marker_file )
|
|
83
|
+
frameworks_for_build( flattened_config, test_build: test_build, release_build: release_build ).each do |source, destination|
|
|
95
84
|
@file_wrapper.sync_tree( source, destination )
|
|
96
85
|
end
|
|
97
86
|
|
|
@@ -130,6 +119,11 @@ class ConfiguratorSetup
|
|
|
130
119
|
end
|
|
131
120
|
|
|
132
121
|
|
|
122
|
+
def validate_build_root(config)
|
|
123
|
+
return @configurator_paths_validator.validate_build_root( config )
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
|
|
133
127
|
# Every check runs, so every problem is reported
|
|
134
128
|
def validate_paths(config)
|
|
135
129
|
valid = validate_simple_paths( config[:cmock][:unity_helper_path], :cmock, :unity_helper_path )
|
|
@@ -308,23 +302,16 @@ class ConfiguratorSetup
|
|
|
308
302
|
|
|
309
303
|
private
|
|
310
304
|
|
|
311
|
-
|
|
312
|
-
marker = File.join( path, marker_file )
|
|
313
|
-
|
|
314
|
-
return ( @file_wrapper.exist?( path ) && !@file_wrapper.directory?( path ) ) ||
|
|
315
|
-
( @file_wrapper.exist?( marker ) && @file_wrapper.directory?( marker ) )
|
|
316
|
-
end
|
|
317
|
-
|
|
318
|
-
# Each framework a build uses, as [vendored source, build destination, marker file]
|
|
305
|
+
# Each framework a build uses, as [vendored source, build destination]
|
|
319
306
|
def vendored_frameworks(config)
|
|
320
|
-
frameworks = [ [File.join( config[:unity_vendor_path], UNITY_LIB_PATH ), config[:project_build_vendor_unity_path]
|
|
307
|
+
frameworks = [ [File.join( config[:unity_vendor_path], UNITY_LIB_PATH ), config[:project_build_vendor_unity_path]] ]
|
|
321
308
|
|
|
322
309
|
if config[:project_use_mocks]
|
|
323
|
-
frameworks << [File.join( config[:cmock_vendor_path], CMOCK_LIB_PATH ), config[:project_build_vendor_cmock_path]
|
|
310
|
+
frameworks << [File.join( config[:cmock_vendor_path], CMOCK_LIB_PATH ), config[:project_build_vendor_cmock_path]]
|
|
324
311
|
end
|
|
325
312
|
|
|
326
313
|
if config[:project_use_exceptions]
|
|
327
|
-
frameworks << [File.join( config[:cexception_vendor_path], CEXCEPTION_LIB_PATH ), config[:project_build_vendor_cexception_path]
|
|
314
|
+
frameworks << [File.join( config[:cexception_vendor_path], CEXCEPTION_LIB_PATH ), config[:project_build_vendor_cexception_path]]
|
|
328
315
|
end
|
|
329
316
|
|
|
330
317
|
return frameworks
|
|
@@ -332,7 +319,7 @@ class ConfiguratorSetup
|
|
|
332
319
|
|
|
333
320
|
def frameworks_for_build(config, test_build:, release_build:)
|
|
334
321
|
return vendored_frameworks( config ) if test_build
|
|
335
|
-
return vendored_frameworks( config ).select { |_,
|
|
322
|
+
return vendored_frameworks( config ).select { |_, destination| destination == config[:project_build_vendor_cexception_path] } if release_build
|
|
336
323
|
|
|
337
324
|
return []
|
|
338
325
|
end
|
|
@@ -353,13 +340,13 @@ class ConfiguratorSetup
|
|
|
353
340
|
end
|
|
354
341
|
|
|
355
342
|
def validate_simple_paths(paths, *keys)
|
|
356
|
-
return paths.map { |path| @
|
|
343
|
+
return paths.map { |path| @configurator_paths_validator.validate_filepath_simple( path, *keys ) }.all?
|
|
357
344
|
end
|
|
358
345
|
|
|
359
346
|
# Each entry of :paths or :files must exist and yield what its section expects
|
|
360
347
|
def validate_path_section(config, section, entries_validation)
|
|
361
348
|
return config[section].keys.sort.map do |key|
|
|
362
|
-
@
|
|
349
|
+
@configurator_paths_validator.validate_path_list( config, section, key ) & @configurator_paths_validator.public_send( entries_validation, config, key )
|
|
363
350
|
end.all?
|
|
364
351
|
end
|
|
365
352
|
|
|
@@ -6,13 +6,12 @@
|
|
|
6
6
|
# =========================================================================
|
|
7
7
|
|
|
8
8
|
require 'ceedling/constants'
|
|
9
|
-
require 'ceedling/file_path_utils' # for glob handling class methods
|
|
10
9
|
require 'ceedling/config/config_matchinator'
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
class ConfiguratorValidator
|
|
14
13
|
|
|
15
|
-
constructor :config_walkinator, :
|
|
14
|
+
constructor :config_walkinator, :loginator, :reportinator, :tool_validator
|
|
16
15
|
|
|
17
16
|
# Walk into config hash verify existence of data at key depth
|
|
18
17
|
def exists?(config, *keys)
|
|
@@ -23,54 +22,6 @@ class ConfiguratorValidator
|
|
|
23
22
|
return false
|
|
24
23
|
end
|
|
25
24
|
|
|
26
|
-
# Walk into config hash. verify existence of path(s) at given key depth.
|
|
27
|
-
# Paths are either full simple paths or a simple portion of a path up to a glob.
|
|
28
|
-
def validate_path_list(config, *keys)
|
|
29
|
-
list, depth = @config_walkinator.fetch_value( *keys, hash:config )
|
|
30
|
-
return false if list.nil?
|
|
31
|
-
|
|
32
|
-
# Trimming add/subtract notation and glob specifiers leaves nothing of a path that
|
|
33
|
-
# begins with a glob, so there is nothing to check. An entry YAML read as something
|
|
34
|
-
# other than a string is left to the entries validation, which reports it.
|
|
35
|
-
paths = list.grep( String ).map { |path| FilePathUtils::no_decorators( path ) }
|
|
36
|
-
missing = paths.reject { |path| path.empty? or @file_wrapper.exist?( path ) }
|
|
37
|
-
|
|
38
|
-
walk = @reportinator.generate_config_walk( keys, depth )
|
|
39
|
-
missing.each { |path| log_error( "Config path #{walk} => '#{path}' does not exist in the filesystem." ) }
|
|
40
|
-
|
|
41
|
-
return missing.empty?
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
# Validate :paths entries, exercising each entry as Ceedling directory glob (variation of Ruby glob)
|
|
46
|
-
def validate_paths_entries(config, key)
|
|
47
|
-
list, _ = @config_walkinator.fetch_value( :paths, key, hash:config )
|
|
48
|
-
return false if list.nil?
|
|
49
|
-
|
|
50
|
-
walk = @reportinator.generate_config_walk( [:paths, key] )
|
|
51
|
-
return list.map { |path| usable_entry?( path, walk ) && valid_paths_entry?( FilePathUtils::no_aggregation_decorators( path ), walk ) }.all?
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
# Validate :files entries, exercising each entry as FileList glob
|
|
56
|
-
def validate_files_entries(config, key)
|
|
57
|
-
list, _ = @config_walkinator.fetch_value( :files, key, hash:config )
|
|
58
|
-
return false if list.nil?
|
|
59
|
-
|
|
60
|
-
walk = @reportinator.generate_config_walk( [:files, key] )
|
|
61
|
-
return list.map { |path| usable_entry?( path, walk ) && valid_files_entry?( FilePathUtils::no_aggregation_decorators( path ), walk ) }.all?
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
# Simple path verification
|
|
66
|
-
def validate_filepath_simple(path, *keys)
|
|
67
|
-
return true if @file_wrapper.exist?( path )
|
|
68
|
-
|
|
69
|
-
walk = @reportinator.generate_config_walk( keys, keys.size )
|
|
70
|
-
log_error( "Config path '#{path}' associated with #{walk} does not exist in the filesystem." )
|
|
71
|
-
return false
|
|
72
|
-
end
|
|
73
|
-
|
|
74
25
|
def validate_tool(config:, key:, respect_optional:true)
|
|
75
26
|
# Get tool
|
|
76
27
|
walk = [:tools, key]
|
|
@@ -102,62 +53,6 @@ class ConfiguratorValidator
|
|
|
102
53
|
|
|
103
54
|
private
|
|
104
55
|
|
|
105
|
-
# A :paths or :files entry that names no path, or wraps its path in quotes, usually
|
|
106
|
-
# quotes only the path after its decoration. YAML keeps those quote marks as part of
|
|
107
|
-
# the value, so the hint points at quoting the whole entry. YAML also reads an unquoted
|
|
108
|
-
# decoration with nothing after it (`- -:`) as a one-key mapping rather than a string.
|
|
109
|
-
ENTRY_QUOTING_HINT = 'Quote the whole entry, decoration included (e.g. "-:path/to/file.c"), ' +
|
|
110
|
-
'not only the path after its +: or -: decoration.'
|
|
111
|
-
|
|
112
|
-
def usable_entry?(entry, walk)
|
|
113
|
-
path = entry.is_a?( String ) ? FilePathUtils::no_aggregation_decorators( entry ) : ''
|
|
114
|
-
|
|
115
|
-
problem =
|
|
116
|
-
if !entry.nil? and !entry.is_a?( String ) then "is not a path (YAML read it as a #{entry.class})"
|
|
117
|
-
elsif path.empty? then 'names no path'
|
|
118
|
-
elsif path.start_with?( '"', "'" ) then 'wraps its path in quotes'
|
|
119
|
-
end
|
|
120
|
-
return true if problem.nil?
|
|
121
|
-
|
|
122
|
-
log_error( "#{walk} => '#{entry}' #{problem}" )
|
|
123
|
-
log_error( ENTRY_QUOTING_HINT )
|
|
124
|
-
return false
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
# A path naming a file is ignored with a warning. Any other entry must yield directories,
|
|
128
|
-
# except a subdirectories glob of a directory that has none.
|
|
129
|
-
def valid_paths_entry?(path, walk)
|
|
130
|
-
if @file_wrapper.exist?( path ) and !@file_wrapper.directory?( path )
|
|
131
|
-
log_complaint( "#{walk} => '#{path}' is a filepath and will be ignored (FYI :paths is directory-oriented while :files is file-oriented)" )
|
|
132
|
-
return true
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
return true if globbed_directories?( path ) or path =~ /\/\*{1,2}$/
|
|
136
|
-
|
|
137
|
-
log_error( "#{walk} => '#{path}' yielded no directories -- matching glob is malformed or directories do not exist" )
|
|
138
|
-
return false
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
# #104 -- FilePathUtils.subdirectory_glob escapes literal brackets in the path, so they
|
|
142
|
-
# are matched rather than read as a glob character class
|
|
143
|
-
def globbed_directories?(path)
|
|
144
|
-
return @file_wrapper.directory_listing( FilePathUtils.subdirectory_glob( path ) ).any? { |entry| @file_wrapper.directory?( entry ) }
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
# A path naming a directory is ignored with a warning. Any other entry must yield files.
|
|
148
|
-
def valid_files_entry?(path, walk)
|
|
149
|
-
if @file_wrapper.exist?( path ) and @file_wrapper.directory?( path )
|
|
150
|
-
log_complaint( "#{walk} => '#{path}' is a directory path and will be ignored (FYI :files is file-oriented while :paths is directory-oriented)" )
|
|
151
|
-
return true
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
# #104 -- literal brackets are escaped so they are matched rather than read as a glob
|
|
155
|
-
return true unless @file_wrapper.instantiate_file_list( FilePathUtils.escape_glob_brackets( path ) ).size.zero?
|
|
156
|
-
|
|
157
|
-
log_error( "#{walk} => '#{path}' yielded no files -- matching glob is malformed or files do not exist" )
|
|
158
|
-
return false
|
|
159
|
-
end
|
|
160
|
-
|
|
161
56
|
def validate_regex_matcher(matcher)
|
|
162
57
|
Regexp.compile( matcher[1..-2] )
|
|
163
58
|
rescue RegexpError => ex
|
|
@@ -168,8 +63,4 @@ class ConfiguratorValidator
|
|
|
168
63
|
@loginator.log( message, Verbosity::ERRORS )
|
|
169
64
|
end
|
|
170
65
|
|
|
171
|
-
def log_complaint(message)
|
|
172
|
-
@loginator.log( message, Verbosity::COMPLAIN )
|
|
173
|
-
end
|
|
174
|
-
|
|
175
66
|
end
|
data/lib/ceedling/defaults.rb
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
require 'ceedling/constants'
|
|
9
9
|
require 'ceedling/system_wrapper'
|
|
10
|
-
require 'ceedling/file_path_utils'
|
|
10
|
+
require 'ceedling/filesystem/file_path_utils'
|
|
11
11
|
|
|
12
12
|
# Assign a default value for system testing where CEEDLING_APPCFG may not be present
|
|
13
13
|
# TODO: Create code config & test structure that does not internalize a test path like this
|
|
@@ -58,14 +58,14 @@ DEFAULT_TEST_LINKER_TOOL = {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
DEFAULT_TEST_FIXTURE_TOOL = {
|
|
61
|
-
:executable => '${1}'.freeze, # Unity test runner executable
|
|
61
|
+
:executable => '"${1}"'.freeze, # Unity test runner executable, quoted as a path
|
|
62
62
|
:name => 'default_test_fixture'.freeze,
|
|
63
63
|
:optional => false.freeze,
|
|
64
64
|
:arguments => [].freeze
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
DEFAULT_TEST_FIXTURE_SIMPLE_BACKTRACE_TOOL = {
|
|
68
|
-
:executable => '${1}'.freeze, # Unity test runner executable
|
|
68
|
+
:executable => '"${1}"'.freeze, # Unity test runner executable, quoted as a path
|
|
69
69
|
:name => 'default_test_fixture_simple_backtrace'.freeze,
|
|
70
70
|
:optional => false.freeze,
|
|
71
71
|
:arguments => [
|
|
@@ -204,7 +204,7 @@ DEFAULT_TEST_BACKTRACE_GDB_TOOL = {
|
|
|
204
204
|
'--eval-command run'.freeze,
|
|
205
205
|
"--command \"${1}\"".freeze, # Debug script file to run
|
|
206
206
|
'--args'.freeze,
|
|
207
|
-
'${2}'.freeze,
|
|
207
|
+
'"${2}"'.freeze, # Test executable, quoted as a path
|
|
208
208
|
# Test case matching flag and (quoted) value, fully composed by the caller as
|
|
209
209
|
# either `-n "<exact name>"` or `-f "<base name>"` -- see
|
|
210
210
|
# GeneratorTestResultsBacktrace#unity_filter_arg.
|