Files
sousa-gecko/third_party/python/fluent.migrate/fluent/migrate/repo_client.py
T
Alex Hochheiden c49fedbda1 Bug 1972681 - Use compatible release operator for vendored Python packages where possible and run ./mach vendor python --upgrade r=ahal,mach-reviewers
Updated aiohttp v3.12.12 -> v3.12.13
Updated attrs v23.1.0 -> v23.2.0
Updated blessed v1.19.1 -> v1.21.0
Updated cbor2 v4.0.1 -> v4.1.2
Updated compare-locales v9.0.1 -> v9.0.4
Updated distro v1.8.0 -> v1.9.0
Updated fluent-migrate v0.13.2 -> v0.13.3
Updated importlib-metadata v6.0.0 -> v6.11.0
Updated jsmin v3.0.0 -> v3.0.1
Updated json-e v4.5.3 -> v4.8.0
Updated looseversion v1.0.1 -> v1.3.0
Updated mozilla-taskgraph v3.3.1 -> v3.3.2
Updated multidict v6.4.4 -> v6.5.0
Updated pathspec v0.9.0 -> v0.12.1
Updated pyasn1 v0.4.8 -> v0.6.1
Updated pyasn1-modules v0.2.8 -> v0.4.2
Updated pylru v1.0.9 -> v1.2.1
Updated python-hglib v2.4 -> v2.6.2
Updated redo v2.0.3 -> v2.0.4
Updated requests-unixsocket v0.2.0 -> v0.4.1
Updated responses v0.10.6 -> v0.25.7
Updated rsa v4.9 -> v4.9.1
Updated sentry-sdk v1.14.0 -> v1.45.1
Updated six v1.16.0 -> v1.17.0
Updated tomlkit v0.12.3 -> v0.13.3
Updated tqdm v4.66.3 -> v4.67.1
Updated typing-extensions v4.12.2 -> v4.14.0
Updated voluptuous v0.12.1 -> v0.15.2
Updated yamllint v1.23.0 -> v1.37.1

Differential Revision: https://phabricator.services.mozilla.com/D254096
2025-06-19 22:31:02 +00:00

110 lines
3.6 KiB
Python

from __future__ import annotations
from typing import Tuple
import json
from subprocess import run
from os.path import isdir, join
import hglib
def git(root: str, *args: str) -> str:
"""
Wrapper for calling command-line git in the `root` directory.
Raises an exception on any error, including a non-0 return code.
Returns the command's stdout as a string.
"""
git = ["git"]
git.extend(args)
proc = run(git, capture_output=True, cwd=root, encoding="utf-8")
if proc.returncode != 0:
raise Exception(proc.stderr or f"git command failed: {args}")
return proc.stdout
class RepoClient:
def __init__(self, root: str):
self.root = root
if isdir(join(root, ".hg")):
self.hgclient = hglib.open(root, "utf-8")
else:
self.hgclient = None
try:
stdout = git(self.root, "rev-parse", "--is-inside-work-tree")
except Exception:
stdout = ""
if stdout != "true\n":
raise Exception(f"Unsupported repository: {root}")
def close(self):
if self.hgclient:
self.hgclient.close()
def blame(self, file: str) -> list[Tuple[str, int]]:
"Return a list of (author, time) tuples for each line in `file`."
if self.hgclient:
args = hglib.util.cmdbuilder(
b"annotate",
file.encode("latin-1"),
template="json",
date=True,
user=True,
cwd=self.root,
)
blame_json = self.hgclient.rawcommand(args)
return [
(line["user"], int(line["date"][0]))
for line in json.loads(blame_json)[0]["lines"]
]
else:
lines: list[Tuple[str, int]] = []
user = ""
time = 0
stdout = git(self.root, "blame", "--porcelain", file)
for line in stdout.splitlines():
if line.startswith("author "):
user = line[7:] or "[noname]"
elif line.startswith("author-mail "):
email = line[11:] # includes leading space
user += email if email != ' <>' else ' <nomail>'
elif line.startswith("author-time "):
time = int(line[12:])
elif line.startswith("\t"):
lines.append((user, time))
return lines
def commit(self, message: str, author: str):
"Add and commit all work tree files"
if self.hgclient:
self.hgclient.commit(message, user=author.encode("utf-8"), addremove=True)
else:
git(self.root, "add", ".")
git(self.root, "commit", f"--author={author}", f"--message={message}")
def head(self) -> str:
"Identifier for the most recent commit"
if self.hgclient:
return self.hgclient.tip().node.decode("utf-8")
else:
return git(self.root, "rev-parse", "HEAD").strip()
def log(self, from_commit: str, to_commit: str) -> list[str]:
if self.hgclient:
return [
rev.desc.decode("utf-8")
for rev in self.hgclient.log(f"{to_commit} % {from_commit}")
]
else:
return (
git(
self.root,
"log",
"--reverse",
"--pretty=format:%s",
f"{from_commit}..{to_commit}",
)
.strip()
.splitlines()
)