diff options
Diffstat (limited to 'third_party/python/fluent.migrate/fluent/migrate/blame.py')
-rw-r--r-- | third_party/python/fluent.migrate/fluent/migrate/blame.py | 80 |
1 files changed, 80 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..2ae23d0ebe --- /dev/null +++ b/third_party/python/fluent.migrate/fluent/migrate/blame.py @@ -0,0 +1,80 @@ +import argparse +import json +import os + +from compare_locales.parser import getParser, Junk +from compare_locales.parser.fluent import FluentEntity +from compare_locales import mozpath +import hglib +from hglib.util import b, cmdbuilder + + +class Blame: + def __init__(self, client): + self.client = client + self.users = [] + self.blame = {} + + def attribution(self, file_paths): + args = cmdbuilder( + b('annotate'), *[b(p) for p in file_paths], template='json', + date=True, user=True, cwd=self.client.root()) + blame_json = self.client.rawcommand(args) + file_blames = json.loads(blame_json) + + for file_blame in file_blames: + self.handleFile(file_blame) + + return {'authors': self.users, + 'blame': self.blame} + + def handleFile(self, file_blame): + path = mozpath.normsep(file_blame['path']) + + 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 = [(e.key, e.val_span)] + else: + key_vals = [] + if isinstance(e, FluentEntity): + key_vals += [ + (f'{e.key}.{attr.key}', attr.val_span) + for attr in e.attributes + ] + for key, (val_start, val_end) in key_vals: + entity_lines = file_blame['lines'][ + (e.ctx.linecol(val_start)[0] - 1):e.ctx.linecol(val_end)[0] + ] + # ignore timezone + entity_lines.sort(key=lambda blame: -blame['date'][0]) + line_blame = entity_lines[0] + user = line_blame['user'] + timestamp = line_blame['date'][0] # ignore timezone + 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): + parser.readFile(os.path.join(self.client.root().decode('utf-8'), path)) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('repo_path') + parser.add_argument('file_path', nargs='+') + args = parser.parse_args() + blame = Blame(hglib.open(args.repo_path)) + attrib = blame.attribution(args.file_path) + print(json.dumps(attrib, indent=4, separators=(',', ': '))) |