100 lines
2.7 KiB
Python
100 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: UTF-8 -*-
|
|
|
|
"""
|
|
Parse and re-serialize ftl files to get them in a consistent form.
|
|
"""
|
|
|
|
import os
|
|
import json
|
|
import glob
|
|
import sys
|
|
import difflib
|
|
from typing import List
|
|
from fluent.syntax import parse, serialize
|
|
from fluent.syntax.ast import Junk
|
|
from compare_locales.paths import File
|
|
from compare_locales import parser
|
|
from compare_locales.checks.fluent import ReferenceMessageVisitor
|
|
|
|
|
|
def check_missing_terms(path: str) -> bool:
|
|
"True if file is ok."
|
|
file = File(path, os.path.basename(path))
|
|
content = open(path, "rb").read()
|
|
p = parser.getParser(file.file)
|
|
p.readContents(content)
|
|
refList = p.parse()
|
|
|
|
p.readContents(content)
|
|
for e in p.parse():
|
|
ref_data = ReferenceMessageVisitor()
|
|
ref_data.visit(e.entry)
|
|
|
|
for attr_or_val, refs in ref_data.entry_refs.items():
|
|
for ref, ref_type in refs.items():
|
|
if ref not in refList:
|
|
print(f"In {path}:{e}, missing '{ref}'")
|
|
return False
|
|
|
|
return True
|
|
|
|
|
|
def check_file(path: str, fix: bool) -> bool:
|
|
"True if file is ok."
|
|
orig_text = open(path, encoding="utf8").read()
|
|
obj = parse(orig_text, with_spans=False)
|
|
# make sure there's no junk
|
|
for ent in obj.body:
|
|
if isinstance(ent, Junk):
|
|
raise Exception(f"file had junk! {path} {ent}")
|
|
# serialize
|
|
new_text = serialize(obj)
|
|
# make sure serializing did not introduce new junk
|
|
obj = parse(new_text, with_spans=False)
|
|
for ent in obj.body:
|
|
if isinstance(ent, Junk):
|
|
raise Exception(f"file introduced junk! {path} {ent}")
|
|
|
|
if new_text == orig_text:
|
|
return check_missing_terms(path)
|
|
|
|
if fix:
|
|
print(f"Fixing {path}")
|
|
open(path, "w", newline="\n", encoding="utf8").write(new_text)
|
|
return True
|
|
else:
|
|
print(f"Bad formatting in {path}")
|
|
print(
|
|
"\n".join(
|
|
difflib.unified_diff(
|
|
orig_text.splitlines(),
|
|
new_text.splitlines(),
|
|
fromfile="bad",
|
|
tofile="good",
|
|
lineterm="",
|
|
)
|
|
)
|
|
)
|
|
return False
|
|
|
|
|
|
def check_files(files: List[str], fix: bool) -> bool:
|
|
"True if files ok."
|
|
|
|
found_bad = False
|
|
for path in files:
|
|
ok = check_file(path, fix)
|
|
if not ok:
|
|
found_bad = True
|
|
return not found_bad
|
|
|
|
|
|
if __name__ == "__main__":
|
|
template_root = os.environ["BUILD_WORKSPACE_DIRECTORY"]
|
|
template_files = glob.glob(
|
|
os.path.join(template_root, "ftl", "*", "*.ftl"), recursive=True
|
|
)
|
|
|
|
check_files(template_files, fix=True)
|