Skip to content

Commit

Permalink
Restructure the setup config load order
Browse files Browse the repository at this point in the history
Change the structure to merge both the default configs and the user-defined configs separately. Then combine the two sets of merged configs.
  • Loading branch information
chuyingy authored and tbates-redarc committed Sep 13, 2023
1 parent 8d3605c commit b562cc6
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 56 deletions.
4 changes: 2 additions & 2 deletions lib/ceedling.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ def self.register_plugin(name, prefix=nil)

# Register the plugin with Ceedling
require 'ceedling/defaults'
DEFAULT_CEEDLING_CONFIG[:plugins][:enabled] << name
DEFAULT_CEEDLING_CONFIG[:plugins][:load_paths] << gem_dir
CEEDLING_CONFIG_INTERNAL[:plugins][:enabled] << name
CEEDLING_CONFIG_INTERNAL[:plugins][:load_paths] << gem_dir
end
end

73 changes: 44 additions & 29 deletions lib/ceedling/configurator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,40 +67,42 @@ def reset_defaults(config)

# The default values defined in defaults.rb (eg. DEFAULT_TOOLS_TEST) are populated
# into @param config
def populate_defaults(config)
new_config = DEFAULT_CEEDLING_CONFIG.deep_clone
new_config.deep_merge!(config)
config.replace(new_config)

@configurator_builder.populate_defaults( config, DEFAULT_TOOLS_TEST )
@configurator_builder.populate_defaults( config, DEFAULT_TOOLS_TEST_PREPROCESSORS ) if (config[:project][:use_test_preprocessor])
@configurator_builder.populate_defaults( config, DEFAULT_TOOLS_TEST_DEPENDENCIES ) if (config[:project][:use_deep_dependencies])

@configurator_builder.populate_defaults( config, DEFAULT_TOOLS_RELEASE ) if (config[:project][:release_build])
@configurator_builder.populate_defaults( config, DEFAULT_TOOLS_RELEASE_ASSEMBLER ) if (config[:project][:release_build] and config[:release_build][:use_assembly])
@configurator_builder.populate_defaults( config, DEFAULT_TOOLS_RELEASE_DEPENDENCIES ) if (config[:project][:release_build] and config[:project][:use_deep_dependencies])
end
def merge_ceedling_config(config, default_config)

# Merge ceedling default config with default tools
default_config.replace( DEFAULT_CEEDLING_CONFIG.deep_clone )
default_config.deep_merge( DEFAULT_TOOLS_TEST.deep_clone )
default_config.deep_merge( DEFAULT_TOOLS_TEST_PREPROCESSORS.deep_clone )
default_config.deep_merge( DEFAULT_TOOLS_TEST_DEPENDENCIES.deep_clone )
default_config.deep_merge( DEFAULT_TOOLS_RELEASE.deep_clone )
default_config.deep_merge( DEFAULT_TOOLS_RELEASE_ASSEMBLER.deep_clone )
default_config.deep_merge( DEFAULT_TOOLS_RELEASE_DEPENDENCIES.deep_clone )

# Merge current config with ceedling internal settings
config.deep_merge( CEEDLING_CONFIG_INTERNAL.deep_clone )

def populate_unity_defaults(config)
unity = config[:unity] || {}
@runner_config = unity.merge(@runner_config || config[:test_runner] || {})
end

def populate_cmock_defaults(config)

def merge_cmock_config(config, default_config)
# cmock has its own internal defaults handling, but we need to set these specific values
# so they're present for the build environment to access;
# note: these need to end up in the hash given to initialize cmock for this to be successful
cmock = config[:cmock] || {}

# populate defaults with cmock internal settings
default_cmock = default_config[:cmock] || {}

# yes, we're duplicating the default mock_prefix in cmock, but it's because we need CMOCK_MOCK_PREFIX always available in Ceedling's environment
cmock[:mock_prefix] = 'Mock' if (cmock[:mock_prefix].nil?)
default_cmock[:mock_prefix] = 'Mock' if (default_cmock[:mock_prefix].nil?)

# just because strict ordering is the way to go
cmock[:enforce_strict_ordering] = true if (cmock[:enforce_strict_ordering].nil?)
default_cmock[:enforce_strict_ordering] = true if (default_cmock[:enforce_strict_ordering].nil?)

cmock[:mock_path] = File.join(config[:project][:build_root], TESTS_BASE_PATH, 'mocks') if (cmock[:mock_path].nil?)
cmock[:verbosity] = @project_verbosity if (cmock[:verbosity].nil?)
default_cmock[:mock_path] = File.join(config[:project][:build_root], TESTS_BASE_PATH, 'mocks') if (default_cmock[:mock_path].nil?)
default_cmock[:verbosity] = @project_verbosity if (default_cmock[:verbosity].nil?)

# populate current config with cmock config
cmock = config[:cmock] || {}

cmock[:plugins] = [] if (cmock[:plugins].nil?)
cmock[:plugins].map! { |plugin| plugin.to_sym }
Expand All @@ -111,13 +113,10 @@ def populate_cmock_defaults(config)

if (cmock[:unity_helper])
cmock[:unity_helper] = [cmock[:unity_helper]] if cmock[:unity_helper].is_a? String
cmock[:includes] = [] if (cmock[:includes].nil?)
cmock[:includes] += cmock[:unity_helper].map{|helper| File.basename(helper) }
cmock[:includes].uniq!
end

@runner_config = cmock.merge(@runner_config || config[:test_runner] || {})

@cmock_builder.manufacture(cmock)
end


Expand Down Expand Up @@ -168,7 +167,7 @@ def tools_supplement_arguments(config)
end


def find_and_merge_plugins(config)
def find_and_merge_plugins(config, default_config)
# plugins must be loaded before generic path evaluation & magic that happen later;
# perform path magic here as discrete step
config[:plugins][:load_paths].each do |path|
Expand All @@ -193,11 +192,11 @@ def find_and_merge_plugins(config)
end

plugin_yml_defaults.each do |defaults|
@configurator_builder.populate_defaults( config, @yaml_wrapper.load(defaults) )
default_config.deep_merge!( @yaml_wrapper.load(defaults) )
end

plugin_hash_defaults.each do |defaults|
@configurator_builder.populate_defaults( config, defaults )
@configurator_builder.populate_defaults( default_config, defaults )
end

# special plugin setting for results printing
Expand All @@ -207,6 +206,22 @@ def find_and_merge_plugins(config)
end


def populate_config_with_defaults(config, default_config)
@configurator_builder.populate_defaults( config, default_config )
end


# unity cmock initializer
def populate_runner_config(config)
unity = config[:unity] || {}
@runner_config = unity.merge(@runner_config || config[:test_runner] || {})

cmock = config[:cmock] || {}
@runner_config = cmock.merge(@runner_config)
@cmock_builder.manufacture(cmock)
end


def merge_imports(config)
if config[:import]
if config[:import].is_a? Array
Expand Down
31 changes: 22 additions & 9 deletions lib/ceedling/defaults.rb
Original file line number Diff line number Diff line change
Expand Up @@ -325,12 +325,6 @@
:include => [],
},

# unlike other top-level entries, environment's value is an array to preserve order
:environment => [
# when evaluated, this provides wider text field for rake task comments
{:rake_columns => '120'},
],

:defines => {
:test => [],
:test_preprocess => [],
Expand Down Expand Up @@ -365,18 +359,15 @@
},

:unity => {
:vendor_path => CEEDLING_VENDOR,
:defines => []
},

:cmock => {
:vendor_path => CEEDLING_VENDOR,
:defines => [],
:includes => []
},

:cexception => {
:vendor_path => CEEDLING_VENDOR,
:defines => []
},

Expand Down Expand Up @@ -405,6 +396,28 @@
:release_assembler => { :arguments => [] },
:release_dependencies_generator => { :arguments => [] },

}.freeze

CEEDLING_CONFIG_INTERNAL = {

# unlike other top-level entries, environment's value is an array to preserve order
:environment => [
# when evaluated, this provides wider text field for rake task comments
{:rake_columns => '120'},
],

:unity => {
:vendor_path => CEEDLING_VENDOR
},

:cmock => {
:vendor_path => CEEDLING_VENDOR
},

:cexception => {
:vendor_path => CEEDLING_VENDOR
},

:plugins => {
:load_paths => CEEDLING_PLUGINS,
:enabled => [],
Expand Down
10 changes: 6 additions & 4 deletions lib/ceedling/setupinator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@ def load_project_files

def do_setup(config_hash)
@config_hash = config_hash
defaults_hash = {}

# load up all the constants and accessors our rake files, objects, & external scripts will need;
# note: configurator modifies the cmock section of the hash with a couple defaults to tie
# project together - the modified hash is used to build cmock object
@ceedling[:configurator].populate_defaults( config_hash )
@ceedling[:configurator].populate_unity_defaults( config_hash )
@ceedling[:configurator].populate_cmock_defaults( config_hash )
@ceedling[:configurator].find_and_merge_plugins( config_hash )
@ceedling[:configurator].merge_ceedling_config( config_hash, defaults_hash )
@ceedling[:configurator].merge_cmock_config( config_hash, defaults_hash )
@ceedling[:configurator].find_and_merge_plugins( config_hash, defaults_hash )
@ceedling[:configurator].populate_config_with_defaults( config_hash, defaults_hash )
@ceedling[:configurator].populate_runner_config( config_hash )
@ceedling[:configurator].merge_imports( config_hash )
@ceedling[:configurator].eval_environment_variables( config_hash )
@ceedling[:configurator].tools_setup( config_hash )
Expand Down
24 changes: 12 additions & 12 deletions spec/ceedling_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@

it 'should load the project with the specified plugins enabled' do
# create test state/variables
DEFAULT_CEEDLING_CONFIG[:plugins][:enabled].clear()
DEFAULT_CEEDLING_CONFIG[:plugins][:load_paths].clear()
CEEDLING_CONFIG_INTERNAL[:plugins][:enabled].clear()
CEEDLING_CONFIG_INTERNAL[:plugins][:load_paths].clear()
spec_double = double('spec-double')
rakefile_path = File.join(File.dirname(__FILE__), '..').gsub('spec','lib')
rakefile_path = File.join( rakefile_path, 'lib', 'ceedling', 'rakefile.rb' )
Expand All @@ -102,8 +102,8 @@
it 'should set the project root if the root key is provided' do
# create test state/variables
Object.send(:remove_const, :PROJECT_ROOT)
DEFAULT_CEEDLING_CONFIG[:plugins][:enabled].clear()
DEFAULT_CEEDLING_CONFIG[:plugins][:load_paths].clear()
CEEDLING_CONFIG_INTERNAL[:plugins][:enabled].clear()
CEEDLING_CONFIG_INTERNAL[:plugins][:load_paths].clear()
rakefile_path = File.join(File.dirname(__FILE__), '..').gsub('spec','lib')
rakefile_path = File.join( rakefile_path, 'lib', 'ceedling', 'rakefile.rb' )
# mocks/stubs/expected calls
Expand All @@ -120,8 +120,8 @@
context 'register_plugin' do
it 'should register a plugin' do
# create test state/variables
DEFAULT_CEEDLING_CONFIG[:plugins][:enabled].clear()
DEFAULT_CEEDLING_CONFIG[:plugins][:load_paths].clear()
CEEDLING_CONFIG_INTERNAL[:plugins][:enabled].clear()
CEEDLING_CONFIG_INTERNAL[:plugins][:load_paths].clear()
spec_double = double('spec-double')
# mocks/stubs/expected calls
expect(Gem::Specification).to receive(:find_by_name).with('ceedling-foo').and_return(spec_double)
Expand All @@ -130,14 +130,14 @@
# execute method
Ceedling.register_plugin('foo')
# validate results
expect(DEFAULT_CEEDLING_CONFIG[:plugins][:enabled]).to eq ["foo"]
expect(DEFAULT_CEEDLING_CONFIG[:plugins][:load_paths]).to eq(["dummy/path"])
expect(CEEDLING_CONFIG_INTERNAL[:plugins][:enabled]).to eq ["foo"]
expect(CEEDLING_CONFIG_INTERNAL[:plugins][:load_paths]).to eq(["dummy/path"])
end

it 'should register a plugin with an alternative prefix' do
# create test state/variables
DEFAULT_CEEDLING_CONFIG[:plugins][:enabled].clear()
DEFAULT_CEEDLING_CONFIG[:plugins][:load_paths].clear()
CEEDLING_CONFIG_INTERNAL[:plugins][:enabled].clear()
CEEDLING_CONFIG_INTERNAL[:plugins][:load_paths].clear()
spec_double = double('spec-double')
# mocks/stubs/expected calls
expect(Gem::Specification).to receive(:find_by_name).with('prefix-foo').and_return(spec_double)
Expand All @@ -146,8 +146,8 @@
# execute method
Ceedling.register_plugin('foo','prefix-')
# validate results
expect(DEFAULT_CEEDLING_CONFIG[:plugins][:enabled]).to eq(["foo"])
expect(DEFAULT_CEEDLING_CONFIG[:plugins][:load_paths]).to eq(["dummy/path"])
expect(CEEDLING_CONFIG_INTERNAL[:plugins][:enabled]).to eq(["foo"])
expect(CEEDLING_CONFIG_INTERNAL[:plugins][:load_paths]).to eq(["dummy/path"])
end
end
end
Expand Down

0 comments on commit b562cc6

Please sign in to comment.