Class: Specwrk::CLI::Watch

Inherits:
Dry::CLI::Command
  • Object
show all
Includes:
PortDiscoverable, WorkerProcesses
Defined in:
lib/specwrk/cli.rb

Constant Summary collapse

SEED_LOOP_INIT_SCRIPT =
<<~RUBY
  require "specwrk/ipc"
  require "specwrk/seed_loop"

  parent_pid = Integer(ENV.fetch("SPECWRK_IPC_PARENT_PID"))
  fd = Integer(ENV.fetch("SPECWRK_IPC_FD"))
  ipc = Specwrk::IPC.from_child_fd(fd, parent_pid: parent_pid)

  Specwrk::SeedLoop.loop!(ipc)
RUBY

Constants included from WorkerProcesses

Specwrk::CLI::WorkerProcesses::WORKER_INIT_SCRIPT

Instance Method Summary collapse

Methods included from PortDiscoverable

#find_open_port

Methods included from WorkerProcesses

#drain_outputs, #start_workers, #worker_count, #worker_env_for

Instance Method Details

#call(count:, watchfile:, **args) ⇒ Object



363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
# File 'lib/specwrk/cli.rb', line 363

def call(count:, watchfile:, **args)
  $stdout.sync = true

  # nil this env var if it exists to prevent never-ending workers
  ENV["SPECWRK_SRV_URI"] = nil

  # Start on a random open port to not conflict with another server
  ENV["SPECWRK_SRV_PORT"] = find_open_port.to_s
  ENV["SPECWRK_SRV_URI"] = "http://localhost:#{ENV.fetch("SPECWRK_SRV_PORT", "5138")}"

  ENV["SPECWRK_SEED_WAITS"] = "0"
  ENV["SPECWRK_MAX_BUCKET_SIZE"] = "1"
  ENV["SPECWRK_COUNT"] = count.to_s
  ENV["SPECWRK_RUN"] = "watch"

  web_pid

  return if Specwrk.force_quit

  seed_pid

  start_watcher(watchfile)

  require "specwrk/cli_reporter"

  title "šŸ‘€ for changes"

  loop do
    status "šŸ‘€ Watching for file changes..."

    @worker_pids = nil
    Thread.pass until file_queue.length.positive? || Specwrk.force_quit

    break if Specwrk.force_quit

    files = []
    files.push(file_queue.pop) until file_queue.length.zero?
    status "Running specs for #{files.join(" ")}..."
    ipc.write(files.join(" "))

    example_count = ipc.read.to_i
    if example_count.positive?
      puts "\n🌱 Seeded #{example_count} examples for execution\n"
    else
      puts "\nšŸ™… No examples to seed for execution\n"
    end

    next if example_count.zero?
    title "šŸ‘· on #{example_count} examples"

    return if Specwrk.force_quit
    start_workers

    Specwrk.wait_for_pids_exit(@worker_pids)

    drain_outputs
    return if Specwrk.force_quit

    reporter = Specwrk::CLIReporter.new

    status = reporter.report
    puts

    if status.zero?
      title "🟢 #{reporter.example_count} examples passed"
    else
      title " šŸ”“ #{reporter.failure_count}/#{reporter.example_count} examples failed"
    end

    $stdout.flush
  end

  ipc.write "INT" # wakes the socket
  Specwrk.wait_for_pids_exit([web_pid, seed_pid])
end