<commit_before>module Riddle
  class Controller
    attr_accessor :path, :bin_path, :searchd_binary_name, :indexer_binary_name

    def initialize(configuration, path)
      @configuration  = configuration
      @path           = path

      @bin_path            = ''
      @searchd_binary_name = 'searchd'
      @indexer_binary_name = 'indexer'
    end

    def sphinx_version
      `#{indexer} 2>&1`[/Sphinx (\d+\.\d+(\.\d+|(?:-dev|(\-id64)?\-beta)))/, 1]
    rescue
      nil
    end

    def index(*indices)
      options = indices.last.is_a?(Hash) ? indices.pop : {}
      indices << '--all' if indices.empty?

      command = "#{indexer} --config \"#{@path}\" #{indices.join(' ')}"
      command << " --rotate" if running?

      Riddle::ExecuteCommand.call command, options[:verbose]
    end

    def start(options={})
      return if running?
      check_for_configuration_file

      command = "#{searchd} --pidfile --config \"#{@path}\""
      command << " --nodetach" if options[:nodetach]

      if options[:nodetach]
        exec(command)
      else
        result = Riddle::ExecuteCommand.call command
      end

      sleep(1)

      unless running?
        puts "Failed to start searchd daemon. Check #{@configuration.searchd.log}."
      end

      result
    end

    def stop
      return true unless running?
      check_for_configuration_file

      stop_flag = 'stopwait'
      stop_flag = 'stop' if Riddle.loaded_version.split('.').first == '0'
      command = %(#{searchd} --pidfile --config "#{@path}" --#{stop_flag})

      result = Riddle::ExecuteCommand.call command
      result.successful = !running?
      result
    end

    def pid
      if File.exists?(@configuration.searchd.pid_file)
        File.read(@configuration.searchd.pid_file)[/\d+/]
      else
        nil
      end
    end

    def rotate
      pid && Process.kill(:HUP, pid.to_i)
    end

    def running?
      !!pid && !!Process.kill(0, pid.to_i)
    rescue
      false
    end

    private

    def indexer
      "#{bin_path}#{indexer_binary_name}"
    end

    def searchd
      "#{bin_path}#{searchd_binary_name}"
    end

    def check_for_configuration_file
      return if File.exist?(@path)
      raise "Configuration file '#{@path}' does not exist"
    end
  end
end<commit_msg>Specific error class when configuration is missing<commit_after>module Riddle
  NoConfigurationFileError = Class.new(StandardError)

  class Controller
    attr_accessor :path, :bin_path, :searchd_binary_name, :indexer_binary_name

    def initialize(configuration, path)
      @configuration  = configuration
      @path           = path

      @bin_path            = ''
      @searchd_binary_name = 'searchd'
      @indexer_binary_name = 'indexer'
    end

    def sphinx_version
      `#{indexer} 2>&1`[/Sphinx (\d+\.\d+(\.\d+|(?:-dev|(\-id64)?\-beta)))/, 1]
    rescue
      nil
    end

    def index(*indices)
      options = indices.last.is_a?(Hash) ? indices.pop : {}
      indices << '--all' if indices.empty?

      command = "#{indexer} --config \"#{@path}\" #{indices.join(' ')}"
      command << " --rotate" if running?

      Riddle::ExecuteCommand.call command, options[:verbose]
    end

    def start(options={})
      return if running?
      check_for_configuration_file

      command = "#{searchd} --pidfile --config \"#{@path}\""
      command << " --nodetach" if options[:nodetach]

      if options[:nodetach]
        exec(command)
      else
        result = Riddle::ExecuteCommand.call command
      end

      sleep(1)

      unless running?
        puts "Failed to start searchd daemon. Check #{@configuration.searchd.log}."
      end

      result
    end

    def stop
      return true unless running?
      check_for_configuration_file

      stop_flag = 'stopwait'
      stop_flag = 'stop' if Riddle.loaded_version.split('.').first == '0'
      command = %(#{searchd} --pidfile --config "#{@path}" --#{stop_flag})

      result = Riddle::ExecuteCommand.call command
      result.successful = !running?
      result
    end

    def pid
      if File.exists?(@configuration.searchd.pid_file)
        File.read(@configuration.searchd.pid_file)[/\d+/]
      else
        nil
      end
    end

    def rotate
      pid && Process.kill(:HUP, pid.to_i)
    end

    def running?
      !!pid && !!Process.kill(0, pid.to_i)
    rescue
      false
    end

    private

    def indexer
      "#{bin_path}#{indexer_binary_name}"
    end

    def searchd
      "#{bin_path}#{searchd_binary_name}"
    end

    def check_for_configuration_file
      return if File.exist?(@path)

      raise Riddle::NoConfigurationFileError, "'#{@path}' does not exist"
    end
  end
end
{'fraction_non_alphanumeric': 0.13018383924754168, 'fraction_numerical': 0.003420265070542967, 'mean_word_length': 2.3326210826210825, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '779428', 'n_tokens_mistral': 1499, 'n_tokens_neox': 1464, 'n_words': 334}