lib/parallel_tests/cli.rb in parallel_tests-1.3.9 vs lib/parallel_tests/cli.rb in parallel_tests-1.5.0

- old
+ new

@@ -1,8 +1,9 @@ require 'optparse' require 'tempfile' require 'parallel_tests' +require 'shellwords' module ParallelTests class CLI def run(argv) options = parse_options!(argv) @@ -104,13 +105,16 @@ options = {} OptionParser.new do |opts| opts.banner = <<-BANNER.gsub(/^ /, '') Run all tests in parallel, giving each process ENV['TEST_ENV_NUMBER'] ('', '2', '3', ...) - [optional] Only run selected files & folders: - parallel_test test/bar test/baz/xxx_text.rb + [optional] Only selected files & folders: + parallel_test test/bar test/baz/xxx_text.rb + [optional] Pass test-options and files via `--`: + parallel_test -- -t acceptance -f progress -- spec/foo_spec.rb spec/acceptance + Options are: BANNER opts.on("-n [PROCESSES]", Integer, "How many processes to use, default: available CPUs") { |n| options[:count] = n } opts.on("-p", "--pattern [PATTERN]", "run tests matching this pattern") { |pattern| options[:pattern] = /#{pattern}/ } opts.on("--group-by [TYPE]", <<-TEXT.gsub(/^ /, '') @@ -138,12 +142,12 @@ options[:isolate] = true end opts.on("--only-group INT[, INT]", Array) { |groups| options[:only_group] = groups.map(&:to_i) } - opts.on("-e", "--exec [COMMAND]", "execute this code parallel and with ENV['TEST_ENV_NUM']") { |path| options[:execute] = path } - opts.on("-o", "--test-options '[OPTIONS]'", "execute test commands with those options") { |arg| options[:test_options] = arg } + opts.on("-e", "--exec [COMMAND]", "execute this code parallel and with ENV['TEST_ENV_NUMBER']") { |path| options[:execute] = path } + opts.on("-o", "--test-options '[OPTIONS]'", "execute test commands with those options") { |arg| options[:test_options] = arg.lstrip } opts.on("-t", "--type [TYPE]", "test(default) / rspec / cucumber / spinach") do |type| begin @runner = load_runner(type) rescue NameError, LoadError => e puts "Runner for `#{type}` type has not been found! (#{e})" @@ -165,22 +169,45 @@ if options[:count] == 0 options.delete(:count) options[:non_parallel] = true end - abort "Pass files or folders to run" if argv.empty? && !options[:execute] + files, remaining = extract_file_paths(argv) + unless options[:execute] + abort "Pass files or folders to run" unless files.any? + options[:files] = files + end - options[:files] = argv + append_test_options(options, remaining) options[:group_by] ||= :filesize if options[:only_group] raise "--group-by found and --single-process are not supported" if options[:group_by] == :found and options[:single_process] allowed = [:filesize, :runtime, :found] if !allowed.include?(options[:group_by]) && options[:only_group] raise "--group-by #{allowed.join(" or ")} is required for --only-group" end options + end + + def extract_file_paths(argv) + dash_index = argv.rindex("--") + file_args_at = (dash_index || -1) + 1 + [argv[file_args_at..-1], argv[0...(dash_index || 0)]] + end + + def extract_test_options(argv) + dash_index = argv.index("--") || -1 + argv[dash_index+1..-1] + end + + def append_test_options(options, argv) + new_opts = extract_test_options(argv) + return if new_opts.empty? + + prev_and_new = [options[:test_options], new_opts.shelljoin] + options[:test_options] = prev_and_new.compact.join(' ') end def load_runner(type) require "parallel_tests/#{type}/runner" runner_classname = type.split("_").map(&:capitalize).join.sub("Rspec", "RSpec")