mirror of
https://github.com/hwchase17/langchain.git
synced 2025-09-01 19:12:42 +00:00
community: add method to create branch and list files for gitlab tool (#27883)
### About - **Description:** In the Gitlab utilities used for the Gitlab tool there are no methods to create branches, list branches and files, as this is already done for Github - **Issue:** None - **Dependencies:** None This Pull request add the methods: - create_branch - list_branches_in_repo - set_active_branch - list_files_in_main_branch - list_files_in_bot_branch - list_files_from_directory --------- Co-authored-by: Erick Friis <erick@langchain.dev>
This commit is contained in:
@@ -325,6 +325,161 @@ class GitLabAPIWrapper(BaseModel):
|
||||
except Exception as e:
|
||||
return "Unable to delete file due to error:\n" + str(e)
|
||||
|
||||
def list_files_in_main_branch(self) -> str:
|
||||
"""
|
||||
Get the list of files in the main branch of the repository
|
||||
|
||||
Returns:
|
||||
str: A plaintext report containing the list of files
|
||||
in the repository in the main branch
|
||||
"""
|
||||
if self.gitlab_base_branch is None:
|
||||
return "No base branch set. Please set a base branch."
|
||||
return self._list_files(self.gitlab_base_branch)
|
||||
|
||||
def list_files_in_bot_branch(self) -> str:
|
||||
"""
|
||||
Get the list of files in the active branch of the repository
|
||||
|
||||
Returns:
|
||||
str: A plaintext report containing the list of files
|
||||
in the repository in the active branch
|
||||
"""
|
||||
if self.gitlab_branch is None:
|
||||
return "No active branch set. Please set a branch."
|
||||
return self._list_files(self.gitlab_branch)
|
||||
|
||||
def list_files_from_directory(self, path: str) -> str:
|
||||
"""
|
||||
Get the list of files in the active branch of the repository
|
||||
from a specific directory
|
||||
|
||||
Returns:
|
||||
str: A plaintext report containing the list of files
|
||||
in the repository in the active branch from the specified directory
|
||||
"""
|
||||
if self.gitlab_branch is None:
|
||||
return "No active branch set. Please set a branch."
|
||||
return self._list_files(
|
||||
branch=self.gitlab_branch,
|
||||
path=path,
|
||||
)
|
||||
|
||||
def _list_files(self, branch: str, path: str = "") -> str:
|
||||
try:
|
||||
files = self._get_repository_files(
|
||||
branch=branch,
|
||||
path=path,
|
||||
)
|
||||
if files:
|
||||
files_str = "\n".join(files)
|
||||
return f"Found {len(files)} files in branch `{branch}`:\n{files_str}"
|
||||
else:
|
||||
return f"No files found in branch: `{branch}`"
|
||||
except Exception as e:
|
||||
return f"Error: {e}"
|
||||
|
||||
def _get_repository_files(self, branch: str, path: str = "") -> List[str]:
|
||||
repo_contents = self.gitlab_repo_instance.repository_tree(ref=branch, path=path)
|
||||
|
||||
files: List[str] = []
|
||||
for content in repo_contents:
|
||||
if content["type"] == "tree":
|
||||
files.extend(self._get_repository_files(branch, content["path"]))
|
||||
else:
|
||||
files.append(content["path"])
|
||||
|
||||
return files
|
||||
|
||||
def create_branch(self, proposed_branch_name: str) -> str:
|
||||
"""
|
||||
Create a new branch in the repository and set it as the active branch
|
||||
|
||||
Parameters:
|
||||
proposed_branch_name (str): The name of the new branch to be created
|
||||
Returns:
|
||||
str: A success or failure message
|
||||
"""
|
||||
from gitlab import GitlabCreateError
|
||||
|
||||
max_attempts = 100
|
||||
new_branch_name = proposed_branch_name
|
||||
for i in range(max_attempts):
|
||||
try:
|
||||
response = self.gitlab_repo_instance.branches.create(
|
||||
{
|
||||
"branch": new_branch_name,
|
||||
"ref": self.gitlab_branch,
|
||||
}
|
||||
)
|
||||
|
||||
self.gitlab_branch = response.name
|
||||
return (
|
||||
f"Branch '{response.name}' "
|
||||
"created successfully, and set as current active branch."
|
||||
)
|
||||
|
||||
except GitlabCreateError as e:
|
||||
if (
|
||||
e.response_code == 400
|
||||
and "Branch already exists" in e.error_message
|
||||
):
|
||||
i += 1
|
||||
new_branch_name = f"{proposed_branch_name}_v{i}"
|
||||
else:
|
||||
# Handle any other exceptions
|
||||
print(f"Failed to create branch. Error: {e}") # noqa: T201
|
||||
raise Exception(
|
||||
"Unable to create branch name from proposed_branch_name: "
|
||||
f"{proposed_branch_name}"
|
||||
)
|
||||
|
||||
return (
|
||||
f"Unable to create branch. At least {max_attempts} branches exist "
|
||||
f"with named derived from "
|
||||
f"proposed_branch_name: `{proposed_branch_name}`"
|
||||
)
|
||||
|
||||
def list_branches_in_repo(self) -> str:
|
||||
"""
|
||||
Get the list of branches in the repository
|
||||
|
||||
Returns:
|
||||
str: A plaintext report containing the number of branches
|
||||
and each branch name
|
||||
"""
|
||||
branches = [
|
||||
branch.name for branch in self.gitlab_repo_instance.branches.list(all=True)
|
||||
]
|
||||
if branches:
|
||||
branches_str = "\n".join(branches)
|
||||
return (
|
||||
f"Found {str(len(branches))} branches in the repository:"
|
||||
f"\n{branches_str}"
|
||||
)
|
||||
return "No branches found in the repository"
|
||||
|
||||
def set_active_branch(self, branch_name: str) -> str:
|
||||
"""Equivalent to `git checkout branch_name` for this Agent.
|
||||
Clones formatting from Gitlab.
|
||||
|
||||
Returns an Error (as a string) if branch doesn't exist.
|
||||
"""
|
||||
curr_branches = [
|
||||
branch.name
|
||||
for branch in self.gitlab_repo_instance.branches.list(
|
||||
all=True,
|
||||
)
|
||||
]
|
||||
if branch_name in curr_branches:
|
||||
self.gitlab_branch = branch_name
|
||||
return f"Switched to branch `{branch_name}`"
|
||||
else:
|
||||
return (
|
||||
f"Error {branch_name} does not exist,"
|
||||
f"in repo with current branches: {str(curr_branches)}"
|
||||
)
|
||||
|
||||
def run(self, mode: str, query: str) -> str:
|
||||
if mode == "get_issues":
|
||||
return self.get_issues()
|
||||
@@ -342,5 +497,17 @@ class GitLabAPIWrapper(BaseModel):
|
||||
return self.update_file(query)
|
||||
elif mode == "delete_file":
|
||||
return self.delete_file(query)
|
||||
elif mode == "create_branch":
|
||||
return self.create_branch(query)
|
||||
elif mode == "list_branches_in_repo":
|
||||
return self.list_branches_in_repo()
|
||||
elif mode == "set_active_branch":
|
||||
return self.set_active_branch(query)
|
||||
elif mode == "list_files_in_main_branch":
|
||||
return self.list_files_in_main_branch()
|
||||
elif mode == "list_files_in_bot_branch":
|
||||
return self.list_files_in_bot_branch()
|
||||
elif mode == "list_files_from_directory":
|
||||
return self.list_files_from_directory(query)
|
||||
else:
|
||||
raise ValueError("Invalid mode" + mode)
|
||||
|
Reference in New Issue
Block a user