<commit_before>require 'yaml'
require 'json'

module OodAppkit
  # Helper methods for parsing/deserializing yml configuration files
  module ConfigParser
    # Specific version hash in the yaml file to parse
    YAML_VERSION = 'v1'

    # Identifier used to distinguish class names when deserializing
    CLASS_ID = 'type'

    # Exception raise when unable to access config file or directory
    class InvalidConfigPath < StandardError; end

    # Parse/deserialize a configuration file or a set of configuration files
    # @param config [#to_s] configuration file or directory
    # @raise [InvalidConfigPath] if config path is inaccessible
    # @return [Hash] hash of deserialized config file
    def self.parse(config:)
      # use 'type' to distinguish class name in yaml file
      JSON.create_id = CLASS_ID

      config = Pathname.new(config.to_s).expand_path
      if config.file?
        parse_file config
      elsif config.directory?
        config.children.each_with_object({}) do |f, h|
          /^(.+)\.yml$/.match(f.basename.to_s) { h[$1.to_sym] = parse_file(f) }
        end
      else
        raise InvalidConfigPath, "invalid config path: #{config}"
      end
    end

    private
      # Parse a single yaml file
      def self.parse_file(file)
        JSON.load(JSON.dump(YAML.load(File.read(file.to_s))[YAML_VERSION])).deep_symbolize_keys
      end
  end
end<commit_msg>return empty hash if v1 not defined<commit_after>require 'yaml'
require 'json'

module OodAppkit
  # Helper methods for parsing/deserializing yml configuration files
  module ConfigParser
    # Specific version hash in the yaml file to parse
    YAML_VERSION = 'v1'

    # Identifier used to distinguish class names when deserializing
    CLASS_ID = 'type'

    # Exception raise when unable to access config file or directory
    class InvalidConfigPath < StandardError; end

    # Parse/deserialize a configuration file or a set of configuration files
    # @param config [#to_s] configuration file or directory
    # @raise [InvalidConfigPath] if config path is inaccessible
    # @return [Hash] hash of deserialized config file
    def self.parse(config:)
      # use 'type' to distinguish class name in yaml file
      JSON.create_id = CLASS_ID

      config = Pathname.new(config.to_s).expand_path
      if config.file?
        parse_file config
      elsif config.directory?
        config.children.each_with_object({}) do |f, h|
          /^(.+)\.yml$/.match(f.basename.to_s) { h[$1.to_sym] = parse_file(f) }
        end
      else
        raise InvalidConfigPath, "invalid config path: #{config}"
      end
    end

    private
      # Parse a single yaml file
      def self.parse_file(file)
        JSON.load(JSON.dump(YAML.load(File.read(file.to_s)).fetch(YAML_VERSION, {}))).deep_symbolize_keys
      end
  end
end
{'fraction_non_alphanumeric': 0.08221119773210489, 'fraction_numerical': 0.001771793054571226, 'mean_word_length': 2.992927864214993, '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': '5085452', 'n_tokens_mistral': 853, 'n_tokens_neox': 811, 'n_words': 268}