Skip to content

Commit

Permalink
Merge pull request #877 from ThrowTheSwitch/test/0_32/streaminator_fo…
Browse files Browse the repository at this point in the history
…r_all

Test/0 32/streaminator for all
  • Loading branch information
mvandervoord authored Apr 15, 2024
2 parents 24a0af4 + 9fe906f commit 1765fc8
Show file tree
Hide file tree
Showing 60 changed files with 388 additions and 337 deletions.
1 change: 1 addition & 0 deletions assets/project_as_gem.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
:use_mocks: TRUE
:use_test_preprocessor: TRUE
:use_backtrace: FALSE
:use_decorators: :auto #Decorate Ceedling's output text. Your options are :auto, :all, or :none

# tweak the way ceedling handles automatic tasks
:build_root: build
Expand Down
1 change: 1 addition & 0 deletions assets/project_with_guts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
:use_mocks: TRUE
:use_test_preprocessor: TRUE
:use_backtrace: FALSE
:use_decorators: :auto #Decorate Ceedling's output text. Your options are :auto, :all, or :none

# tweak the way ceedling handles automatic tasks
:build_root: build
Expand Down
1 change: 1 addition & 0 deletions assets/project_with_guts_gcov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
:use_mocks: TRUE
:use_test_preprocessor: TRUE
:use_backtrace: FALSE
:use_decorators: :auto #Decorate Ceedling's output text. Your options are :auto, :all, or :none

# tweak the way ceedling handles automatic tasks
:build_root: build
Expand Down
72 changes: 70 additions & 2 deletions bin/ceedling
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,73 @@ CEEDLING_VENDOR = File.join( CEEDLING_ROOT, 'vendor' )
# Add load path for `require 'ceedling/*'` statements and bin/ code
$LOAD_PATH.unshift( CEEDLING_BIN, CEEDLING_LIB_BASE )

# Load "bootloader" / command line handling in bin/
require 'main'
require 'cli' # Located alongside this file in CEEDLING_BIN
require 'constructor' # Assumed installed via Ceedling gem dependencies
require 'app_cfg' # Located alongside this file in CEEDLING_BIN

CEEDLING_APPCFG = get_app_cfg()

# Entry point
begin
# Construct all bootloader objects
# 1. Add full path to $LOAD_PATH to simplify objects.yml
# 2. Add vendored DIY to $LOAD_PATH so we can use it
# 3. Require DIY (used by Ceedling application too)
# 4. Perform object construction + dependency injection from bin/objects.yml
# 5. Remove unneeded / potentially problematic paths from $LOAD_PATH
$LOAD_PATH.unshift( CEEDLING_LIB )
$LOAD_PATH.unshift( File.join(CEEDLING_VENDOR, 'diy/lib') )

require 'diy'
objects = DIY::Context.from_yaml( File.read( File.join( CEEDLING_BIN, 'objects.yml' ) ) )
objects.build_everything()

$LOAD_PATH.delete( CEEDLING_BIN ) # Loaded in top-level `ceedling` script
$LOAD_PATH.delete( CEEDLING_LIB )

# Keep a copy of the command line for edge case CLI hacking (Thor consumes ARGV)
_ARGV = ARGV.clone

#
# NOTE: See comment block in cli.rb to understand CLI handling
# ------------------------------------------------------------
#

# Backwards compatibility command line hack to silently preserve Rake `-T` CLI handling
if (ARGV.size() == 1 and ARGV[0] == '-T')
# Call Rake task listing handler w/ default handling of project file and mixins
objects[:cli_handler].rake_help( env:ENV, app_cfg:CEEDLING_APPCFG )

# Run command line args through Thor (including "naked" Rake tasks)
else
CeedlingTasks::CLI.start( ARGV,
{
:app_cfg => CEEDLING_APPCFG,
:objects => objects,
}
)
end

# Handle case of Thor application CLI failing to handle command line arguments.
rescue Thor::UndefinedCommandError
# Marrying Thor & Rake command line handling creates a gap (see comments in CLI handling).
# If a user enters only Rake build tasks at the command line followed by Thor flags,
# our Thor configuration doesn't see those flags.
# We catch the exception of unrecognized Thor commands here (i.e. any "naked" Rake tasks),
# and try again by forcing the Thor `build` command at the beginning of the command line.
# This way, our Thor handling will process option flags and properly pass the Rake tasks
# along as well.
CeedlingTasks::CLI.start( _ARGV.unshift( 'build' ),
{
:app_cfg => CEEDLING_APPCFG,
:objects => objects,
}
)

# Bootloader boom handling (ideally this never runs... we failed to build much if we're here)
rescue StandardError => e
$stderr.puts( "\nERROR: #{e.message}" )
$stderr.puts( e.backtrace ) if ( defined?( PROJECT_DEBUG ) and PROJECT_DEBUG )
exit(1)
end

2 changes: 1 addition & 1 deletion bin/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ def upgrade(path)
\x5 > ceedling build test:all
TASKS are zero or more build operations created from your project configuration.
If no tasks are provided, the built-in default tasks or your :project
If no tasks are provided, the built-in default tasks or your :project ->
:default_tasks will be executed.
Optional Flags:
Expand Down
48 changes: 28 additions & 20 deletions bin/cli_handler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

class CliHandler

constructor :configinator, :projectinator, :cli_helper, :path_validator, :actions_wrapper, :logger
constructor :configinator, :projectinator, :cli_helper, :path_validator, :actions_wrapper, :streaminator

# Override to prevent exception handling from walking & stringifying the object variables.
# Object variables are lengthy and produce a flood of output.
Expand All @@ -24,13 +24,13 @@ def app_help(env, app_cfg, options, command, &thor_help)
# If help requested for a command, show it and skip listing build tasks
if !command.nil?
# Block handler
@logger._print( '🌱 Application ' )
@streaminator.stream_puts( 'Ceedling Application ' )
thor_help.call( command ) if block_given?
return
end

# Display Thor-generated help listing
@logger._print( '🌱 Application ' )
@streaminator.stream_puts( 'Ceedling Application ' )
thor_help.call( command ) if block_given?

# If it was help for a specific command, we're done
Expand Down Expand Up @@ -90,7 +90,7 @@ def new_project(ceedling_root, options, name, dest)
@actions._touch_file( File.join(dest, 'test/support', '.gitkeep') )
end

@logger.log( "\n🌱 New project '#{name}' created at #{dest}/\n" )
@streaminator.stream_puts( "\nNew project '#{name}' created at #{dest}/\n" )
end


Expand All @@ -104,7 +104,7 @@ def upgrade_project(ceedling_root, options, path)
end

project_filepath = File.join( path, options[:project] )
_, config = @projectinator.load( filepath:project_filepath, silent:true )
_, config = @projectinator.load( filepath:project_filepath )

if (@helper.which_ceedling?( config ) == 'gem')
msg = "Project configuration specifies the Ceedling gem, not vendored Ceedling"
Expand All @@ -124,7 +124,7 @@ def upgrade_project(ceedling_root, options, path)
@helper.copy_docs( ceedling_root, path )
end

@logger.log( "\n🌱 Upgraded project at #{path}/\n" )
@streaminator.stream_puts( "\nUpgraded project at #{path}/\n" )
end


Expand All @@ -146,6 +146,16 @@ def build(env:, app_cfg:, options:{}, tasks:)
)

log_filepath = @helper.process_logging( options[:log], options[:logfile] )
if (config[:project] && config[:project][:use_decorators])
case config[:project][:use_decorators]
when :all
@streaminator.decorate(true)
when :none
@streaminator.decorate(false)
else #includes :auto
#nothing more to do. we've already figured out auto
end
end

# Save references
app_cfg[:project_config] = config
Expand Down Expand Up @@ -200,11 +210,11 @@ def dumpconfig(env, app_cfg, options, filepath, sections)
default_tasks: default_tasks
)
else
@logger.log( " > Skipped loading Ceedling application" )
@streaminator.stream_puts( " > Skipped loading Ceedling application", Verbosity::OBNOXIOUS )
end
ensure
@helper.dump_yaml( config, filepath, sections )
@logger.log( "\n🌱 Dumped project configuration to #{filepath}\n" )
@streaminator.stream_puts( "\nDumped project configuration to #{filepath}\n" )
end
end

Expand Down Expand Up @@ -242,13 +252,13 @@ def environment(env, app_cfg, options)
end
end

output = "\n🌱 Environment variables:\n"
output = "\nEnvironment variables:\n"

env_list.sort.each do |line|
output << " • #{line}\n"
end

@logger.log( output + "\n")
@streaminator.stream_puts( output + "\n" )
end


Expand All @@ -257,11 +267,11 @@ def list_examples(examples_path)

raise( "No examples projects found") if examples.empty?

output = "\n🌱 Available example projects:\n"
output = "\nAvailable example projects:\n"

examples.each {|example| output << " • #{example}\n" }

@logger.log( output + "\n" )
@streaminator.stream_puts( output + "\n" )
end


Expand Down Expand Up @@ -294,19 +304,19 @@ def create_example(ceedling_root, examples_path, options, name, dest)
# Copy in documentation
@helper.copy_docs( ceedling_root, dest ) if options[:docs]

@logger.log( "\n🌱 Example project '#{name}' created at #{dest}/\n" )
@streaminator.stream_puts( "\nExample project '#{name}' created at #{dest}/\n" )
end


def version()
require 'ceedling/version'
version = <<~VERSION
🌱 Ceedling => #{Ceedling::Version::CEEDLING}
Ceedling => #{Ceedling::Version::CEEDLING}
CMock => #{Ceedling::Version::CMOCK}
Unity => #{Ceedling::Version::UNITY}
CException => #{Ceedling::Version::CEXCEPTION}
VERSION
@logger.log( version )
@streaminator.stream_puts( version )
end


Expand All @@ -319,21 +329,19 @@ def list_rake_tasks(env:, app_cfg:, filepath:nil, mixins:[])
@configinator.loadinate(
filepath: filepath,
mixins: mixins,
env: env,
silent: true # Suppress project config load logging
env: env
)

# Save reference to loaded configuration
app_cfg[:project_config] = config

@logger.log( "🌱 Build & Plugin Tasks:\n(Parameterized tasks tend to require enclosing quotes and/or escape sequences in most shells)" )
@streaminator.stream_puts( "Ceedling Build & Plugin Tasks:\n(Parameterized tasks tend to require enclosing quotes and/or escape sequences in most shells)" )

@helper.load_ceedling(
project_filepath: project_filepath,
config: config,
which: app_cfg[:which_ceedling],
default_tasks: app_cfg[:default_tasks],
silent: true
default_tasks: app_cfg[:default_tasks]
)

@helper.print_rake_tasks()
Expand Down
27 changes: 16 additions & 11 deletions bin/cli_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@

class CliHelper

constructor :file_wrapper, :actions_wrapper, :config_walkinator, :path_validator, :logger
constructor :file_wrapper, :actions_wrapper, :config_walkinator, :path_validator, :streaminator

def setup
#Aliases
@actions = @actions_wrapper

@streaminator.decorate( !windows? )
end


Expand Down Expand Up @@ -47,10 +49,10 @@ def which_ceedling?(config)
end


def load_ceedling(project_filepath:, config:, which:, default_tasks:[], silent:false)
def load_ceedling(project_filepath:, config:, which:, default_tasks:[])
# Determine which Ceedling we're running
# 1. Copy the which value passed in (most likely a default determined in the first moments of startup)
# 2. If a :project :which_ceedling entry exists in the config, use it instead
# 2. If a :project -> :which_ceedling entry exists in the config, use it instead
_which = which.dup()
walked = @config_walkinator.fetch_value( config, :project, :which_ceedling )
_which = walked[:value] if !walked[:value].nil?
Expand All @@ -70,18 +72,18 @@ def load_ceedling(project_filepath:, config:, which:, default_tasks:[], silent:f
ceedling_path = File.expand_path( ceedling_path )

if !@file_wrapper.directory?( ceedling_path )
raise "Configuration value :project :which_ceedling => '#{_which}' points to a path relative to your project file that contains no Ceedling installation"
raise "Configuration value :project -> :which_ceedling => '#{_which}' points to a path relative to your project file that contains no Ceedling installation"
end

# Otherwise, :which_ceedling is an absolute path
else
if !@file_wrapper.exist?( ceedling_path )
raise "Configuration value :project :which_ceedling => '#{_which}' points to a path that contains no Ceedling installation"
raise "Configuration value :project -> :which_ceedling => '#{_which}' points to a path that contains no Ceedling installation"
end
end

require( File.join( ceedling_path, '/lib/ceedling.rb' ) )
@logger.log( " > Running Ceedling from #{ceedling_path}/" ) if !silent
@streaminator.stream_puts( " > Running Ceedling from #{ceedling_path}/", Verbosity::OBNOXIOUS )
end

# Set default tasks
Expand Down Expand Up @@ -189,6 +191,9 @@ def run_rake_tasks(tasks)
def set_verbosity(verbosity=nil)
verbosity = verbosity.nil? ? Verbosity::NORMAL : VERBOSITY_OPTIONS[verbosity.to_sym()]

# If we already set verbosity, there's nothing more to do here
return if Object.const_defined?('PROJECT_VERBOSITY')

# Create global constant PROJECT_VERBOSITY
Object.module_eval("PROJECT_VERBOSITY = verbosity")
PROJECT_VERBOSITY.freeze()
Expand Down Expand Up @@ -216,7 +221,7 @@ def dump_yaml(config, filepath, sections)
if walked[:value].nil?
# Reformat list of symbols to list of :<section>s
_sections.map! {|section| ":#{section.to_s}"}
msg = "Cound not find configuration section #{_sections.join(' ')}"
msg = "Cound not find configuration section #{_sections.join(' -> ')}"
raise(msg)
end

Expand Down Expand Up @@ -396,9 +401,9 @@ def vendor_tools(ceedling_root, dest)

private

def windows?
return ((RbConfig::CONFIG['host_os'] =~ /mswin|mingw/) ? true : false) if defined?( RbConfig )
return ((Config::CONFIG['host_os'] =~ /mswin|mingw/) ? true : false)
end
def windows?
return ((RbConfig::CONFIG['host_os'] =~ /mswin|mingw/) ? true : false) if defined?( RbConfig )
return ((Config::CONFIG['host_os'] =~ /mswin|mingw/) ? true : false)
end

end
8 changes: 4 additions & 4 deletions bin/configinator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ class Configinator

constructor :config_walkinator, :projectinator, :mixinator

def loadinate(filepath:nil, mixins:[], env:{}, silent:false)
def loadinate(filepath:nil, mixins:[], env:{})
# Aliases for clarity
cmdline_filepath = filepath
cmdline_mixins = mixins || []

# Load raw config from command line, environment variable, or default filepath
project_filepath, config = @projectinator.load( filepath:cmdline_filepath, env:env, silent:silent )
project_filepath, config = @projectinator.load( filepath:cmdline_filepath, env:env )

# Extract cfg_enabled_mixins mixins list plus load paths list from config
cfg_enabled_mixins, cfg_load_paths = @projectinator.extract_mixins(
Expand All @@ -36,7 +36,7 @@ def loadinate(filepath:nil, mixins:[], env:{}, silent:false)
if not @projectinator.validate_mixins(
mixins: cfg_enabled_mixins,
load_paths: cfg_load_paths,
source: 'Config :mixins :enabled =>',
source: 'Config :mixins -> :enabled =>',
yaml_extension: yaml_ext
)
raise 'Project configuration file section :mixins failed validation'
Expand Down Expand Up @@ -82,7 +82,7 @@ def loadinate(filepath:nil, mixins:[], env:{}, silent:false)
)

# Merge mixins
@mixinator.merge( config:config, mixins:mixins_assembled, silent:silent )
@mixinator.merge( config:config, mixins:mixins_assembled )

return project_filepath, config
end
Expand Down
Loading

0 comments on commit 1765fc8

Please sign in to comment.