<commit_before>#!/usr/bin/env ruby

require 'active_support'
require 'fileutils'
require 'pathname'

module RenameRefactor
  AFFECTED_FILETYPES = %w[
    rb
    js
    coffee
    html
    haml
    erb
    css
    sass
    scss
    yml
  ]

  DIRECTORIES = %w[
    app
    config
    git
    lib
    spec
    test
  ]

  REPLACE_WORDS = {
    'entity' => 'symbol',
    'link' => 'mapping',
  }

  class RenameRefactorProvider
    include ActiveSupport::Inflector

    attr_accessor :verbose, :dry_run

    def initialize(verbose: false, dry_run: true)
      self.verbose = verbose
      self.dry_run = dry_run
    end

    def run
      REPLACE_WORDS.each { |old_word, new_word| replace old_word, new_word }
    end

    def replace(old_word, new_word)
      affected_files.each do |file|
        replace_in_file(file, old_word, new_word)
        rename_file(file, old_word, new_word)
      end
    end

    def replace_in_file(file, old_word, new_word)
      commands = [
        "gsub(\"#{old_word}\",\"#{new_word}\")",
        "gsub(\"#{pluralize(old_word)}\",\"#{pluralize(new_word)}\")",
        "gsub(\"#{camelize(old_word)}\",\"#{camelize(new_word)}\")",
        "gsub(\"#{camelize(pluralize(old_word))}\","\
          "\"#{camelize(pluralize(new_word))}\")",
      ]
      tmp_file = "> /tmp/awk_tmp_file && mv /tmp/awk_tmp_file #{file}"
      command = "#{awk} '{#{commands.join(';')};print}' #{file} #{tmp_file}"
      puts command if verbose
      system(command) unless dry_run
    end

    def rename_file(old_filename, old_word, new_word)
      new_filename = old_filename.gsub(
        /(?<=_|\b)(#{old_word}|#{pluralize(old_word)})/) do |match|
        match == old_word ? new_word : pluralize(new_word)
      end
      if new_filename != old_filename
        puts "#{old_filename} --> #{new_filename}" if verbose
        if !dry_run
          FileUtils.mkdir_p(File.dirname(new_filename))
          FileUtils.mv(old_filename, new_filename)
        end
      end
    end

    def affected_files
      filetype = AFFECTED_FILETYPES.first
      loc = DIRECTORIES.join(' ')
      out = `find #{loc} -iname "*.#{filetype}" #{other_filetype_options}`
      out.lines.map { |l| l.delete("\n") }
    end

    def other_filetype_options
      AFFECTED_FILETYPES[1..-1].reduce('') do |options, filetype|
        options << "-o -iname \"*.#{filetype}\" "
      end
    end

    def awk
      'awk'
    end
  end

  class MigrationProvider
    include ActiveSupport::Inflector

    STRUCTURE_SQL_PATH = Pathname.new('db/structure.sql')
    MIGRATION_DIRPATH  = Pathname.new('db/migrate')

    attr_accessor :verbose, :dry_run, :migration_commands

    def initialize(verbose: false, dry_run: true)
      self.verbose = verbose
      self.dry_run = dry_run
      self.migration_commands = []
    end

    def run
      clean_slate unless dry_run
      sql_statements = read_structure_sql

      sql_statements.each do |sql_statement|
        rename_columns(sql_statement)
        rename_table(sql_statement)
        rebuild_index(sql_statement)
        rename_in_function(sql_statement)
        rename_primary_keys(sql_statement)
        rebuild_foreign_keys(sql_statement)
      end

      puts migration_commands.map(&:inspect).join("\n") if dry_run && verbose
      write_migration
    end

    def clean_slate
      puts 'Running rake db:migrate:clean' if verbose
      system('bundle exec rake db:migrate:clean')
    end

    def read_structure_sql
      STRUCTURE_SQL_PATH.readlines("\n\n\n").map do |command|
        command.lines.select do |line|
          !line.start_with?('--') && line != "\n"
        end.join("\n")
      end<commit_msg>Don't write migration file in dry_run.<commit_after>#!/usr/bin/env ruby

require 'active_support'
require 'fileutils'
require 'pathname'

module RenameRefactor
  AFFECTED_FILETYPES = %w[
    rb
    js
    coffee
    html
    haml
    erb
    css
    sass
    scss
    yml
  ]

  DIRECTORIES = %w[
    app
    config
    git
    lib
    spec
    test
  ]

  REPLACE_WORDS = {
    'entity' => 'symbol',
    'link' => 'mapping',
  }

  class RenameRefactorProvider
    include ActiveSupport::Inflector

    attr_accessor :verbose, :dry_run

    def initialize(verbose: false, dry_run: true)
      self.verbose = verbose
      self.dry_run = dry_run
    end

    def run
      REPLACE_WORDS.each { |old_word, new_word| replace old_word, new_word }
    end

    def replace(old_word, new_word)
      affected_files.each do |file|
        replace_in_file(file, old_word, new_word)
        rename_file(file, old_word, new_word)
      end
    end

    def replace_in_file(file, old_word, new_word)
      commands = [
        "gsub(\"#{old_word}\",\"#{new_word}\")",
        "gsub(\"#{pluralize(old_word)}\",\"#{pluralize(new_word)}\")",
        "gsub(\"#{camelize(old_word)}\",\"#{camelize(new_word)}\")",
        "gsub(\"#{camelize(pluralize(old_word))}\","\
          "\"#{camelize(pluralize(new_word))}\")",
      ]
      tmp_file = "> /tmp/awk_tmp_file && mv /tmp/awk_tmp_file #{file}"
      command = "#{awk} '{#{commands.join(';')};print}' #{file} #{tmp_file}"
      puts command if verbose
      system(command) unless dry_run
    end

    def rename_file(old_filename, old_word, new_word)
      new_filename = old_filename.gsub(
        /(?<=_|\b)(#{old_word}|#{pluralize(old_word)})/) do |match|
        match == old_word ? new_word : pluralize(new_word)
      end
      if new_filename != old_filename
        puts "#{old_filename} --> #{new_filename}" if verbose
        if !dry_run
          FileUtils.mkdir_p(File.dirname(new_filename))
          FileUtils.mv(old_filename, new_filename)
        end
      end
    end

    def affected_files
      filetype = AFFECTED_FILETYPES.first
      loc = DIRECTORIES.join(' ')
      out = `find #{loc} -iname "*.#{filetype}" #{other_filetype_options}`
      out.lines.map { |l| l.delete("\n") }
    end

    def other_filetype_options
      AFFECTED_FILETYPES[1..-1].reduce('') do |options, filetype|
        options << "-o -iname \"*.#{filetype}\" "
      end
    end

    def awk
      'awk'
    end
  end

  class MigrationProvider
    include ActiveSupport::Inflector

    STRUCTURE_SQL_PATH = Pathname.new('db/structure.sql')
    MIGRATION_DIRPATH  = Pathname.new('db/migrate')

    attr_accessor :verbose, :dry_run, :migration_commands

    def initialize(verbose: false, dry_run: true)
      self.verbose = verbose
      self.dry_run = dry_run
      self.migration_commands = []
    end

    def run
      clean_slate unless dry_run
      sql_statements = read_structure_sql

      sql_statements.each do |sql_statement|
        rename_columns(sql_statement)
        rename_table(sql_statement)
        rebuild_index(sql_statement)
        rename_in_function(sql_statement)
        rename_primary_keys(sql_statement)
        rebuild_foreign_keys(sql_statement)
      end

      puts migration_commands.map(&:inspect).join("\n") if dry_run && verbose
      write_migration unless dry_run
    end

    def clean_slate
      puts 'Running rake db:migrate:clean' if verbose
      system('bundle exec rake db:migrate:clean')
    end

    def read_structure_sql
      STRUCTURE_SQL_PATH.readlines("\n\n\n").map do |command|
        command.lines.select do |line|
          !line.start_with?('--') && line != "\n"
        end.join("\n")
      end
{'fraction_non_alphanumeric': 0.12527233115468409, 'fraction_numerical': 0.0005446623093681918, 'mean_word_length': 2.6487829110779932, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, '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': '4979297', 'n_tokens_mistral': 2574, 'n_tokens_neox': 2534, 'n_words': 484}