lib/org-converge/command.rb in org-converge-0.0.13 vs lib/org-converge/command.rb in org-converge-0.0.14
- old
+ new
@@ -2,10 +2,11 @@
class Command
attr_reader :dotorg
attr_reader :logger
attr_reader :ob
attr_reader :engine
+ attr_reader :runmode
def initialize(options)
@options = options
@dotorg = options['<org_file>']
@root_dir = options['--root-dir']
@@ -25,10 +26,13 @@
@babel = nil
@logger = Logger.new(options['--log'] || STDOUT)
logger.formatter = proc do |severity, datetime, progname, msg|
"[#{datetime.strftime('%Y-%m-%dT%H:%M:%S %z')}] #{msg}\n"
end
+
+ # Keep track of the exit status from the process for idempotency checks
+ @procs_exit_status = Hash.new { |h,k| h[k] = { } }
end
def execute!
case
when @options['--showfiles']
@@ -46,11 +50,11 @@
false
end
def converge!
tangle!
- runmode = @options['--runmode'] || ob.in_buffer_settings['RUNMODE']
+ @runmode = @options['--runmode'] || ob.in_buffer_settings['RUNMODE']
case
when @options['--name']
if runmode == 'sequentially'
run_matching_blocks_sequentially!
else
@@ -63,11 +67,11 @@
def dispatch_runmode(runmode)
case runmode
when 'parallel'
run_blocks_in_parallel!
- when 'sequential'
+ when 'sequential', 'idempotent'
run_blocks_sequentially!
when 'chained', 'chain', 'tasks'
run_blocks_chain!
when 'spec'
run_against_blocks_results!
@@ -129,31 +133,30 @@
logger.error "Could not find a final task to run!"
end
end
def run_blocks_sequentially!
- @engine = OrgConverge::Engine.new(:logger => @logger, :babel => @babel)
babel.tangle_runnable_blocks!(@run_dir)
runlist_stack = []
babel.ob.scripts.each do |key, script|
runlist_stack << [key, script]
end
while not runlist_stack.empty?
key, script = runlist_stack.shift
-
# Decision: Only run blocks which have a name
next unless script[:header][:name]
-
display_name = script[:header][:name]
- with_running_engine do |engine|
+ exit_status_list = with_running_engine(:runmode => @runmode) \
+ do |engine|
file = File.expand_path("#{@run_dir}/#{key}")
bin = determine_lang_bin(script)
cmd = "#{bin} #{file}"
run_procs(script, cmd, engine)
end
+ @procs_exit_status.merge!(exit_status_list)
end
logger.info "Run has completed successfully.".fg 'green'
end
def run_blocks_in_parallel!
@@ -207,11 +210,11 @@
display_name = script[:header][:name]
with_running_engine do |engine|
file = File.expand_path("#{@run_dir}/#{key}")
bin = determine_lang_bin(script)
cmd = "#{bin} #{file}"
- engine.register display_name, cmd, { :cwd => @root_dir, :logger => logger }
+ run_procs(script, cmd, engine)
end
end
logger.info "Run has completed successfully.".fg 'green'
end
@@ -342,9 +345,29 @@
end
def run_procs(script, cmd, engine=nil)
engine ||= @engine
display_name = script[:header][:name]
+
+ if @runmode == 'idempotent'
+ case
+ when script[:header][:if]
+ block_name = script[:header][:if]
+ exit_status = @procs_exit_status[block_name]
+ unless exit_status == 0
+ logger.info "#{display_name.fg 'green'} -- Skipped since :if clause matches check from '#{block_name.fg 'yellow'}'"
+ return
+ end
+ when script[:header][:unless]
+ block_name = script[:header][:unless]
+ exit_status = @procs_exit_status[block_name]
+ if exit_status == 0
+ logger.info "#{display_name.fg 'green'} -- Skipped since :unless clause matches check from '#{block_name.fg 'yellow'}'"
+ return
+ end
+ end
+ end
+
if script[:header][:procs]
procs = script[:header][:procs].to_i
1.upto(procs) do |i|
proc_name = "#{display_name}:#{i}"
engine.register proc_name, cmd, { :cwd => @root_dir, :logger => logger, :header => script[:header] }