<commit_before>require 'mkmf'
require 'open3'

module ConfigCurator

  class PackageLookup

    # Error when a package lookup cannot be completed.
    class LookupFailed < RuntimeError; end

    # Default list of supported package tools.
    TOOLS = %i(dpkg pacman)

    attr_accessor :tool, :tools

    def initialize tool: nil
      self.tool = tool
    end

    # Package tools that support package lookup ordered by preference.
    # @return [Array] list of supported package tools
    def tools
      @tools ||= TOOLS
    end

    # The package tool to use for this instance.
    # @return [Symbol] tool to use
    def tool
      return @tool if @tool

      tools.each do |cmd|
        if command? cmd
          return @tool = cmd
        end
      end
      @tool
    end

    # Checks if package is installed.
    # @param package [String] package name to check
    # @return [Boolean] if package is installed
    def installed? package
      fail LookupFailed, 'No supported package tool found.' if tool.nil?
      send tool, package
    end

    private

    # Checks if command exists.
    # @param command [String] command name to check
    # @return [String, nil] full path to command or nil if not found
    def command? command
      MakeMakefile::Logging.quiet = true
      MakeMakefile.find_executable command.to_s
    end

    #
    # Tool specific package lookup methods below.
    #

    def dpkg package
      cmd = command? 'dpkg'
      Open3.popen3 cmd, '-s', package do |_, _ , _, wait_thr|
        wait_thr.value.to_i
      end
    end

    def pacman package
      cmd = command? 'pacman'
      Open3.popen3 cmd, '-qQ', package do |_, _ , _, wait_thr|
        wait_thr.value.to_i
      end<commit_msg>Must check for 0 exit status in package lookup.<commit_after>require 'mkmf'
require 'open3'

module ConfigCurator

  class PackageLookup

    # Error when a package lookup cannot be completed.
    class LookupFailed < RuntimeError; end

    # Default list of supported package tools.
    TOOLS = %i(dpkg pacman)

    attr_accessor :tool, :tools

    def initialize tool: nil
      self.tool = tool
    end

    # Package tools that support package lookup ordered by preference.
    # @return [Array] list of supported package tools
    def tools
      @tools ||= TOOLS
    end

    # The package tool to use for this instance.
    # @return [Symbol] tool to use
    def tool
      return @tool if @tool

      tools.each do |cmd|
        if command? cmd
          return @tool = cmd
        end
      end
      @tool
    end

    # Checks if package is installed.
    # @param package [String] package name to check
    # @return [Boolean] if package is installed
    def installed? package
      fail LookupFailed, 'No supported package tool found.' if tool.nil?
      send tool, package
    end

    private

    # Checks if command exists.
    # @param command [String] command name to check
    # @return [String, nil] full path to command or nil if not found
    def command? command
      MakeMakefile::Logging.quiet = true
      MakeMakefile.find_executable command.to_s
    end

    #
    # Tool specific package lookup methods below.
    #

    def dpkg package
      cmd = command? 'dpkg'
      Open3.popen3 cmd, '-s', package do |_, _ , _, wait_thr|
        wait_thr.value.to_i == 0
      end
    end

    def pacman package
      cmd = command? 'pacman'
      Open3.popen3 cmd, '-qQ', package do |_, _ , _, wait_thr|
        wait_thr.value.to_i == 0
      end
{'fraction_non_alphanumeric': 0.0711835334476844, 'fraction_numerical': 0.0037164093767867354, 'mean_word_length': 2.270093457943925, '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': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1992528', 'n_tokens_mistral': 1046, 'n_tokens_neox': 1008, 'n_words': 397}