forge-tools/frg/context.py

78 lines
2.1 KiB
Python
Raw Normal View History

"""
Repo/git-aware contextual data
This module takes care of anything that needs to be pulled from the
invocation environment (i.e. git context, ...) to make things work.
"""
import pydantic
2024-11-02 22:22:43 +00:00
import logging
import subprocess
2024-11-02 22:22:43 +00:00
logger = logging.getLogger(__name__)
class GitContext(pydantic.BaseModel):
"""
Contextual data based on where the invocation
to the tool is made.
"""
repo_name: str
repo_author: str
current_branch: str
host: str
def parse_remote_url(remote_url: str) -> tuple[str, str, str]:
"""Parses the remote URL attached to a repository to detect the host, repo owner and name."""
if "@" in remote_url:
_, url = remote_url.removesuffix(".git").split("@")
host, full_repo_name = url.split(":")
owner, repo = full_repo_name.split("/")
return ("https://" + host, owner, repo)
if remote_url.startswith("http"):
url = (
remote_url.removeprefix("http://")
.removeprefix("https://")
.removesuffix(".git")
)
url_parts = url.split("/")
repo = url_parts[-1]
owner = url_parts[-2]
host = "https://" + "/".join(url_parts[:-2])
return (host, owner, repo)
return ("", "", "")
def get_git_context(*, domain_aliases: dict[str, str] | None = None) -> GitContext:
2024-11-02 22:22:43 +00:00
"""Gathers contextual data from the environment."""
if not domain_aliases:
domain_aliases = dict()
current_branch_cmd = subprocess.run(
["git", "branch", "--show-current"], capture_output=True
)
current_branch = current_branch_cmd.stdout.decode("utf8").strip()
remote_url_cmd = subprocess.run(
["git", "config", "--get", "remote.origin.url"], capture_output=True
)
remote_url = remote_url_cmd.stdout.decode("utf8").strip()
host, owner, repo = parse_remote_url(remote_url)
if host in domain_aliases:
2024-11-02 22:22:43 +00:00
logger.info(f"Remapped domain: {host} -> {domain_aliases[host]}")
host = domain_aliases[host]
return GitContext(
repo_name=repo, repo_author=owner, host=host, current_branch=current_branch
)