lib/jive.rb in jive-0.1.0 vs lib/jive.rb in jive-0.2.0
- old
+ new
@@ -1,144 +1,17 @@
# frozen_string_literal: true
require "fileutils"
-require "jive/version"
require "open3"
+require "jive/batch_runner"
+require "jive/popen"
+require "jive/runner"
+require "jive/version"
+
module Jive
class Error < StandardError; end
def self.run(tasks)
Jive::BatchRunner.new.run(tasks)
- end
-
- module Popen
- Result = Struct.new(:command, :stdout, :stderr, :status, :duration)
-
- def self.popen(command, path = nil, env = {}, &block)
- result = popen_with_detail(command, path, env, &block)
-
- ["#{result.stdout}#{result.stderr}", result.status&.exitstatus]
- end
-
- def self.popen_with_detail(command, path = Dir.pwd, env = {})
- FileUtils.mkdir_p(path) unless File.directory?(path)
-
- captured_stdout = ''
- captured_stderr = ''
- exit_status = nil
- start = Time.now
-
- Open3.popen3(env.merge('PWD' => path), *Array(command), { chdir: path }) do |stdin, stdout, stderr, wait_thr|
- out_reader = Thread.new { stdout.read }
- err_reader = Thread.new { stderr.read }
-
- yield(stdin) if block_given?
-
- stdin.close
- captured_stdout = out_reader.value
- captured_stderr = err_reader.value
- exit_status = wait_thr.value
- end
- Result.new(command, captured_stdout, captured_stderr, exit_status, Time.now - start)
- end
- end
-
- class BatchRunner
- attr_reader :runner, :stdout
-
- def initialize(runner: Runner.new, stdout: STDOUT)
- @runner = runner
- @stdout = stdout
- end
-
- def run(tasks, verbose: true)
- runner.run(tasks) do |command, &run|
- stdout.puts
- stdout.puts "$ #{command.join(' ')}"
- result = run.call
- stdout.print result.stdout if verbose
- stdout.print result.stderr if verbose
- stdout.puts "==> Finished in #{result.duration} seconds"
- stdout.puts
- end
- stdout.puts '==================================================='
- if runner.all_success_and_clean?
- stdout.puts 'Passed successfully.'
- return 0
- elsif runner.all_success?
- stdout.puts 'Passed successfully, but we have warnings:'
- stdout.puts
- emit_warnings
- return 2
- else
- stdout.puts 'Something failed:'
- emit_warnings
- emit_errors
- return 1
- end
- end
-
- private
-
- def emit_warnings
- runner.warned_results.each do |result|
- stdout.puts
- stdout.puts "**** #{result.command.join(' ')} had the following warning(s):"
- stdout.puts
- stdout.puts result.stderr
- stdout.puts
- end
- end
-
- def emit_errors
- runner.failed_results.each do |result|
- stdout.puts
- stdout.puts "**** #{result.command.join(' ')} failed with the following error(s):"
- stdout.puts
- stdout.puts result.stdout
- stdout.puts result.stderr
- stdout.puts
- end
- end
- end
-
- class Runner
- attr_reader :results
-
- def initialize
- @results = []
- end
-
- def run(commands, &block)
- commands.each do |command|
- block.call(command) do
- cmd_result = Popen.popen_with_detail(command)
- results << cmd_result
- cmd_result
- end
- end
- end
-
- def all_success_and_clean?
- all_success? && all_stderr_empty?
- end
-
- def all_success?
- results.all? { |result| result.status.success? }
- end
-
- def all_stderr_empty?
- results.all? { |result| result.stderr.empty? }
- end
-
- def failed_results
- results.reject { |result| result.status.success? }
- end
-
- def warned_results
- results.select do |result|
- result.status.success? && !result.stderr.empty?
- end
- end
end
end