1010from pathlib import Path
1111from typing import TYPE_CHECKING , Any , Optional , Union , cast
1212
13- import git
1413import tomlkit
15- from git import InvalidGitRepositoryError , Repo
1614from inquirer_textual .common .Choice import Choice
1715from inquirer_textual .widgets .InquirerConfirm import InquirerConfirm
1816from inquirer_textual .widgets .InquirerSelect import InquirerSelect
1917from pydantic .dataclasses import dataclass
2018
21- from codeflash .api .cfapi import get_user_id , is_github_app_installed_on_repo
19+ from codeflash .api .cfapi import get_user_id
2220from codeflash .cli_cmds import themed_prompts as prompts
23- from codeflash .cli_cmds .cli_common import apologize_and_exit
21+ from codeflash .cli_cmds .cli_common import apologize_and_exit , get_git_repo_or_none
2422from codeflash .cli_cmds .console import console , logger
2523from codeflash .cli_cmds .extension import install_vscode_extension
2624from codeflash .cli_cmds .validators import (
3432from codeflash .code_utils .compat import LF
3533from codeflash .code_utils .config_parser import parse_config_file
3634from codeflash .code_utils .env_utils import check_formatter_installed , get_codeflash_api_key
37- from codeflash .code_utils .git_utils import get_git_remotes , get_repo_owner_and_name
38- from codeflash .code_utils .github_utils import get_github_secrets_page_url
35+ from codeflash .code_utils .git_utils import get_git_remotes
36+ from codeflash .code_utils .github_utils import get_github_secrets_page_url , install_github_app
3937from codeflash .code_utils .oauth_handler import perform_oauth_signin
4038from codeflash .code_utils .shell_utils import get_shell_rc_path , is_powershell , save_api_key_to_rc
4139from codeflash .either import is_successful
@@ -236,11 +234,8 @@ def init_codeflash() -> None:
236234
237235 project_name = check_for_toml_or_setup_file ()
238236
239- try :
240- repo = Repo (curdir , search_parent_directories = True )
241- git_remotes = get_git_remotes (repo )
242- except InvalidGitRepositoryError :
243- git_remotes = []
237+ repo = get_git_repo_or_none (curdir )
238+ git_remotes = get_git_remotes (repo ) if repo is not None else []
244239
245240 answers = collect_config (curdir , auth_status , project_name , git_remotes )
246241 git_remote = answers .git_remote
@@ -257,11 +252,8 @@ def init_codeflash() -> None:
257252 if not configure_pyproject_toml (setup_info ):
258253 apologize_and_exit ()
259254
260- try :
261- git .Repo (search_parent_directories = True )
262- in_git_repo = True
263- except git .InvalidGitRepositoryError :
264- in_git_repo = False
255+ maybe_git_repo = get_git_repo_or_none ()
256+ in_git_repo = maybe_git_repo is not None
265257
266258 integration_options = [Choice ("📦 VSCode Extension" , data = "vscode" )]
267259 if in_git_repo :
@@ -283,7 +275,8 @@ def init_codeflash() -> None:
283275 )
284276 for choice in selected :
285277 if choice .data == "github_app" :
286- install_github_app (git_remote )
278+ if maybe_git_repo is not None :
279+ install_github_app (maybe_git_repo , git_remote )
287280 elif choice .data == "github_actions" :
288281 install_github_actions (override_formatter_check = True )
289282 elif choice .data == "vscode" :
@@ -541,9 +534,8 @@ def install_github_actions(override_formatter_check: bool = False) -> None: # n
541534 config , _config_file_path = parse_config_file (override_formatter_check = override_formatter_check )
542535 ph ("cli-github-actions-install-started" )
543536
544- try :
545- repo = Repo (config ["module_root" ], search_parent_directories = True )
546- except git .InvalidGitRepositoryError :
537+ repo = get_git_repo_or_none (Path (config ["module_root" ]))
538+ if repo is None :
547539 console .print (
548540 "Skipping GitHub action installation for continuous optimization because you're not in a git repository."
549541 )
@@ -846,74 +838,8 @@ def configure_pyproject_toml(
846838 return True
847839
848840
849- def prompt_github_app_install (owner : str , repo : str ) -> None :
850- """Prompt user to install GitHub app and wait for confirmation."""
851- app_url = "https://github.com/apps/codeflash-ai/installations/select_target"
852-
853- open_page = prompts .select_or_exit (
854- f"Open GitHub App installation page? ({ app_url } )" ,
855- choices = ["Yes" , "No" ],
856- default = "Yes" ,
857- header = (
858- f"🐙 GitHub App Installation\n \n "
859- f"You'll need to install the Codeflash GitHub app for { owner } /{ repo } .\n \n "
860- "I'll open the installation page where you can select your repository."
861- ),
862- )
863- if open_page == "Yes" :
864- webbrowser .open (app_url )
865-
866- prompts .confirm ("Continue once you've completed the installation?" , default = True )
867-
868-
869- def install_github_app (git_remote : str ) -> None :
870- try :
871- git_repo = git .Repo (search_parent_directories = True )
872- except git .InvalidGitRepositoryError :
873- console .print ("Skipping GitHub app installation because you're not in a git repository." )
874- return
875-
876- if git_remote not in get_git_remotes (git_repo ):
877- console .print (f"Skipping GitHub app installation, remote ({ git_remote } ) does not exist in this repository." )
878- return
879-
880- owner , repo = get_repo_owner_and_name (git_repo , git_remote )
881-
882- if is_github_app_installed_on_repo (owner , repo , suppress_errors = True ):
883- console .print (
884- f"🐙 Looks like you've already installed the Codeflash GitHub app on this repository ({ owner } /{ repo } )! Continuing…"
885- )
886- return
887-
888- # Not installed - prompt for installation
889- try :
890- prompt_github_app_install (owner , repo )
891-
892- # Verify installation with retries
893- max_retries = 2
894- for attempt in range (max_retries + 1 ):
895- if is_github_app_installed_on_repo (owner , repo , suppress_errors = True ):
896- console .print (f"✅ GitHub App installed successfully for { owner } /{ repo } !" )
897- break
898-
899- if attempt == max_retries :
900- console .print (
901- f"❌ GitHub App not detected on { owner } /{ repo } .\n "
902- f"You won't be able to create PRs until you install it.\n "
903- f"Use the '--no-pr' flag for local-only optimizations."
904- )
905- break
906-
907- console .print (
908- f"❌ GitHub App not detected on { owner } /{ repo } .\n Press Enter to check again after installation..."
909- )
910- console .input ()
911- except (KeyboardInterrupt , EOFError ):
912- console .print () # Clean line for next prompt
913-
914-
915841def save_api_key_and_set_env (api_key : str ) -> None :
916- """Save API key to shell RC file and set environment variable ."""
842+ """Save API key to shell RC and set env var ."""
917843 shell_rc_path = get_shell_rc_path ()
918844 if not shell_rc_path .exists () and os .name == "nt" :
919845 shell_rc_path .parent .mkdir (parents = True , exist_ok = True )
@@ -931,7 +857,7 @@ def save_api_key_and_set_env(api_key: str) -> None:
931857
932858
933859def enter_api_key_and_save_to_rc () -> None :
934- """Prompt for API key with validation and save to shell RC file ."""
860+ """Prompt for API key and save to shell RC."""
935861 browser_launched = False
936862 api_key = ""
937863
0 commit comments