forge-tools/frg/context.py

75 lines
2 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
import subprocess
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:
if not domain_aliases:
domain_aliases = dict()
"""Gathers contextual data from the environment."""
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:
print(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
)