require "find" require "fileutils" require "tty-file" module Geny module Actions # Utilities for manipulating files in bulk class Find # Replace the content of any file that matches the pattern with # a replacement # @param root [String] the path to search # @param pattern [String,Regexp] a pattern to find # @param replacement [String] the content to insert # @param force [TrueClass,FalseClass] overwrite existing files # @param excluding [Regexp] exclude any file matching this pattern # @note This attempts to ignore binary files # # @example # find.replace("src", "Boilerplate", "YourProject") def replace(root, pattern, replacement, force: false, excluding: nil) ::Find.find(root) do |path| # The first emitted path will be the root directory next if path == root # Don't look any further into this directory ::Find.prune if excluding && path.match?(excluding) # We don't care about directories next if File.directory?(path) # We can't replace binary files next if TTY::File.binary?(path) TTY::File.replace_in_file( path, pattern, replacement, verbose: false, force: force ) end end # Replace any filename that matches the pattern with a replacement # @param root [String] the path to search # @param pattern [String,Regexp] a pattern to find # @param replacement [String] the content to insert # @param force [TrueClass,FalseClass] overwrite existing files # @param excluding [Regexp] exclude any file matching this pattern # # @example # find.rename("src", "Boilerplate", "YourProject") def rename(root, pattern, replacement, force: false, excluding: nil) options = {force: force, excluding: excluding} ::Find.find(root) do |path| # The first emitted path will be the root directory next if path == root # Don't look any further into this directory ::Find.prune if excluding && path.match?(excluding) # The path doesn't match, keep searching next unless path.match?(pattern) # The path matches, so rename it dest = path.sub(pattern, replacement) FileUtils.mv(path, dest, force: force) # Find and rename the children of the path rename(dest, pattern, replacement, options) if File.directory?(dest) # We already searched the directory's children, so we should stop ::Find.prune end end end end end