Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the qa tool more robust #709

Merged
merged 5 commits into from
Sep 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 54 additions & 30 deletions Lib/gftools/qa.py
Original file line number Diff line number Diff line change
@@ -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(
Expand All @@ -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)
Expand All @@ -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")
Expand All @@ -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")]
Expand All @@ -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()
Expand All @@ -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)
19 changes: 10 additions & 9 deletions Lib/gftools/scripts/qa.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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()
Loading