
When opening a text file it is important to specify encoding='utf-8' since otherwise the behavior will depend on your system locale. This change fixes all the encoding omissions I could find in the tools directory, found by running "git cl presubmit --all" with crrev.com/c/4290775 patched in. Bug: 1418846 Change-Id: Ie4478ff9b3e3814e6396a5b0c3c0e9c273202838 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4295846 Commit-Queue: Bruce Dawson <brucedawson@chromium.org> Reviewed-by: Demetrios Papadopoulos <dpapad@chromium.org> Cr-Commit-Position: refs/heads/main@{#1111897}
108 lines
4.0 KiB
Python
108 lines
4.0 KiB
Python
# Copyright 2022 The Chromium Authors
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
import collections
|
|
import importlib.util
|
|
import os
|
|
import re
|
|
import sys
|
|
from typing import Dict, List
|
|
|
|
from json_data_generator.util import (GetDirNameFromPath, GetFileNameFromPath,
|
|
GetFileNameWithoutExtensionFromPath,
|
|
JoinPath)
|
|
|
|
_FILE_PATH = os.path.dirname(os.path.realpath(__file__))
|
|
|
|
_JSON5_PATH = os.path.join(_FILE_PATH, os.pardir, os.pardir, 'third_party',
|
|
'pyjson5', 'src')
|
|
sys.path.insert(1, _JSON5_PATH)
|
|
import json5
|
|
|
|
_JINJA2_PATH = os.path.join(_FILE_PATH, os.pardir, os.pardir, 'third_party')
|
|
sys.path.insert(1, _JINJA2_PATH)
|
|
import jinja2
|
|
|
|
|
|
class JSONDataGenerator(object):
|
|
'''A generic json data generator.'''
|
|
|
|
def __init__(self, out_dir: str):
|
|
self.out_dir = out_dir
|
|
self.model: Dict = {}
|
|
# Store all json sources used in the generator.
|
|
self.sources: List[str] = list()
|
|
|
|
def AddJSONFilesToModel(self, paths: List[str]):
|
|
'''Adds one or more JSON files to the model.'''
|
|
for path in paths:
|
|
try:
|
|
with open(path, 'r', encoding='utf-8') as f:
|
|
self.AddJSONToModel(path, f.read())
|
|
self.sources.append(path)
|
|
except ValueError as err:
|
|
raise ValueError('\n%s:\n %s' % (path, err))
|
|
|
|
def AddJSONToModel(self, json_path: str, json_string: str):
|
|
'''Adds a |json_string| with data to the model.
|
|
Every json file is added to |self.model| with the original file
|
|
name as the key.
|
|
'''
|
|
data = json5.loads(json_string,
|
|
object_pairs_hook=collections.OrderedDict)
|
|
# Use the json file name as the key of the loaded json data.
|
|
key = GetFileNameWithoutExtensionFromPath(json_path)
|
|
self.model[key] = data
|
|
|
|
def GetGlobals(self, template_path: str):
|
|
file_name_without_ext = GetFileNameWithoutExtensionFromPath(
|
|
template_path)
|
|
out_file_path = JoinPath(self.out_dir, file_name_without_ext)
|
|
return {
|
|
'model': self.model,
|
|
'source_json_files': self.sources,
|
|
'out_file_path': out_file_path,
|
|
}
|
|
|
|
def GetFilters(self):
|
|
return {
|
|
'to_header_guard': self._ToHeaderGuard,
|
|
}
|
|
|
|
def RenderTemplate(self,
|
|
path_to_template: str,
|
|
path_to_template_helper: str = None):
|
|
template_dir = GetDirNameFromPath(path_to_template)
|
|
template_name = GetFileNameFromPath(path_to_template)
|
|
jinja_env = jinja2.Environment(
|
|
loader=jinja2.FileSystemLoader(template_dir),
|
|
keep_trailing_newline=True)
|
|
jinja_env.globals.update(self.GetGlobals(path_to_template))
|
|
jinja_env.filters.update(self.GetFilters())
|
|
if path_to_template_helper:
|
|
template_helper_module = self._LoadTemplateHelper(
|
|
path_to_template_helper)
|
|
jinja_env.globals.update(
|
|
template_helper_module.get_custom_globals(self.model))
|
|
jinja_env.filters.update(
|
|
template_helper_module.get_custom_filters(self.model))
|
|
template = jinja_env.get_template(template_name)
|
|
return template.render()
|
|
|
|
def _LoadTemplateHelper(self, path_to_template_helper: str):
|
|
template_helper_dir = GetDirNameFromPath(path_to_template_helper)
|
|
try:
|
|
sys.path.append(template_helper_dir)
|
|
spec = importlib.util.spec_from_file_location(
|
|
path_to_template_helper, path_to_template_helper)
|
|
module = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(module)
|
|
return module
|
|
finally:
|
|
# Restore sys.path to what it was before.
|
|
sys.path.remove(template_helper_dir)
|
|
|
|
def _ToHeaderGuard(self, path: str):
|
|
return re.sub(r'[\\\/\.\-]+', '_', path.upper())
|