class TurboTests::Runner

def start_subprocess(env, extra_args, tests, process_id)

def start_subprocess(env, extra_args, tests, process_id)
  if tests.empty?
    @messages << {
      "type" => "exit",
      "process_id" => process_id
    }
  else
    require "securerandom"
    env["RSPEC_FORMATTER_OUTPUT_ID"] = SecureRandom.uuid
    env["RUBYOPT"] = "-I#{File.expand_path("..", __dir__)}"
    command = [
      ENV["BUNDLE_BIN_PATH"], "exec", "rspec",
      *extra_args,
      "--seed", rand(2**16).to_s,
      "--format", "ParallelTests::RSpec::RuntimeLogger",
      "--out", @runtime_log,
      "--format", "TurboTests::JsonRowsFormatter",
      *tests
    ]
    if @verbose
      command_str = [
        env.map { |k, v| "#{k}=#{v}" }.join(" "),
        command.join(" ")
      ].select { |x| x.size > 0 }.join(" ")
      STDERR.puts "Process #{process_id}: #{command_str}"
    end
    _stdin, stdout, stderr, _wait_thr = Open3.popen3(env, *command)
    @threads <<
      Thread.new {
        require "json"
        stdout.each_line do |line|
          result = line.split(env["RSPEC_FORMATTER_OUTPUT_ID"])
          output = result.shift
          STDOUT.print(output) unless output.empty?
          message = result.shift
          next unless message
          message = JSON.parse(message)
          message["process_id"] = process_id
          @messages << message
        end
        @messages << {"type" => "exit", "process_id" => process_id}
      }
    @threads << start_copy_thread(stderr, STDERR)
  end
end