Commit 5b03930
Changed files (10)
exe
lib
test
integration
exe/jive
@@ -1,4 +1,4 @@
#!/usr/bin/env -S ruby --disable-gems
# frozen_string_literal: true
-require "jive"
+require "jive/cli"
lib/jive/batch_runner.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+module Jive
+ class BatchRunner
+ attr_reader :runner, :stdout
+
+ def initialize(runner: Runner.new, stdout: $stdout)
+ @runner = runner
+ @stdout = stdout
+ end
+
+ def run(tasks)
+ stream_output_for(runner, tasks)
+ stdout.puts "==================================================="
+ print_result_for(runner)
+ end
+
+ private
+
+ def stream_output_for(runner, tasks)
+ runner.run(tasks) do |command, &run|
+ stdout.puts
+ stdout.puts "$ #{command.join(" ")}"
+ result = run.call
+ stdout.print result.stdout
+ stdout.print result.stderr
+ stdout.puts "==> Finished in #{result.duration} seconds"
+ stdout.puts
+ end
+ end
+
+ def print_result_for(runner)
+ if runner.all_success_and_clean?
+ stdout.puts "Passed successfully."
+ 0
+ elsif runner.all_success?
+ stdout.puts "Passed successfully, but we have warnings:"
+ stdout.puts
+ emit_warnings_for(runner)
+ 2
+ else
+ stdout.puts "Something failed:"
+ emit_warnings_for(runner)
+ emit_errors_for(runner)
+ 1
+ end
+ end
+
+ def emit_warnings_for(runner)
+ 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_for(runner)
+ 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
+end
lib/jive/cli.rb
@@ -0,0 +1,4 @@
+# frozen_string_literal: true
+
+require "thor"
+require "jive"
lib/jive/popen.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+module Jive
+ 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
+end
lib/jive/runner.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+module Jive
+ 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
lib/jive.rb
@@ -1,146 +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."
- 0
- elsif runner.all_success?
- stdout.puts "Passed successfully, but we have warnings:"
- stdout.puts
- emit_warnings
- 2
- else
- stdout.puts "Something failed:"
- emit_warnings
- emit_errors
- 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
test/integration/jive_test.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+require "test_helper"
+
+class JiveTest < Minitest::Test
+ def test_run_exits_with_exit_code_zero
+ assert_equal 0, Jive.run([["echo", "."]])
+ end
+end
.rubocop.yml
@@ -1,9 +1,20 @@
AllCops:
+ NewCops: enable
TargetRubyVersion: 2.5
Layout/LineLength:
Max: 120
+Metrics/AbcSize:
+ Exclude:
+ - lib/jive/batch_runner.rb
+ - lib/jive/popen.rb
+
+Metrics/MethodLength:
+ Exclude:
+ - lib/jive/batch_runner.rb
+ - lib/jive/popen.rb
+
Style/Documentation:
Enabled: false
Gemfile
@@ -8,3 +8,5 @@ gemspec
gem "minitest", "~> 5.0"
gem "rake", "~> 13.0"
gem "rubocop", "~> 1.7"
+gem "rubocop-minitest", "~> 0.1"
+gem "rubocop-rake", "~> 0.5"
Gemfile.lock
@@ -27,6 +27,10 @@ GEM
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.4.1)
parser (>= 2.7.1.5)
+ rubocop-minitest (0.10.3)
+ rubocop (>= 0.87, < 2.0)
+ rubocop-rake (0.5.1)
+ rubocop
ruby-progressbar (1.11.0)
thor (1.1.0)
unicode-display_width (2.0.0)
@@ -39,6 +43,8 @@ DEPENDENCIES
minitest (~> 5.0)
rake (~> 13.0)
rubocop (~> 1.7)
+ rubocop-minitest (~> 0.1)
+ rubocop-rake (~> 0.5)
BUNDLED WITH
2.2.8