Skip to content
Open
72 changes: 70 additions & 2 deletions git_utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import re
from configparser import NoOptionError, NoSectionError
from typing import Optional, Union

Expand Down Expand Up @@ -60,7 +61,10 @@ def _ensure_git_config(repo: Repo) -> None:


def init_git_repo(
path_to_repo: Union[str, os.PathLike], module_name: Optional[str] = None, render_id: Optional[str] = None
path_to_repo: Union[str, os.PathLike],
module_name: Optional[str] = None,
render_id: Optional[str] = None,
initial_files: Optional[dict[str, str]] = None,
) -> Repo:
"""
Initializes a new git repository in the given path.
Expand All @@ -74,6 +78,11 @@ def init_git_repo(

repo = Repo.init(path_to_repo)
_ensure_git_config(repo)

if initial_files:
file_utils.store_response_files(path_to_repo, initial_files, [])
repo.git.add(".")

repo.git.commit(
"--allow-empty", "-m", _get_full_commit_message(INITIAL_COMMIT_MESSAGE, module_name, None, render_id)
)
Expand All @@ -82,9 +91,18 @@ def init_git_repo(


def clone_repo(
source_repo_path: str, new_repo_path: str, module_name: Optional[str] = None, render_id: Optional[str] = None
source_repo_path: str,
new_repo_path: str,
module_name: Optional[str] = None,
render_id: Optional[str] = None,
initial_files: Optional[dict[str, str]] = None,
) -> Repo:
repo = Repo.clone_from(source_repo_path, new_repo_path)

if initial_files:
file_utils.store_response_files(new_repo_path, initial_files, [])
repo.git.add(".")

repo.git.commit(
"--allow-empty", "-m", _get_full_commit_message(INITIAL_COMMIT_MESSAGE, module_name, None, render_id)
)
Expand Down Expand Up @@ -415,3 +433,53 @@ def get_repo_info(repo_path: Union[str, os.PathLike]) -> dict:
info["remotes"] = remotes

return info


def get_last_rendered_functionality(repo_path: Union[str, os.PathLike]) -> tuple[Optional[str], Optional[str]]:
if not os.path.exists(repo_path):
return None, None

repo = Repo(repo_path)
grep_pattern = FUNCTIONAL_REQUIREMENT_FINISHED_COMMIT_MESSAGE.format(".*")
grep_pattern = grep_pattern.replace("[", "\\[").replace("]", "\\]")
commit_sha = repo.git.rev_list(repo.active_branch.name, "--grep", grep_pattern, "-n", "1")

if not commit_sha:
# Repo was interrupted during the first functionality, fallback to initial commit and provide only module name
grep_pattern = INITIAL_COMMIT_MESSAGE
grep_pattern = grep_pattern.replace("[", "\\[").replace("]", "\\]")
commit_sha = repo.git.rev_list(repo.active_branch.name, "--grep", grep_pattern, "-n", "1")
if not commit_sha:
raise InvalidGitRepositoryError("Git repository is in an invalid state. Initial commit could not be found.")

commit_message = repo.commit(commit_sha).message
if isinstance(commit_message, bytes):
commit_message = commit_message.decode("utf-8")

match = re.search(r"Module name:\s*(\S+)\n", commit_message)
if not match:
raise InvalidGitRepositoryError(
"Git repository is in an invalid state. Could not find module name in initial commit."
)

module_name = match.group(1)
return module_name, None

commit_message = repo.commit(commit_sha).message
if isinstance(commit_message, bytes):
commit_message = commit_message.decode("utf-8")

match = re.search(r"FRID\):(\S+) fully implemented", commit_message)
if not match:
raise InvalidGitRepositoryError(
"Git repository is in an invalid state. Could not find frid in finished commit."
)
frid = match.group(1)

match = re.search(r"Module name:\s*(\S+)\n", commit_message)
if not match:
raise InvalidGitRepositoryError(
"Git repository is in an invalid state. Could not find module name in finished commit."
)
module_name = match.group(1)
return module_name, frid
Loading
Loading