require 'stringio' module Pluginscan # Responsible for scanning a file for a set of issue types class FileIssuesScanner attr_reader :file_results def initialize(checks) @checks = checks end # Returns an array of CheckFindings objects def scan(file_contents) # Run each check on the file checks_findings = @checks.map { |check| LinesIssuesScanner.new(check).scan(file_contents) } checks_findings.select(&:any_findings?) end end end module Pluginscan # Responsible for scanning each line of a file for issues of a certain type class LinesIssuesScanner def initialize(check) @line_issues_scanner = LineIssuesScanner.new(check) @check_findings = CheckFindings.new(check) end def scan(file_contents) string_io = StringIO.new(file_contents) @check_findings.tap do |check_findings| string_io.each_line do |line| check_findings.add @line_issues_scanner.scan(line, string_io.lineno) end end end end end