<commit_before>require 'digest/sha1'
require 'logger'
require 'memoizable'

class GitHubUpsert < Struct.new(:client, :repo_name, :filename, :content)
  include Memoizable
  NEWLINE = "\n".freeze

  def self.execute(*args, &block)
    new(*args, &block).execute
  end

  def initialize(client, repo_name, filename)
    content = yield.to_s
    content << NEWLINE unless content.end_with?(NEWLINE)
    super(client, repo_name, filename, content)
  end

  def execute
    if exists?
      update! if changed?
    else
      add!
    end
  end

  private

  def update!
    logger.info(message)
    client.update_content(repo_name, filename, message, file[:sha], content)
  end

  def add!
    logger.info('Add ' + filename)
    client.add_content(repo_name, filename, message, content)
  end

  def exists?
    !!file
  end
  memoize :exists?

  def changed?
    file[:sha] != sha
  end
  memoize :changed?

  def file
    contents = client.repo(repo_name).rels[:contents].get.data
    contents.find { |file| file[:path] == filename }
  rescue Octokit::NotFound # repo is empty
    nil
  end
  memoize :file

  def sha
    # see http://git-scm.com/book/en/Git-Internals-Git-Objects#Object-Storage
    Digest::SHA1.hexdigest("blob #{content.size}\0" + content)
  end
  memoize :sha

  def message
    'Update ' + filename
  end
  memoize :message

  def logger
    Logger.new(STDOUT)
  end
  memoize :logger
end
<commit_msg>Methods defs return the name as a symbol in 2.1+<commit_after>require 'digest/sha1'
require 'logger'
require 'memoizable'

class GitHubUpsert < Struct.new(:client, :repo_name, :filename, :content)
  include Memoizable
  NEWLINE = "\n".freeze

  def self.execute(*args, &block)
    new(*args, &block).execute
  end

  def initialize(client, repo_name, filename)
    content = yield.to_s
    content << NEWLINE unless content.end_with?(NEWLINE)
    super(client, repo_name, filename, content)
  end

  def execute
    if exists?
      update! if changed?
    else
      add!
    end
  end

  private

  def update!
    logger.info(message)
    client.update_content(repo_name, filename, message, file[:sha], content)
  end

  def add!
    logger.info('Add ' + filename)
    client.add_content(repo_name, filename, message, content)
  end

  memoize def exists?
    !!file
  end

  memoize def changed?
    file[:sha] != sha
  end

  memoize def file
    contents = client.repo(repo_name).rels[:contents].get.data
    contents.find { |file| file[:path] == filename }
  rescue Octokit::NotFound # repo is empty
    nil
  end

  memoize def sha
    # see http://git-scm.com/book/en/Git-Internals-Git-Objects#Object-Storage
    Digest::SHA1.hexdigest("blob #{content.size}\0" + content)
  end

  memoize def message
    'Update ' + filename
  end

  memoize def logger
    Logger.new(STDOUT)
  end
end

{'fraction_non_alphanumeric': 0.11079545454545454, 'fraction_numerical': 0.002840909090909091, 'mean_word_length': 3.210762331838565, 'pattern_counts': {'":': 0, '<': 9, '<?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': '1825267', 'n_tokens_mistral': 963, 'n_tokens_neox': 941, 'n_words': 245}