module ReactOnRails::GitUtils
def self.dirty_worktree_error_message
def self.dirty_worktree_error_message <<~MSG.strip You have uncommitted changes. Please commit or stash them before continuing. The React on Rails generator creates many new files and it's important to keep your existing changes separate from the generated code for easier review. MSG end
def self.missing_git_error_message
def self.missing_git_error_message <<~MSG.strip Git is not installed. Please install Git and commit your changes before continuing. The React on Rails generator creates many new files and version control helps track what was generated versus your existing code. MSG end
def self.not_a_git_repository_error_message
def self.not_a_git_repository_error_message <<~MSG.strip Git is installed, but this directory is not a Git repository yet. Initialize Git and commit or stash your changes before continuing. The React on Rails generator creates many new files and version control helps track what was generated versus your existing code. MSG end
def self.report_worktree_issues(message_handler, git_installed:, as_error:)
def self.report_worktree_issues(message_handler, git_installed:, as_error:) return false if skip_worktree_check? status = git_installed ? worktree_status : :git_not_installed return false if status == :clean msg = worktree_message(status, as_error: as_error) as_error ? message_handler.add_error(msg) : message_handler.add_warning(msg) true end
def self.skip_worktree_check?
def self.skip_worktree_check? truthy_env?(ENV.fetch("CI", nil)) || truthy_env?(ENV.fetch("COVERAGE", nil)) end
def self.truthy_env?(value)
def self.truthy_env?(value) CI_TRUTHY_VALUES.include?(value.to_s.strip.downcase) end
def self.uncommitted_changes?(message_handler, git_installed: true)
def self.uncommitted_changes?(message_handler, git_installed: true) report_worktree_issues(message_handler, git_installed: git_installed, as_error: true) end
def self.warn_if_uncommitted_changes(message_handler, git_installed: true)
def self.warn_if_uncommitted_changes(message_handler, git_installed: true) report_worktree_issues(message_handler, git_installed: git_installed, as_error: false) end
def self.worktree_message(status, as_error:)
def self.worktree_message(status, as_error:) case status when :not_a_git_repository as_error ? not_a_git_repository_error_message : NOT_A_GIT_REPOSITORY_WARNING when :git_not_installed as_error ? missing_git_error_message : MISSING_GIT_WARNING else as_error ? dirty_worktree_error_message : DIRTY_WORKTREE_WARNING end end
def self.worktree_status
def self.worktree_status output, status = Open3.capture2e("git", "status", "--porcelain") return :clean if status.success? && output.strip.empty? # Exit code 128 is git's standard fatal error (e.g., not a git repository) return :not_a_git_repository if status.exitstatus == 128 :dirty rescue Errno::ENOENT # git binary not found despite passing the cli_exists? check :git_not_installed end