# frozen_string_literal: true require_relative "./make_pr/base" module Neetob class CLI module Github class Search < MakePr::Base attr_accessor :repos, :key_to_search, :search_file_path, :replacement_term, :sandbox def initialize(repos, key_to_search, search_file_path, replacement_term, sandbox = false) @key_to_search = key_to_search @replacement_term = replacement_term branch_name = build_branch_name pr_title = build_pr_title super(pr_title, branch_name) @search_file_path = search_file_path @repos = repos @sandbox = sandbox end def run matching_repos = find_all_matching_apps_or_repos(repos, :github, sandbox) matching_repos.each do |repo| ui.info("\nSearching in #{repo}") clone_repo_in_tmp_dir(repo) begin if replacement_term.nil? find_and_print_matching_lines(repo) else check_and_delete_remote_branch(repo) find_and_replace_keyword(repo) ui.say("No changes were made to #{repo}, check if keyword exists.") and next if !are_changes_made?(repo) ui.info(add_commmit_and_push_changes(repo)) delete_local_feature_branch(repo) pull_request = client.create_pull_request(repo, "main", branch_name, pr_title) ui.success("Successfully replaced \"#{key_to_search}\" with \"#{replacement_term}\" in #{repo}") ui.success("PR Link:- #{pull_request.html_url}") end rescue StandardError => e ExceptionHandler.new(e).process end end `rm -rf /tmp/neetob` end private def search_for_keyword(repo) `#{cd_to_repo(repo)} && \ find . -type f -iregex "#{search_file_path}" | xargs grep -E "#{key_to_search}"` end def find_and_print_matching_lines(repo) files_with_matching_lines = find_matching_files(repo) files_with_matching_lines.empty? ? ui.error("Keyword not found") : print_matching_lines(files_with_matching_lines) end def find_matching_files(repo) result = search_for_keyword(repo) result.each_line.reduce({}) do |lines_by_file, line| filename, content = line.split(":", 2) lines_by_file[filename] ||= [] lines_by_file[filename] << content.strip lines_by_file end end def print_matching_lines(files_with_matching_lines) files_with_matching_lines.each do |file, list_of_lines| ui.info("#{file}") list_of_lines.each { |line| ui.success(" ↳#{line}") } end end def are_changes_made?(repo) changes_made = `#{cd_to_repo(repo)} && git checkout #{branch_name} && git status` !changes_made.include?("nothing to commit") end def find_and_replace_keyword(repo) `#{cd_to_repo(repo)} && \ find . -type f -regex #{search_file_path} -print0 | \ xargs -0 sed -i '' 's/#{key_to_search}/#{replacement_term}/g'` end def build_pr_title "Replaced \"#{key_to_search}\" with \"#{replacement_term}\"" end def build_branch_name branch_name = "search-#{key_to_search}-and-replace-with-#{replacement_term}" branch_name.gsub(/\W/, "_") end end end end end