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] }