Skip to content

Instantly share code, notes, and snippets.

@maddiesch
Created August 22, 2018 20:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maddiesch/e27becb5aced23c8f0ce9406337c52ad to your computer and use it in GitHub Desktop.
Save maddiesch/e27becb5aced23c8f0ce9406337c52ad to your computer and use it in GitHub Desktop.
Run a subcommand a set number of times
#!/usr/bin/env ruby
##
# Usage `run --number 5 b rspec`
#
#
##
require 'optparse'
require 'open3'
require 'shellwords'
require 'securerandom'
require 'fileutils'
##
# Run a command and send the command output to stdout/stderr
class Command
def run(*args)
execute_command(*args)
end
private
def execute_command(*args)
status = Open3.popen3(*args) do |_i, o, e, t|
out = Thread.new do
until o.eof? || o.closed?
STDOUT.puts o.gets
end
end
err = Thread.new do
until e.eof? || o.closed?
STDERR.puts e.gets
end
end
out.join
err.join
t.value.to_i
end
status
end
end
options = {
count: 3,
fail_fast: false
}
OptionParser.new do |opts|
opts.banner = 'Usage: run -n 10 [command]'
opts.on('--number N', Integer, 'Number of times to run') do |count|
options[:count] = count
end
opts.on('--fail-fast', 'Stop if there is a failure') do
options[:fail_fast] = true
end
end.parse!
sub_command = Shellwords.join(ARGV.map { |word| Shellwords.escape(word) })
results = []
path = File.join('/', 'tmp', SecureRandom.uuid)
content = <<~EOF
#!/bin/bash --login
source ~/.bash_profile
shopt -s expand_aliases
#{sub_command}
EOF
File.open(path, 'w+') { |f| f.write(content) }
FileUtils.chmod('+x', path)
begin
options[:count].times do |index|
STDOUT.puts "Running (#{index}) #{sub_command}"
status = Command.new.run("/bin/bash -c '#{path}'")
if options[:fail_fast] && status != 0
STDERR.puts "Early Exit: Sub Command Failed #{status}"
raise "Early Exit: Sub Command Failed #{status}"
end
results << status
end
rescue StandardError => error
STDERR.puts error.message
exit(1)
ensure
FileUtils.rm(path)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment