From: Frantisek Hrbata Date: Mon, 14 Dec 2020 17:08:25 +0000 (+0100) Subject: git-mr-comment-list: initial implementation X-Git-Tag: v0.2~50 X-Git-Url: http://www.hrbata.com/gitweb/?a=commitdiff_plain;h=890d4f48197f325039649863e9af240e9213d04b;p=gimrr.git git-mr-comment-list: initial implementation Signed-off-by: Frantisek Hrbata --- diff --git a/git-mr-comment-list b/git-mr-comment-list new file mode 100755 index 0000000..6cf01ad --- /dev/null +++ b/git-mr-comment-list @@ -0,0 +1,122 @@ +#!/usr/bin/env python3 + +# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 + +""" +Copyright © 2020 Frantisek Hrbata +This program is free software. It comes without any warranty, to +the extent permitted by applicable law. You can redistribute it +and/or modify it under the terms of the Do What The Fuck You Want +To Public License, Version 2, as published by Sam Hocevar. See +http://www.wtfpl.net/ for more details. +""" + +import argparse +import sys +import os +import string +import mrlib +import fcntl + +fmt = "{f:2.2} {m:.16} {c:.16} {s:70.70} {n:20.20} {d}" + +parser = argparse.ArgumentParser(description="List comments for MRs.") +parser.add_argument("mr", nargs="*", default=["HEAD"], metavar="MR", + help="Merge request revisions for which comments will be listed (default: HEAD)") +parser.add_argument("-A", "--all", action="store_true", + help="List comments for all MRs. MRs entered as positional arguments or on stdin are ignored.") +parser.add_argument("-", "--stdin", action="store_true", + help="List comments for MRs from stdin. MRs entered as positional arguments are ignored.") +parser.add_argument("--fmt", metavar="FMT", default=fmt, + help="Python's formatted string for comments.") +parser.add_argument("--grep", metavar="PATTERN", action="append", + help="Limit the comments output to ones with message that matches the specified pattern. Can be used multiple times.") +parser.add_argument("--all-match", action="store_true", + help="Limit the comments output to ones that match all given --grep.") +parser.add_argument("-i", "--regexp-ignore-case", action="store_true", + help="Match the regular expression limiting patterns without regard to letter case.") +parser.add_argument("-r", "--read-revs", metavar="FILE", + help="Read revs for previously read comments from FILE (default: $HOME/.gimrr/comment.revs).") + +class CFormatter(string.Formatter): + def __init__(self): + pass + + def get_field(self, field, a, cargs): + if field not in cargs: + if field == "0": + value = "{}" + else: + value = "{{{}}}".format(field) + else: + value = cargs[field] + + return (value, field) + +cfmt = CFormatter() +def printc(fmt, cargs): + print(cfmt.vformat(fmt, None, cargs)) + +args = parser.parse_args() +user = mrlib.get_user() +refs = mrlib.load_refs() +revs = list() + +if args.read_revs: + revs_path = args.read_revs +else: + revs_path = os.environ.get('HOME') + "/" + ".gimrr/comment.revs" + +if os.path.exists(revs_path): + with open(revs_path, "r") as fd: + fcntl.lockf(fd.fileno(), fcntl.LOCK_SH | fcntl.LOCK_NB) + revs = [r for r in fd.read().split("\n") if r] + +if args.all: + mrs = mrlib.filter_revs(refs, types=["head"]) +else: + if args.stdin: + mrs = sys.stdin.readlines() + else: + mrs = args.mr + + mrs = mrlib.verify_mrs(mrs, refs) + +mboxes = mrlib.filter_revs(refs, mrs=mrs, types=["mbox"]) + +stdin = "\n".join(mboxes) +if not stdin: + sys.exit() + +cmd = ["git", "log", "--stdin", "--format=%H%x09%s%x09%an%x09%ae%x09%ad"] +if args.grep: + for pattern in args.grep: + cmd += ["--grep", pattern] + +if args.all_match: + cmd += ["--all-match"] + +if args.regexp_ignore_case: + cmd += ["--regexp-ignore-case"] + +rv, out, err = mrlib.run(cmd, stdin=stdin) + +c2m = mrlib.comments2mrs(refs, mrs) +cargs = dict() + +for line in reversed(out.split("\n")): + if not line: + continue + sha, subj, name, email, date = line.split("\t") + cargs["c"] = sha + cargs["s"] = subj + cargs["n"] = name + cargs["e"] = email + cargs["d"] = date + cargs["m"] = c2m[sha] + if sha in revs: + cargs["f"] = "" + else: + cargs["f"] = "N" + + printc(args.fmt, cargs)