diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /third_party/python/fluent.migrate/fluent/migrate/blame.py | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/python/fluent.migrate/fluent/migrate/blame.py')
-rw-r--r-- | third_party/python/fluent.migrate/fluent/migrate/blame.py | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/third_party/python/fluent.migrate/fluent/migrate/blame.py b/third_party/python/fluent.migrate/fluent/migrate/blame.py new file mode 100644 index 0000000000..7ea505edaf --- /dev/null +++ b/third_party/python/fluent.migrate/fluent/migrate/blame.py @@ -0,0 +1,77 @@ +from __future__ import annotations +from typing import Dict, Iterable, Tuple, TypedDict, cast + +import argparse +import json +from os.path import join + +from compare_locales.parser import Junk, getParser +from compare_locales.parser.fluent import FluentEntity + +from .repo_client import RepoClient + +BlameData = Dict[str, Dict[str, Tuple[int, float]]] +"File path -> message key -> [userid, timestamp]" + + +class BlameResult(TypedDict): + authors: list[str] + blame: BlameData + + +class Blame: + def __init__(self, client: RepoClient): + self.client = client + self.users: list[str] = [] + self.blame: BlameData = {} + + def attribution(self, file_paths: Iterable[str]) -> BlameResult: + for file in file_paths: + blame = self.client.blame(file) + self.handleFile(file, blame) + return {"authors": self.users, "blame": self.blame} + + def handleFile(self, path: str, file_blame: list[Tuple[str, int]]): + try: + parser = getParser(path) + except UserWarning: + return + + self.blame[path] = {} + + self.readFile(parser, path) + entities = parser.parse() + for e in entities: + if isinstance(e, Junk): + continue + if e.val_span: + key_vals: list[tuple[str, str]] = [(e.key, e.val_span)] + else: + key_vals = [] + if isinstance(e, FluentEntity): + key_vals += [ + (f"{e.key}.{attr.key}", cast(str, attr.val_span)) + for attr in e.attributes + ] + for key, (val_start, val_end) in key_vals: + entity_lines = file_blame[ + (e.ctx.linecol(val_start)[0] - 1) : e.ctx.linecol(val_end)[0] + ] + user, timestamp = max(entity_lines, key=lambda x: x[1]) + if user not in self.users: + self.users.append(user) + userid = self.users.index(user) + self.blame[path][key] = (userid, timestamp) + + def readFile(self, parser, path: str): + parser.readFile(join(self.client.root, path)) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("repo_path") + parser.add_argument("file_path", nargs="+") + args = parser.parse_args() + blame = Blame(RepoClient(args.repo_path)) + attrib = blame.attribution(args.file_path) + print(json.dumps(attrib, indent=4, separators=(",", ": "))) |