diff --git a/Lib/gftools/qa.py b/Lib/gftools/qa.py index 1c61cf279..7c34c29f7 100644 --- a/Lib/gftools/qa.py +++ b/Lib/gftools/qa.py @@ -1,32 +1,52 @@ import logging import os import subprocess +import traceback from gftools.gfgithub import GitHubClient from gftools.utils import mkdir + try: from diffenator2 import ninja_diff, ninja_proof except ModuleNotFoundError: - raise ModuleNotFoundError(("gftools was installed without the QA " - "dependencies. To install the dependencies, see the ReadMe, " - "https://github.com/googlefonts/gftools#installation")) + raise ModuleNotFoundError( + ( + "gftools was installed without the QA " + "dependencies. To install the dependencies, see the ReadMe, " + "https://github.com/googlefonts/gftools#installation" + ) + ) logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) +def report_exceptions(meth): + def safe_call(self, *args, **kwargs): + try: + meth(self, *args, **kwargs) + except Exception as e: + msg = f"Call to {meth.__name__} failed:\n{e}" + print(msg) + print() + print(traceback.format_exc()) + self.post_to_github(msg+"\n\n"+"See CI logs for more details") + + return safe_call + + class FontQA: - def __init__(self, fonts, fonts_before=None, out="out"): + def __init__(self, fonts, fonts_before=None, out="out", url=None): self.fonts = fonts self.fonts_before = fonts_before self.out = out + self.url = url + @report_exceptions def diffenator(self, **kwargs): logger.info("Running Diffenator") if not self.fonts_before: - logger.warning( - "Cannot run Diffenator since there are no fonts before" - ) + logger.warning("Cannot run Diffenator since there are no fonts before") return dst = os.path.join(self.out, "Diffenator") ninja_diff( @@ -39,13 +59,12 @@ def diffenator(self, **kwargs): diffenator=True, diffbrowsers=False, ) - + + @report_exceptions def diffbrowsers(self, imgs=False): logger.info("Running Diffbrowsers") if not self.fonts_before: - logger.warning( - "Cannot run diffbrowsers since there are no fonts before" - ) + logger.warning("Cannot run diffbrowsers since there are no fonts before") return dst = os.path.join(self.out, "Diffbrowsers") mkdir(dst) @@ -59,7 +78,8 @@ def diffbrowsers(self, imgs=False): diffenator=False, diffbrowsers=True, ) - + + @report_exceptions def proof(self, imgs=False): logger.info("Running proofing tools") dst = os.path.join(self.out, "Proof") @@ -71,12 +91,13 @@ def proof(self, imgs=False): filter_styles=None, ) + @report_exceptions def fontbakery(self, profile="googlefonts", html=False, extra_args=None): logger.info("Running Fontbakery") out = os.path.join(self.out, "Fontbakery") mkdir(out) cmd = ( - ["fontbakery", "check-"+profile, "-l", "INFO", "--succinct"] + ["fontbakery", "check-" + profile, "-l", "INFO", "--succinct"] + [f.path for f in self.fonts] + ["-C"] + ["--ghmarkdown", os.path.join(out, "report.md")] @@ -87,6 +108,16 @@ def fontbakery(self, profile="googlefonts", html=False, extra_args=None): cmd.extend(extra_args) subprocess.call(cmd) + fontbakery_report = os.path.join(self.out, "Fontbakery", "report.md") + if not os.path.isfile(fontbakery_report): + logger.warning( + "Cannot Post Github message because no Fontbakery report exists" + ) + return + with open(fontbakery_report) as doc: + msg = doc.read() + self.post_to_github(msg) + def googlefonts_upgrade(self, imgs=False): self.fontbakery() self.diffenator() @@ -102,27 +133,20 @@ def render(self, imgs=False): else: self.proof(imgs) - def post_to_github(self, url): - """Post Fontbakery report as a new issue or as a comment to an open + def post_to_github(self, text): + """Post text as a new issue or as a comment to an open PR""" + if not self.url: + return # Parse url tokens - url_split = url.split("/") + url_split = self.url.split("/") repo_owner = url_split[3] repo_name = url_split[4] - issue_number = url_split[-1] if "pull" in url else None + issue_number = url_split[-1] if "pull" in self.url else None - fontbakery_report = os.path.join(self.out, "Fontbakery", "report.md") - if not os.path.isfile(fontbakery_report): - logger.warning( - "Cannot Post Github message because no Fontbakery report exists" - ) - return - client = GitHubClient(repo_owner, repo_name) - with open(fontbakery_report) as doc: - msg = doc.read() - if issue_number: - client.create_issue_comment(issue_number, msg) - else: - client.create_issue("Google Font QA report", msg) + if issue_number: + client.create_issue_comment(issue_number, text) + else: + client.create_issue("Google Font QA report", text) diff --git a/Lib/gftools/scripts/qa.py b/Lib/gftools/scripts/qa.py index eb0b0c140..ee1b6fda7 100755 --- a/Lib/gftools/scripts/qa.py +++ b/Lib/gftools/scripts/qa.py @@ -216,12 +216,20 @@ def main(args=None): family_name, fonts_before_dir ) + url = None + if args.out_url: + url = args.out_url + elif args.out_github and args.pull_request: + url = args.pull_request + elif args.out_github and args.github_dir: + url = args.github_dir + if fonts_before: dfonts_before = [DFont(f) for f in fonts_before if f.endswith((".ttf", ".otf")) and "static" not in f] - qa = FontQA(dfonts, dfonts_before, args.out) + qa = FontQA(dfonts, dfonts_before, args.out, url=url) else: - qa = FontQA(dfonts, out=args.out) + qa = FontQA(dfonts, out=args.out, url=url) if args.auto_qa and family_on_gf: qa.googlefonts_upgrade(args.imgs) @@ -238,13 +246,6 @@ def main(args=None): if args.proof: qa.proof() - if args.out_url: - qa.post_to_github(args.out_url) - elif args.out_github and args.pull_request: - qa.post_to_github(args.pull_request) - elif args.out_github and args.github_dir: - qa.post_to_github(args.github_dir) - if __name__ == "__main__": main()