diff --git a/scripts/interpreter/gen_commit.py b/scripts/interpreter/gen_commit.py index cbba628..9300a7e 100755 --- a/scripts/interpreter/gen_commit.py +++ b/scripts/interpreter/gen_commit.py @@ -8,64 +8,57 @@ load_dotenv() def get_git_credentials(): - """Retrieve Git credentials and project path from command-line arguments.""" if len(sys.argv) != 4: print("Usage: python gen_commit.py ") sys.exit(1) return sys.argv[1], sys.argv[2], sys.argv[3] +def get_git_diff(project_path): + """Run git diff and return the output.""" + result = os.popen(f'cd "{project_path}" && git diff').read() + return result.strip() + + def gen_commit(project_path): - """Generate commit message using OpenInterpreter based on git diff.""" + """Generate commit message using OpenInterpreter based on git diff output.""" agent = OpenInterpreter() agent.llm.model = "gpt-4o" agent.auto_run = True - # Read convention and git commit guidance convention_path = os.path.join(os.path.dirname(__file__), "resources/commit_convention.md") - git_commit_path = os.path.join(os.path.dirname(__file__), "resources/git_commit.md") - with open(convention_path, "r") as f: convention_content = f.read() - with open(git_commit_path, "r") as f: - git_commit_content = f.read() agent.system_message = f""" -You are a helpful assistant that generates commit messages based on uncommitted code. +You are a helpful assistant that generates concise, conventional commit messages based on code diffs. -Follow these rules: -1. Use English. -2. Be concise and follow this format: +Guidelines: +- Use English. +- Do not include explanations—only output a single-line commit message. +- Follow this convention: {convention_content} - -3. Use these git commands to analyze changes as you see fit: -{git_commit_content} - -4. Only return the commit message. Do not add explanation or extra output. """ + diff_output = get_git_diff(project_path) + if not diff_output: + return "chore: no changes to commit" + prompt = f""" -Generate a commit message based on the following changes in the project directory: +Analyze the following git diff and generate a commit message: -cd {project_path} - -Check uncommitted changes and generate a commit message. """ response = agent.chat(prompt) - - if isinstance(response, list) and len(response) > 0: - if isinstance(response[-1], dict) and "content" in response[-1]: - return response[-1]["content"].strip() + if isinstance(response, list) and response and isinstance(response[-1], dict) and "content" in response[-1]: + return response[-1]["content"].strip() return str(response).strip() async def get_submodule_info(): - """Retrieve mapping of submodule paths to their names.""" proc = await asyncio.create_subprocess_exec( "git", "config", "--file", ".gitmodules", "--get-regexp", r"^submodule\..*\.path$", - stdout=asyncio.subprocess.PIPE, - stderr=asyncio.subprocess.PIPE, + stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, ) stdout, stderr = await proc.communicate() @@ -85,17 +78,14 @@ async def get_submodule_info(): async def commit_and_push_submodules(): - """Generate commits and push changes for each modified submodule.""" print("Checking for submodule changes...") submodule_info = await get_submodule_info() proc = await asyncio.create_subprocess_shell( "git submodule foreach --quiet 'if [ -n \"$(git status --porcelain)\" ]; then echo $path; fi'", - stdout=asyncio.subprocess.PIPE, - stderr=asyncio.subprocess.PIPE, + stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, ) stdout, stderr = await proc.communicate() - if stderr: print(f"Error checking submodules:\n{stderr.decode()}") return @@ -111,15 +101,11 @@ async def commit_and_push_submodules(): name = submodule_info.get(abs_path, submodule_path) print(f"Processing submodule: {name} at {abs_path}") - # Generate commit message commit_msg = gen_commit(abs_path) - # Get remote URL proc = await asyncio.create_subprocess_exec( "git", "remote", "get-url", "origin", - cwd=abs_path, - stdout=asyncio.subprocess.PIPE, - stderr=asyncio.subprocess.PIPE, + cwd=abs_path, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, ) stdout, stderr = await proc.communicate() if stderr: @@ -129,7 +115,6 @@ async def commit_and_push_submodules(): remote_url = stdout.decode().strip().replace(".git", "").replace("https://", "") remote_url = f"https://{git_user}:{git_pass}@{remote_url}" - # Commit and push commands = [ f"cd {abs_path} && git add .", f'cd {abs_path} && git commit -m "{commit_msg}" || true', @@ -148,17 +133,13 @@ async def commit_and_push_submodules(): async def push_code(): - """Main routine: commit and push changes for main repo and submodules.""" git_user, git_pass, project_path = get_git_credentials() - os.chdir(project_path) print(f"Changed to project path: {project_path}") - # Get main repo remote URL proc = await asyncio.create_subprocess_exec( "git", "remote", "get-url", "origin", - stdout=asyncio.subprocess.PIPE, - stderr=asyncio.subprocess.PIPE, + stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, ) stdout, stderr = await proc.communicate() if stderr: @@ -166,10 +147,8 @@ async def push_code(): git_repo = stdout.decode().strip().replace(".git", "").replace("https://", "") remote_url = f"https://{git_user}:{git_pass}@{git_repo}" - # Handle submodules await commit_and_push_submodules() - # Generate and commit main repo commit_msg = gen_commit(project_path) print(f"Generated commit message:\n{commit_msg}\n")