Rename a RubyGem

It’s often said that one of the hardest parts of software development is naming things. When I start working on a RubyGem, I often name it something that I end up not liking by the time I finish the Gem so I have to go through and rename a bunch of files, constants, and references.

I finally decided to write a script to make renaming even easier.

require 'pathname'
require 'fileutils'

class GemRename
  def initialize(base_dir = ".")
    @base_dir = Pathname.new(base_dir)
  end

  def constants(from:, to:)
    update_file_contents(from, to)
  end

  def paths_and_contents(from:, to:)
    rename_files_and_directories(from, to)
    update_file_contents(from, to)
  end

  private

  def rename_files_and_directories(old_name, new_name)
    # Rename directories
    @base_dir.glob("**/*#{old_name}*").select(&:directory?).each do |dir|
      FileUtils.mv(dir, dir.to_s.gsub(old_name, new_name))
    end

    # Rename files
    @base_dir.glob("**/*#{old_name}*").each do |file|
      FileUtils.mv(file, file.to_s.gsub(old_name, new_name)) if file.file?
    end
  end

  def update_file_contents(old_text, new_text)
    @base_dir.glob("**/*").select(&:file?).each do |file|
      text = File.read(file)
      new_contents = text.gsub(old_text, new_text)
      File.open(file, "w") { |f| f.puts new_contents }
    end
  end
end

# Usage Example
# rename = GemRename.new(".")
# rename.constants from: "OldGem", to: "NewGem"
# rename.paths_and_contents from: "old_gem", to: "new_gem"

To use interactively from a console, open irb, paste the code above, and modify the code below with your old and new gem names:

rename = GemRename.new(".")
rename.constants from: "OldGem", to: "NewGem"
rename.paths_and_contents from: "old_gem", to: "new_gem"