blob: 978659334d8ee105c1fe32b0b0c1cb9bc3d8ba7b [file] [log] [blame] [edit]
#!/usr/bin/python3
import subprocess
import re
import os
import argparse
from collections import defaultdict
from enum import Enum
from glob import glob
class CheckType(Enum):
NEW_FAMILY = 1
MODIFIED_FAMILY = 2
MODIFIED_FAMILY_METADATA = 3
DESIGNER = 4
class CheckToken(Enum):
NEW_FONT = 1
DESIGNER = 2
FONT_FAMILY = 3
MODIFIED_FONTS = 4
MODIFIED_METADATA = 5
def _parse_git_diff(diff_info: str) -> list[tuple[str, str]]:
"""
'''
A ofl/mavenpro/MavenPro[wght].ttf
M ofl/mavenpro/METADATA.pb
''' -> [
("A", "ofl/mavenpro/MavenPro[wght].ttf"),
("M", "ofl/mavenpro/METADATA.pb")
]
"""
parsed = re.findall(r"([A|M|D])(\t)(.*)", diff_info)
return [(s, p) for s, _, p in parsed]
def directory_check_types(branch="origin/main"):
git_diff_text = subprocess.run(
["git", "diff", branch, "--name-status"], capture_output=True
).stdout.decode("utf-8")
git_diff = _parse_git_diff(git_diff_text)
# Tokenize each directory git diff has reported
directories_to_check = defaultdict(set)
for state, path in git_diff:
dirpath = (
os.path.dirname(path)
if path not in ("to_sandbox.txt", "to_production.txt")
else path
)
# skip article directories. These should be checked on github
if os.path.basename(dirpath) == "article":
continue
dir_tokens = directories_to_check[dirpath]
if path.startswith("catalog"):
dir_tokens.add(CheckToken.DESIGNER)
if path.startswith(("ofl", "ufl", "apache")):
dir_tokens.add(CheckToken.FONT_FAMILY)
if path.endswith((".ttf", ".otf")) and state == "A":
dir_tokens.add(CheckToken.NEW_FONT)
if path.endswith((".ttf", ".otf")) and (state == "M" or state == "D"):
dir_tokens.add(CheckToken.MODIFIED_FONTS)
if path.endswith((".txt", ".pb", ".html")) and state == "M":
dir_tokens.add(CheckToken.MODIFIED_METADATA)
# Set each directory's check type
results = []
for path, tokens in directories_to_check.items():
if CheckToken.FONT_FAMILY in tokens:
if CheckToken.MODIFIED_FONTS in tokens:
results.append((path, CheckType.MODIFIED_FAMILY))
elif CheckToken.MODIFIED_METADATA in tokens:
results.append((path, CheckType.MODIFIED_FAMILY_METADATA))
else:
results.append((path, CheckType.NEW_FAMILY))
if CheckToken.DESIGNER in tokens:
results.append((path, CheckType.DESIGNER))
return results
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
"--branch", default="origin/main", help="branch to compare current head against"
)
parser.add_argument(
"--render", action="store_true", help="Check rendering of families only"
)
parser.add_argument("--pr-number", help="PR to output fontbakery report to")
parser.add_argument("--pr-url-body", default="https://www.github.com/google/fonts/pull/%s")
args = parser.parse_args()
profile_test_file = os.path.join(os.path.dirname(__file__), "test_profiles.py")
for directory, check_type in directory_check_types(args.branch):
out = os.path.join("out", os.path.basename(directory))
fonts = glob(os.path.join(directory, "*.ttf"))
qa_cmd_prefix = ["gftools", "qa", "-f"] + fonts + ["-o", out]
if args.pr_number:
if not args.pr_url_body.endswith("/"):
args.pr_url_body += "/"
url = "%s%s" % (args.pr_url_body, args.pr_number)
qa_cmd_prefix += ["--out-url", url]
if args.render and check_type == CheckType.NEW_FAMILY:
print(f"Rendering new family: {directory}")
subprocess.run(qa_cmd_prefix + ["-gfb", "--render", "--imgs"])
elif args.render and check_type == CheckType.MODIFIED_FAMILY:
print(f"Rendering modified family: {directory}")
subprocess.run(qa_cmd_prefix + ["-gfb", "--render", "--imgs"])
# we only want args.render to do the above two conditions
elif args.render:
continue
elif check_type == CheckType.NEW_FAMILY:
print(f"Checking new family: {directory}")
subprocess.run(qa_cmd_prefix + ["--fontbakery", "--interpolations"], check=True)
elif check_type == CheckType.MODIFIED_FAMILY:
print(f"Checking modified family: {directory}")
subprocess.run(qa_cmd_prefix + ["-gfb", "--fontbakery", "--diffenator", "--interpolations"], check=True)
elif check_type == CheckType.MODIFIED_FAMILY_METADATA:
print(f"Checking modified family metadata: {directory}")
subprocess.run(qa_cmd_prefix + ["--fontbakery", "-o", out], check=True)
elif check_type == CheckType.DESIGNER:
print(f"Checking designer profile: {directory}")
subprocess.run(["pytest", profile_test_file, directory])
else:
print(f"Skipping directory {directory}")
if __name__ == "__main__":
main()