<commit_before>require_relative 'tools/cane'
require_relative 'tools/flay'
require_relative 'tools/flog'
require_relative 'tools/reek'
require_relative 'tools/rubocop'
require_relative 'tools/bigfiles'
require_relative 'tools/punchlist'

# XXX: This name is too similar to process_runner

module Quality
  # Knows how to run different quality tools based on a configuration
  # already determined.
  class Runner
    include Tools::Cane
    include Tools::Flay
    include Tools::Flog
    include Tools::Reek
    include Tools::Rubocop
    include Tools::BigFiles
    include Tools::Punchlist

    extend Forwardable

    def initialize(config,
                   gem_spec: Gem::Specification,
                   quality_checker_class: Quality::QualityChecker,
                   count_io: IO,
                   count_file: File,
                   globber: Dir)
      @config = config
      @gem_spec = gem_spec
      @quality_checker_class = quality_checker_class
      @count_io = count_io
      @count_file = count_file
      @globber = globber
    end

    def run_quality
      tools.each { |tool| run_quality_with_tool(tool) }
    end

    def run_quality_with_tool(tool)
      installed = @gem_spec.find_all_by_name(tool).any?
      suppressed = @config.skip_tools.include? tool

      if installed && !suppressed
        method("quality_#{tool}".to_sym).call
      elsif !installed
        puts "#{tool} not installed"
      end
    end

    def run_ratchet
      # XXX: a lot of things know about globbing--isn't this config's job?
      @globber.glob("#{@config.output_dir}/*_high_water_mark")
        .each do |filename|
        run_ratchet_on_file(filename)
      end
    end

    def run_ratchet_on_file(filename)
      puts "Processing #{filename}"
      existing_violations = count_existing_violations(filename)
      new_violations = [0, existing_violations - 1].max
      write_violations(filename, new_violations)
    end

    def write_violations(filename, new_violations)
      @count_file.open(filename, 'w') do |file|
        file.write(new_violations.to_s + "\n")
      end
    end

    def count_existing_violations(filename)
      existing_violations = @count_io.read(filename).to_i
      fail("Problem with file #{filename}") if existing_violations < 0
      existing_violations
    end

    def tools
      self.class.ancestors.map do |ancestor|
        ancestor_name = ancestor.to_s
        next unless ancestor_name.start_with?('Quality::Tools::')
        ancestor_name.split('::').last.downcase
      end.compact
    end

    def ratchet_quality_cmd(cmd,
                            command_options,
                            &count_violations_on_line)
      quality_checker = @quality_checker_class.new(cmd,
                                                   command_options,
                                                   @config.output_dir,
                                                   @config.verbose)
      quality_checker.execute(&count_violations_on_line)
    end

    def_delegators :@config, :ruby_files, :ruby_files_glob, :source_files_glob,
                   :punchlist_regexp
  end
end
<commit_msg>Attempt at fixing #28 to not require bundler<commit_after>require 'forwardable'
require_relative 'tools/cane'
require_relative 'tools/flay'
require_relative 'tools/flog'
require_relative 'tools/reek'
require_relative 'tools/rubocop'
require_relative 'tools/bigfiles'
require_relative 'tools/punchlist'

# XXX: This name is too similar to process_runner

module Quality
  # Knows how to run different quality tools based on a configuration
  # already determined.
  class Runner
    include Tools::Cane
    include Tools::Flay
    include Tools::Flog
    include Tools::Reek
    include Tools::Rubocop
    include Tools::BigFiles
    include Tools::Punchlist

    extend ::Forwardable

    def initialize(config,
                   gem_spec: Gem::Specification,
                   quality_checker_class: Quality::QualityChecker,
                   count_io: IO,
                   count_file: File,
                   globber: Dir)
      @config = config
      @gem_spec = gem_spec
      @quality_checker_class = quality_checker_class
      @count_io = count_io
      @count_file = count_file
      @globber = globber
    end

    def run_quality
      tools.each { |tool| run_quality_with_tool(tool) }
    end

    def run_quality_with_tool(tool)
      installed = @gem_spec.find_all_by_name(tool).any?
      suppressed = @config.skip_tools.include? tool

      if installed && !suppressed
        method("quality_#{tool}".to_sym).call
      elsif !installed
        puts "#{tool} not installed"
      end
    end

    def run_ratchet
      # XXX: a lot of things know about globbing--isn't this config's job?
      @globber.glob("#{@config.output_dir}/*_high_water_mark")
        .each do |filename|
        run_ratchet_on_file(filename)
      end
    end

    def run_ratchet_on_file(filename)
      puts "Processing #{filename}"
      existing_violations = count_existing_violations(filename)
      new_violations = [0, existing_violations - 1].max
      write_violations(filename, new_violations)
    end

    def write_violations(filename, new_violations)
      @count_file.open(filename, 'w') do |file|
        file.write(new_violations.to_s + "\n")
      end
    end

    def count_existing_violations(filename)
      existing_violations = @count_io.read(filename).to_i
      fail("Problem with file #{filename}") if existing_violations < 0
      existing_violations
    end

    def tools
      self.class.ancestors.map do |ancestor|
        ancestor_name = ancestor.to_s
        next unless ancestor_name.start_with?('Quality::Tools::')
        ancestor_name.split('::').last.downcase
      end.compact
    end

    def ratchet_quality_cmd(cmd,
                            command_options,
                            &count_violations_on_line)
      quality_checker = @quality_checker_class.new(cmd,
                                                   command_options,
                                                   @config.output_dir,
                                                   @config.verbose)
      quality_checker.execute(&count_violations_on_line)
    end

    def_delegators :@config, :ruby_files, :ruby_files_glob, :source_files_glob,
                   :punchlist_regexp
  end
end

{'fraction_non_alphanumeric': 0.07871170463472113, 'fraction_numerical': 0.0012568735271013354, 'mean_word_length': 2.3505263157894736, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5409615', 'n_tokens_mistral': 1904, 'n_tokens_neox': 1822, 'n_words': 399}