-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathport_check.py
124 lines (105 loc) · 3.2 KB
/
port_check.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import argparse
import inspect
import os
import re
import shutil
import subprocess
import fontbakery
import fontbakery.fonts_profile
from jinja2 import Template
FONTBAKERY_DIR = os.path.dirname(fontbakery.__file__)
parser = argparse.ArgumentParser(
description="Port a check from fontbakery to fontspector"
)
parser.add_argument("check", help="The name of the check to port")
parser.add_argument(
"--profile",
help="The name of the profile to port the check to",
choices=["googlefonts", "universal", "opentype"],
default="universal",
)
args = parser.parse_args()
fontbakery.fonts_profile.load_all_checks()
try:
check = fontbakery.fonts_profile.checks_by_id[args.check]
except KeyError:
print("Check not found")
exit(1)
checkid_parts = check.id.split("/")
functionname = checkid_parts.pop(-1)
filename = '/'.join(checkid_parts) + '/' + functionname + ".rs"
source = inspect.getsource(check)
source = re.sub("(?s).*?def ", "def ", source, count=1)
source = re.sub("(?m)^", " // ", source)
template = Template(
r"""
use fontspector_checkapi::{prelude::*, testfont, FileTypeConvert};
use skrifa::MetadataProvider;
#[check(
id = "{{ check.id }}",
rationale = "
{{ check.rationale | replace('"', '\\"') }}
",
proposal = "{{ proposal | join(' and ')}}",
title = "{{ check.__doc__}}"
)]
fn {{ functionname }} (t: &Testable, _context: &Context) -> CheckFnResult {
let f = testfont!(t);
let mut problems = vec![];
{{ source }}
unimplemented!();
return_result(problems)
}
"""
)
with open("profile-" + args.profile + "/src/checks/" + filename, "w+") as f:
f.write(
template.render(
check=check,
proposal=(
check.proposal if isinstance(check.proposal, list) else [check.proposal]
),
filename=filename,
functionname=functionname,
source=source,
)
)
subprocess.run(
[
"rustfmt",
"profile-" + args.profile + "/src/checks/" + filename,
],
check=True,
)
# Add it to the mod.rs files
for i in range(len(checkid_parts)+1):
subdirs = '/'.join(checkid_parts[:i])
if subdirs: subdirs += '/'
modfile = "profile-" + args.profile + "/src/checks/" + subdirs + "mod.rs"
if i < len(checkid_parts):
modline = f"pub mod {checkid_parts[i]};\n"
else:
modline = f"mod {functionname};\n"
modline += f"pub use {functionname}::{functionname};\n"
if os.path.exists(modfile) and modline not in open(modfile, "r").read():
with open(modfile, "a") as f:
f.write(modline)
# Sort it with rustfmt
subprocess.run(
[
"rustfmt",
modfile,
"--unstable-features",
"--skip-children",
],
check=True,
)
# See if we can find a test
test_base_file = "test_checks_" + check.id.replace("/", "_") + ".py"
test_file = os.path.join(FONTBAKERY_DIR, "tests", test_base_file)
if os.path.exists(test_file):
# Copy to fontspector-py/tests
target = os.path.join("fontspector-py", "tests", test_base_file)
shutil.copy(test_file, target)
else:
print(f"No test file found in {test_file}")