class Matrixeval::Runner

Attributes

argv[R]
command[R]

Public Class Methods

new(argv) click to toggle source
# File lib/matrixeval/runner.rb, line 15
def initialize(argv)
  @argv = argv
  @command = CommandLine.new(argv)
  @threads ||= []
  @matrixeval_results ||= []
end
start(argv) click to toggle source
# File lib/matrixeval/runner.rb, line 8
def start(argv)
  new(argv).start
end

Public Instance Methods

start() click to toggle source
# File lib/matrixeval/runner.rb, line 22
    def start
      load_plugin

      validates

      if command.init?
        init
      elsif command.all?
        run_all_contexts
      else
        run_a_specific_context
      end
    rescue OptionParser::InvalidOption => e
      puts <<~ERROR
        #{e.message}
        See 'matrixeval --help'
        ERROR
      exit
    rescue Config::YAML::MissingError
      puts "Please run 'matrixeval init' first to generate matrixeval.yml"
      puts "See 'matrixeval init -h'"
      exit
    ensure
      turn_on_stty_opost
    end

Private Instance Methods

contexts() click to toggle source
# File lib/matrixeval/runner.rb, line 181
def contexts
  @contexts ||= Context.all
end
init() click to toggle source
# File lib/matrixeval/runner.rb, line 60
def init
  Config::YAML.create_for(command.init_options[:target])
  Gitignore.update
end
load_plugin() click to toggle source
# File lib/matrixeval/runner.rb, line 199
def load_plugin
  require "matrixeval/#{Config.target_name}"
rescue LoadError, Config::YAML::MissingError
end
parallel(collection) { |sub_collection| ... } click to toggle source
# File lib/matrixeval/runner.rb, line 159
def parallel(collection)
  @threads = [] unless @threads.empty?
  @matrixeval_results = [] unless @matrixeval_results.empty?

  collection.each_slice(per_worker_contexts_count) do |sub_collection|
    @threads << Thread.new do
      yield sub_collection
    end
  end

  @threads.each(&:join)

  @threads.each do |thread|
    @matrixeval_results += (thread[:matrixeval_results] || [])
  end
end
per_worker_contexts_count() click to toggle source
# File lib/matrixeval/runner.rb, line 177
def per_worker_contexts_count
  [(contexts.count / workers_count), 1].max
end
pull_all_images() click to toggle source
# File lib/matrixeval/runner.rb, line 124
def pull_all_images
  parallel(Config.main_vector_variants) do |sub_variants|
    sub_variants.each do |variant|
      puts "Docker image check/pull #{variant.container.image}"
      image_exists = system %Q{[ -n "$(docker images -q #{variant.container.image})" ]}
      next if image_exists

      system "docker pull #{variant.container.image}"
    end
  end
end
report() click to toggle source
# File lib/matrixeval/runner.rb, line 136
def report
  turn_on_stty_opost

  table = Terminal::Table.new(title: Rainbow("MatrixEval").blue.bright + " Summary", alignment: :center) do |table|

    headers = Config.vectors.map(&:key) + ['result']
    table.add_row headers.map { |value| { value: value, alignment: :center } }
    table.add_separator 

    @matrixeval_results.each do |context, success|
      success_cell = [success ? Rainbow('Success').green : Rainbow('Failed').red]
      row = (context.variants.map(&:key) + success_cell).map do |value|
        { value: value, alignment: :center }
      end

      table.add_row row
    end

  end

  puts table
end
run_a_specific_context() click to toggle source
# File lib/matrixeval/runner.rb, line 109
def run_a_specific_context
  DockerCompose::File.create_all
  Gitignore.update
  ExtraMountFiles.create
  Config.target.create_files

  context = Context.find_by_command_options!(command.context_options)

  puts Rainbow("[ MatrixEval ] ").blue.bright + Rainbow(" #{context.name} ").white.bright.bg(:blue)
  puts Rainbow("[ MatrixEval ] Run \"#{command.rest_arguments.join(" ")}\"").blue.bright

  docker_compose = DockerCompose.new(context)
  docker_compose.run(command.rest_arguments)
end
run_all_contexts() click to toggle source
# File lib/matrixeval/runner.rb, line 65
def run_all_contexts
  DockerCompose::File.create_all
  Gitignore.update
  ExtraMountFiles.create
  Config.target.create_files

  pull_all_images

  if workers_count == 1
    run_all_contexts_sequentially
  else
    run_all_contexts_in_parallel
  end
end
run_all_contexts_in_parallel() click to toggle source
# File lib/matrixeval/runner.rb, line 94
def run_all_contexts_in_parallel
  parallel(contexts) do |sub_contexts|
    Thread.current[:matrixeval_results] = []

    sub_contexts.each do |context|
      docker_compose = DockerCompose.new(context)
      success = docker_compose.run(command.rest_arguments)

      Thread.current[:matrixeval_results] << [context, !!success]
    end
  end

  report
end
run_all_contexts_sequentially() click to toggle source
# File lib/matrixeval/runner.rb, line 80
def run_all_contexts_sequentially
  Context.all.each do |context|
    puts Rainbow("[ MatrixEval ] ").blue.bright + Rainbow(" #{context.name} ").white.bright.bg(:blue)
    puts Rainbow("[ MatrixEval ] Run \"#{command.rest_arguments.join(" ")}\"").blue.bright

    docker_compose = DockerCompose.new(context)
    success = docker_compose.run(command.rest_arguments)

    @matrixeval_results << [context, !!success]
  end

  report
end
turn_on_stty_opost() click to toggle source
# File lib/matrixeval/runner.rb, line 195
def turn_on_stty_opost
  system("stty opost")
end
validates() click to toggle source
# File lib/matrixeval/runner.rb, line 50
    def validates
      return if command.valid?

      puts <<~ERROR
        matrixeval: '#{argv.join(' ')}' is not a MatrixEval command.
        See 'matrixeval --help'
        ERROR
      exit
    end
workers_count() click to toggle source
# File lib/matrixeval/runner.rb, line 185
def workers_count
  count = if Config.parallel_workers == "number_of_processors"
    Concurrent.physical_processor_count
  else
    Integer(Config.parallel_workers)
  end

  [count, 1].max
end