Class: Henitai::Reporter::Github

Inherits:
Base
  • Object
show all
Defined in:
lib/henitai/reporter.rb,
sig/henitai.rbs

Overview

GitHub Actions annotation reporter. Prints one ::warning workflow command per survived mutant so survivors show up inline on the PR diff. Killed/ignored/no-coverage/timeout mutants stay silent.

Instance Attribute Summary collapse

Attributes inherited from Base

#config, #history_store

Instance Method Summary collapse

Methods inherited from Base

#authoritative?, #canonical_path

Constructor Details

#initialize(config:, history_store: nil, io: $stdout) ⇒ Github

Returns a new instance of Github.

Parameters:



525
526
527
528
# File 'lib/henitai/reporter.rb', line 525

def initialize(config:, history_store: nil, io: $stdout)
  super(config:, history_store:)
  @io = io
end

Instance Attribute Details

#ioObject (readonly)

Returns the value of attribute io.

Returns:

  • (Object)


538
539
540
# File 'lib/henitai/reporter.rb', line 538

def io
  @io
end

Instance Method Details

#annotation_line(mutant) ⇒ String

Parameters:

Returns:

  • (String)


540
541
542
543
544
545
546
547
# File 'lib/henitai/reporter.rb', line 540

def annotation_line(mutant)
  format(
    "::warning file=%<file>s,line=%<line>d::%<message>s",
    file: relative_path(mutant.location.fetch(:file)),
    line: mutant.location.fetch(:start_line),
    message: escape_message("Survived mutant: #{mutant.operator}#{mutant.description}")
  )
end

#escape_message(message) ⇒ String

GitHub workflow-command message payload escaping: only %, LF and CR are significant; everything else is parsed literally.

Parameters:

  • (String)

Returns:

  • (String)


558
559
560
# File 'lib/henitai/reporter.rb', line 558

def escape_message(message)
  message.gsub("%", "%25").gsub("\n", "%0A").gsub("\r", "%0D")
end

#relative_path(file) ⇒ String

Parameters:

  • (String)

Returns:

  • (String)


549
550
551
552
553
554
# File 'lib/henitai/reporter.rb', line 549

def relative_path(file)
  pathname = Pathname.new(file)
  return file unless pathname.absolute?

  pathname.relative_path_from(Dir.pwd).to_s
end

#report(result) ⇒ void

This method returns an undefined value.

Parameters:



530
531
532
533
534
# File 'lib/henitai/reporter.rb', line 530

def report(result)
  result.mutants.select(&:survived?).each do |mutant|
    io.puts(annotation_line(mutant))
  end
end