123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- #!/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
- )
- 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"])
- elif check_type == CheckType.MODIFIED_FAMILY:
- print(f"Checking modified family: {directory}")
- subprocess.run(qa_cmd_prefix + ["-gfb", "--fontbakery", "--diffenator"])
- elif check_type == CheckType.MODIFIED_FAMILY_METADATA:
- print(f"Checking modified family metadata: {directory}")
- subprocess.run(qa_cmd_prefix + ["--fontbakery", "-o", out])
- 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()
|