mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-13 23:26:24 +00:00
Add .clang-format files and format more files
The .clang-format files tell clang-format to ignore certain directories
(replacing code in lint_clang_format.sh which will be removed).
$ git ls-tree -r master --name-only | grep '\.\(c\|h\|cpp\|gn\|gni\|mm\|m\|py\)$' | xargs ./append-space-to-files
$ git checkout -- generator/templates third_party/khronos/{KHR,vulkan}
$ git cl format --full --python
Followed by manual reformatting of a few things in Python for
readability.
Bug: none
Change-Id: I4c9e472cc9a5cd80c07286e808f4e597cfef5428
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/24785
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
committed by
Commit Bot service account
parent
5a1d39ad0b
commit
01aeca22a9
@@ -12,7 +12,6 @@
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Module to create generators that render multiple Jinja2 templates for GN.
|
||||
|
||||
A helper module that can be used to create generator scripts (clients)
|
||||
@@ -54,6 +53,7 @@ from collections import namedtuple
|
||||
#
|
||||
FileRender = namedtuple('FileRender', ['template', 'output', 'params_dicts'])
|
||||
|
||||
|
||||
# The interface that must be implemented by generators.
|
||||
class Generator:
|
||||
def get_description(self):
|
||||
@@ -72,6 +72,7 @@ class Generator:
|
||||
"""Return a list of extra input dependencies."""
|
||||
return []
|
||||
|
||||
|
||||
# Allow custom Jinja2 installation path through an additional python
|
||||
# path from the arguments if present. This isn't done through the regular
|
||||
# argparse because PreprocessingLoader uses jinja2 in the global scope before
|
||||
@@ -92,6 +93,7 @@ except ValueError:
|
||||
|
||||
import jinja2
|
||||
|
||||
|
||||
# A custom Jinja2 template loader that removes the extra indentation
|
||||
# of the template blocks so that the output is correctly indented
|
||||
class _PreprocessingLoader(jinja2.BaseLoader):
|
||||
@@ -113,18 +115,21 @@ class _PreprocessingLoader(jinja2.BaseLoader):
|
||||
def preprocess(self, source):
|
||||
lines = source.split('\n')
|
||||
|
||||
# Compute the current indentation level of the template blocks and remove their indentation
|
||||
# Compute the current indentation level of the template blocks and
|
||||
# remove their indentation
|
||||
result = []
|
||||
indentation_level = 0
|
||||
|
||||
# Filter lines that are pure comments. line_comment_prefix is not enough because it removes
|
||||
# the comment but doesn't completely remove the line, resulting in more verbose output.
|
||||
# Filter lines that are pure comments. line_comment_prefix is not
|
||||
# enough because it removes the comment but doesn't completely remove
|
||||
# the line, resulting in more verbose output.
|
||||
lines = filter(lambda line: not line.strip().startswith('//*'), lines)
|
||||
|
||||
# Remove indentation templates have for the Jinja control flow.
|
||||
for line in lines:
|
||||
# The capture in the regex adds one element per block start or end so we divide by two
|
||||
# there is also an extra line chunk corresponding to the line end, so we substract it.
|
||||
# The capture in the regex adds one element per block start or end,
|
||||
# so we divide by two. There is also an extra line chunk
|
||||
# corresponding to the line end, so we subtract it.
|
||||
numends = (len(self.blockend.split(line)) - 1) // 2
|
||||
indentation_level -= numends
|
||||
|
||||
@@ -142,14 +147,19 @@ class _PreprocessingLoader(jinja2.BaseLoader):
|
||||
elif line.startswith('\t'):
|
||||
line = line[1:]
|
||||
else:
|
||||
assert(line.strip() == '')
|
||||
assert line.strip() == ''
|
||||
return line
|
||||
|
||||
|
||||
_FileOutput = namedtuple('FileOutput', ['name', 'content'])
|
||||
|
||||
|
||||
def _do_renders(renders, template_dir):
|
||||
loader = _PreprocessingLoader(template_dir)
|
||||
env = jinja2.Environment(loader=loader, lstrip_blocks=True, trim_blocks=True, line_comment_prefix='//*')
|
||||
env = jinja2.Environment(loader=loader,
|
||||
lstrip_blocks=True,
|
||||
trim_blocks=True,
|
||||
line_comment_prefix='//*')
|
||||
|
||||
def do_assert(expr):
|
||||
assert expr
|
||||
@@ -177,16 +187,17 @@ def _do_renders(renders, template_dir):
|
||||
|
||||
return outputs
|
||||
|
||||
|
||||
# Compute the list of imported, non-system Python modules.
|
||||
# It assumes that any path outside of the root directory is system.
|
||||
def _compute_python_dependencies(root_dir = None):
|
||||
def _compute_python_dependencies(root_dir=None):
|
||||
if not root_dir:
|
||||
# Assume this script is under generator/ by default.
|
||||
root_dir = os.path.join(os.path.dirname(__file__), os.pardir)
|
||||
root_dir = os.path.abspath(root_dir)
|
||||
|
||||
module_paths = (module.__file__ for module in sys.modules.values()
|
||||
if module and hasattr(module, '__file__'))
|
||||
if module and hasattr(module, '__file__'))
|
||||
|
||||
paths = set()
|
||||
for path in module_paths:
|
||||
@@ -203,37 +214,85 @@ def _compute_python_dependencies(root_dir = None):
|
||||
|
||||
return paths
|
||||
|
||||
|
||||
def run_generator(generator):
|
||||
parser = argparse.ArgumentParser(
|
||||
description = generator.get_description(),
|
||||
formatter_class = argparse.ArgumentDefaultsHelpFormatter,
|
||||
description=generator.get_description(),
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
)
|
||||
|
||||
generator.add_commandline_arguments(parser);
|
||||
parser.add_argument('--template-dir', default='templates', type=str, help='Directory with template files.')
|
||||
parser.add_argument(kJinja2Path, default=None, type=str, help='Additional python path to set before loading Jinja2')
|
||||
parser.add_argument('--output-json-tarball', default=None, type=str, help='Name of the "JSON tarball" to create (tar is too annoying to use in python).')
|
||||
parser.add_argument('--depfile', default=None, type=str, help='Name of the Ninja depfile to create for the JSON tarball')
|
||||
parser.add_argument('--expected-outputs-file', default=None, type=str, help="File to compare outputs with and fail if it doesn't match")
|
||||
parser.add_argument('--root-dir', default=None, type=str, help='Optional source root directory for Python dependency computations')
|
||||
parser.add_argument('--allowed-output-dirs-file', default=None, type=str, help="File containing a list of allowed directories where files can be output.")
|
||||
parser.add_argument('--print-cmake-dependencies', default=False, action="store_true", help="Prints a semi-colon separated list of dependencies to stdout and exits.")
|
||||
parser.add_argument('--print-cmake-outputs', default=False, action="store_true", help="Prints a semi-colon separated list of outputs to stdout and exits.")
|
||||
parser.add_argument('--output-dir', default=None, type=str, help='Directory where to output generate files.')
|
||||
generator.add_commandline_arguments(parser)
|
||||
parser.add_argument('--template-dir',
|
||||
default='templates',
|
||||
type=str,
|
||||
help='Directory with template files.')
|
||||
parser.add_argument(
|
||||
kJinja2Path,
|
||||
default=None,
|
||||
type=str,
|
||||
help='Additional python path to set before loading Jinja2')
|
||||
parser.add_argument(
|
||||
'--output-json-tarball',
|
||||
default=None,
|
||||
type=str,
|
||||
help=('Name of the "JSON tarball" to create (tar is too annoying '
|
||||
'to use in python).'))
|
||||
parser.add_argument(
|
||||
'--depfile',
|
||||
default=None,
|
||||
type=str,
|
||||
help='Name of the Ninja depfile to create for the JSON tarball')
|
||||
parser.add_argument(
|
||||
'--expected-outputs-file',
|
||||
default=None,
|
||||
type=str,
|
||||
help="File to compare outputs with and fail if it doesn't match")
|
||||
parser.add_argument(
|
||||
'--root-dir',
|
||||
default=None,
|
||||
type=str,
|
||||
help=('Optional source root directory for Python dependency '
|
||||
'computations'))
|
||||
parser.add_argument(
|
||||
'--allowed-output-dirs-file',
|
||||
default=None,
|
||||
type=str,
|
||||
help=("File containing a list of allowed directories where files "
|
||||
"can be output."))
|
||||
parser.add_argument(
|
||||
'--print-cmake-dependencies',
|
||||
default=False,
|
||||
action="store_true",
|
||||
help=("Prints a semi-colon separated list of dependencies to "
|
||||
"stdout and exits."))
|
||||
parser.add_argument(
|
||||
'--print-cmake-outputs',
|
||||
default=False,
|
||||
action="store_true",
|
||||
help=("Prints a semi-colon separated list of outputs to "
|
||||
"stdout and exits."))
|
||||
parser.add_argument('--output-dir',
|
||||
default=None,
|
||||
type=str,
|
||||
help='Directory where to output generate files.')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
renders = generator.get_file_renders(args);
|
||||
renders = generator.get_file_renders(args)
|
||||
|
||||
# Output a list of all dependencies for CMake or the tarball for GN/Ninja.
|
||||
if args.depfile != None or args.print_cmake_dependencies:
|
||||
dependencies = generator.get_dependencies(args)
|
||||
dependencies += [args.template_dir + os.path.sep + render.template for render in renders]
|
||||
dependencies += [
|
||||
args.template_dir + os.path.sep + render.template
|
||||
for render in renders
|
||||
]
|
||||
dependencies += _compute_python_dependencies(args.root_dir)
|
||||
|
||||
if args.depfile != None:
|
||||
with open(args.depfile, 'w') as f:
|
||||
f.write(args.output_json_tarball + ": " + " ".join(dependencies))
|
||||
f.write(args.output_json_tarball + ": " +
|
||||
" ".join(dependencies))
|
||||
|
||||
if args.print_cmake_dependencies:
|
||||
sys.stdout.write(";".join(dependencies))
|
||||
@@ -248,33 +307,42 @@ def run_generator(generator):
|
||||
actual = {render.output for render in renders}
|
||||
|
||||
if actual != expected:
|
||||
print("Wrong expected outputs, caller expected:\n " + repr(sorted(expected)))
|
||||
print("Wrong expected outputs, caller expected:\n " +
|
||||
repr(sorted(expected)))
|
||||
print("Actual output:\n " + repr(sorted(actual)))
|
||||
return 1
|
||||
|
||||
# Print the list of all the outputs for cmake.
|
||||
if args.print_cmake_outputs:
|
||||
sys.stdout.write(";".join([os.path.join(args.output_dir, render.output) for render in renders]))
|
||||
sys.stdout.write(";".join([
|
||||
os.path.join(args.output_dir, render.output) for render in renders
|
||||
]))
|
||||
return 0
|
||||
|
||||
outputs = _do_renders(renders, args.template_dir)
|
||||
|
||||
# The caller wants to assert that the outputs are only in specific directories.
|
||||
# The caller wants to assert that the outputs are only in specific
|
||||
# directories.
|
||||
if args.allowed_output_dirs_file != None:
|
||||
with open(args.allowed_output_dirs_file) as f:
|
||||
allowed_dirs = set([line.strip() for line in f.readlines()])
|
||||
|
||||
for directory in allowed_dirs:
|
||||
if not directory.endswith('/'):
|
||||
print('Allowed directory entry "{}" doesn\'t end with /'.format(directory))
|
||||
print('Allowed directory entry "{}" doesn\'t '
|
||||
'end with /'.format(directory))
|
||||
return 1
|
||||
|
||||
def check_in_subdirectory(path, directory):
|
||||
return path.startswith(directory) and not '/' in path[len(directory):]
|
||||
return path.startswith(
|
||||
directory) and not '/' in path[len(directory):]
|
||||
|
||||
for render in renders:
|
||||
if not any(check_in_subdirectory(render.output, directory) for directory in allowed_dirs):
|
||||
print('Output file "{}" is not in the allowed directory list below:'.format(render.output))
|
||||
if not any(
|
||||
check_in_subdirectory(render.output, directory)
|
||||
for directory in allowed_dirs):
|
||||
print('Output file "{}" is not in the allowed directory '
|
||||
'list below:'.format(render.output))
|
||||
for directory in sorted(allowed_dirs):
|
||||
print(' "{}"'.format(directory))
|
||||
return 1
|
||||
|
||||
Reference in New Issue
Block a user