diff --git a/main.py b/main.py index 065708e..f40da29 100644 --- a/main.py +++ b/main.py @@ -430,14 +430,19 @@ async def broadcast(repo_hash: str, data: dict): for connection in connections[repo_hash]: await connection.send_json(data) -def run_git_command(repo_path: str, command: list[str]) -> str: - result = subprocess.run(["git", "-C", repo_path] + command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) - if result.returncode != 0: - raise Exception(result.stderr.strip()) - return result.stdout.strip()[:1024 * 1024] +async def run_git_command(repo_path: str, command: list[str]) -> str: + proc = await asyncio.create_subprocess_exec( + 'git', '-C', repo_path, *command, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE + ) + stdout, stderr = await proc.communicate() + if proc.returncode != 0: + raise Exception(stderr.decode().strip()) + return stdout.decode().strip()[:1024 * 1024] -def get_commits_by_day(repo_path: pathlib.Path) -> Dict[str, List[str]]: - log_output = run_git_command(str(repo_path), ["log", "--pretty=format:%H|%ad", "--date=short"]) +async def get_commits_by_day(repo_path: pathlib.Path) -> Dict[str, List[str]]: + log_output = await run_git_command(str(repo_path), ["log", "--pretty=format:%H|%ad", "--date=short"]) commits_by_date = collections.defaultdict(list) for line in log_output.splitlines(): if "|" in line: @@ -454,8 +459,16 @@ async def process_repo(url: str, repo_hash: str, is_user_request: bool = False): await broadcast(repo_hash, {"type": "message", "content": "Cloning repository..."}) for _ in range(3): try: - subprocess.run(["git", "clone", url, str(repo_path)], check=True) - break + proc = await asyncio.create_subprocess_exec( + 'git', 'clone', url, str(repo_path), + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE + ) + stdout, stderr = await proc.communicate() + if proc.returncode == 0: + break + else: + raise subprocess.CalledProcessError(proc.returncode, ['git', 'clone'], stderr.decode()) except subprocess.CalledProcessError: await asyncio.sleep(1) else: @@ -464,13 +477,21 @@ async def process_repo(url: str, repo_hash: str, is_user_request: bool = False): await broadcast(repo_hash, {"type": "message", "content": "Updating repository..."}) for _ in range(3): try: - subprocess.run(["git", "-C", str(repo_path), "pull"], check=True) - break + proc = await asyncio.create_subprocess_exec( + 'git', '-C', str(repo_path), 'pull', + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE + ) + stdout, stderr = await proc.communicate() + if proc.returncode == 0: + break + else: + raise subprocess.CalledProcessError(proc.returncode, ['git', 'pull'], stderr.decode()) except subprocess.CalledProcessError: await asyncio.sleep(1) else: raise Exception("Pull failed after 3 tries") - commits_by_day = get_commits_by_day(repo_path) + commits_by_day = await get_commits_by_day(repo_path) history = {c["uid"]: c for c in await db.find("commits", {"repo": repo_hash})} new_commits = 0 for date in sorted(commits_by_day): @@ -479,7 +500,7 @@ async def process_repo(url: str, repo_hash: str, is_user_request: bool = False): if commit in history and history[commit]["status"] == "success": continue new_commits += 1 - diff = run_git_command(str(repo_path), ["show", commit, "--no-color", "--format=medium"]) + diff = await run_git_command(str(repo_path), ["show", commit, "--no-color", "--format=medium"]) prompt = ( "Generate a describtion about what is done (or fixed) functionally for end users.\n" "Allowed prefixes: feat, fix, security, change.\n"