<commit_before># Levels defined using a text-based ruby DSL syntax.
# See #BaseDSL for the DSL format implementation.
class DSLDefined < Level
  include Seeded
  after_destroy :delete_level_file

  def dsl_default
    "Enter the level definition here.\n"
  end

  def self.setup(data)
    level = find_or_create_by({ name: data[:name] })
    level.send(:write_attribute, 'properties', {})
    level.update!(name: data[:name], game_id: Game.find_by(name: self.to_s).id, properties: data[:properties])
    level
  end

  def self.dsl_class
    "#{self}DSL".constantize
  end

  # Use DSL class to parse file
  def self.parse_file(filename, name=nil)
    parse(File.read(filename), filename, name)
  end

  # Use DSL class to parse string
  def self.parse(str, filename, name=nil)
    dsl_class.parse(str,filename,name)
  end

  def self.create_from_level_builder(params, level_params)
    text = level_params[:dsl_text] || params[:dsl_text]
    transaction do
      # Parse data, save updated level data to database
      data, i18n = dsl_class.parse(text, '')
      data[:properties].merge! level_params
      level = setup data

      # Save updated level data to external file
      File.write(Rails.root.join(level.filename), text)

      # Rewrite autogenerated 'dsls.en.yml' i18n file with new master-copy English strings
      yml_file = Rails.root.join("config/locales/dsls.en.yml")
      i18n_strings = File.exist?(yml_file) ? YAML.load_file(yml_file) : {}
      # Overwrite existing string keys with their new values
      i18n_strings.deep_merge! i18n
      i18n_warning = "# Autogenerated English-language level-definition locale file. Do not edit by hand or commit to version control.\n"
      File.write(yml_file, i18n_warning + i18n_strings.to_yaml(line_width: -1))
      level
    end
  end

  def filename
    # Find a file in config/scripts/**/*.[class]* containing the string "name '[name]'"
    grep_string = "grep -lir \"name '#{name}'\" --include=*.#{self.class.to_s.underscore}* config/scripts --color=never"
    `#{grep_string}`.chomp.presence || "config/scripts/#{name.parameterize.underscore}.#{self.class.to_s.underscore}"
  end

  def update(params)
    if params[:dsl_text].present?
      self.class.create_from_level_builder({dsl_text: params.delete(:dsl_text)}, params.merge(name: name))
    else
      super(params)
    end
  end

  private
  def delete_level_file
    level_file = Rails.root.join(filename)
    File.delete(level_file) if File.exist?(level_file)
  end

end<commit_msg>Prevent `name` from ending up in properties<commit_after># Levels defined using a text-based ruby DSL syntax.
# See #BaseDSL for the DSL format implementation.
class DSLDefined < Level
  include Seeded
  after_destroy :delete_level_file

  def dsl_default
    "Enter the level definition here.\n"
  end

  def self.setup(data)
    level = find_or_create_by({ name: data[:name] })
    level.send(:write_attribute, 'properties', {})
    level.update!(name: data[:name], game_id: Game.find_by(name: self.to_s).id, properties: data[:properties])
    level
  end

  def self.dsl_class
    "#{self}DSL".constantize
  end

  # Use DSL class to parse file
  def self.parse_file(filename, name=nil)
    parse(File.read(filename), filename, name)
  end

  # Use DSL class to parse string
  def self.parse(str, filename, name=nil)
    dsl_class.parse(str,filename,name)
  end

  def self.create_from_level_builder(params, level_params)
    text = level_params[:dsl_text] || params[:dsl_text]
    transaction do
      # Parse data, save updated level data to database
      data, i18n = dsl_class.parse(text, '')
      data[:properties].merge! level_params
      level = setup data

      # Save updated level data to external file
      File.write(Rails.root.join(level.filename), text)

      # Rewrite autogenerated 'dsls.en.yml' i18n file with new master-copy English strings
      yml_file = Rails.root.join("config/locales/dsls.en.yml")
      i18n_strings = File.exist?(yml_file) ? YAML.load_file(yml_file) : {}
      # Overwrite existing string keys with their new values
      i18n_strings.deep_merge! i18n
      i18n_warning = "# Autogenerated English-language level-definition locale file. Do not edit by hand or commit to version control.\n"
      File.write(yml_file, i18n_warning + i18n_strings.to_yaml(line_width: -1))
      level
    end
  end

  def filename
    # Find a file in config/scripts/**/*.[class]* containing the string "name '[name]'"
    grep_string = "grep -lir \"name '#{name}'\" --include=*.#{self.class.to_s.underscore}* config/scripts --color=never"
    `#{grep_string}`.chomp.presence || "config/scripts/#{name.parameterize.underscore}.#{self.class.to_s.underscore}"
  end

  def update(params)
    if params[:dsl_text].present?
      # Don't allow renaming
      params.delete(:name)
      self.class.create_from_level_builder({dsl_text: params.delete(:dsl_text)}, params)
    else
      super(params)
    end
  end

  private
  def delete_level_file
    level_file = Rails.root.join(filename)
    File.delete(level_file) if File.exist?(level_file)
  end

end
{'fraction_non_alphanumeric': 0.11377010592389172, 'fraction_numerical': 0.006669282071400549, 'mean_word_length': 3.631244323342416, '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': '4105138', 'n_tokens_mistral': 1731, 'n_tokens_neox': 1655, 'n_words': 414}