feat: +git tools

This commit is contained in:
莘权 马 2024-03-21 20:37:23 +08:00
parent 5ee95b1461
commit 85adc47366
5 changed files with 133 additions and 1 deletions

View file

@ -9,6 +9,8 @@
from __future__ import annotations
import shutil
import subprocess
import uuid
from enum import Enum
from pathlib import Path
from typing import Dict, List
@ -283,3 +285,36 @@ class GitRepository:
continue
files.append(filename)
return files
@classmethod
async def clone_from(cls, url: str | Path, output_dir: str | Path = None) -> "GitRepository":
from metagpt.context import Context
to_path = Path(output_dir or Path(__file__).parent / f"../../workspace/downloads/{uuid.uuid4().hex}").resolve()
to_path.mkdir(parents=True, exist_ok=True)
ctx = Context()
env = ctx.new_environ()
proxy = ["-c", f"http.proxy={ctx.config.proxy}"] if ctx.config.proxy else []
command = ["git", "clone"] + proxy + [str(url)]
logger.info(" ".join(command))
process = subprocess.Popen(command, cwd=str(to_path), stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
try:
# Wait for the process to complete, with a timeout
stdout, stderr = process.communicate(timeout=600)
info = f"{stdout.decode('utf-8')}\n{stderr.decode('utf-8')}"
logger.info(info)
dir_name = Path(url).with_suffix("").name
to_path = to_path / dir_name
if not cls.is_git_dir(to_path):
raise ValueError(info)
logger.info(f"git clone to {to_path}")
return GitRepository(local_path=to_path, auto_init=False)
except subprocess.TimeoutExpired:
logger.info("The command did not complete within the given timeout.")
process.kill() # Kill the process if it times out
stdout, stderr = process.communicate()
raise ValueError(f"{stdout.decode('utf-8')}\n{stderr.decode('utf-8')}")
async def checkout(self, commit_id: str):
self._repository.git.checkout(commit_id)
logger.info(f"git checkout {commit_id}")