| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- # Copyright (c) 2022 Project CHIP Authors
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # 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.
- import fnmatch
- import logging
- import os
- from dataclasses import dataclass, field
- from typing import Iterator, List, Optional
- from .types import IdlFileType, InputIdlFile
- from .using_codegen import (CodegenCppAppPregenerator, CodegenCppClustersTLVMetaPregenerator,
- CodegenCppProtocolsTLVMetaPregenerator, CodegenJavaClassPregenerator, CodegenJavaJNIPregenerator)
- from .using_zap import ZapApplicationPregenerator
- def _IdlsInDirectory(top_directory_name: str, truncate_length: int):
- for root, dirs, files in os.walk(top_directory_name):
- for file in files:
- if file.endswith('.zap'):
- yield InputIdlFile(file_type=IdlFileType.ZAP,
- full_path=os.path.join(root, file),
- relative_path=os.path.join(root[truncate_length:], file))
- if file.endswith('.matter'):
- yield InputIdlFile(file_type=IdlFileType.MATTER,
- full_path=os.path.join(root, file),
- relative_path=os.path.join(root[truncate_length:], file))
- def _FindAllIdls(sdk_root: str, external_roots: Optional[List[str]]) -> Iterator[InputIdlFile]:
- relevant_subdirs = [
- 'examples', # all example apps
- 'src', # realistically only controller/data_model
- ]
- while sdk_root.endswith('/'):
- sdk_root = sdk_root[:-1]
- sdk_root_length = len(sdk_root)
- # first go over SDK items
- for subdir_name in relevant_subdirs:
- top_directory_name = os.path.join(sdk_root, subdir_name)
- logging.debug(f"Searching {top_directory_name}")
- for idl in _IdlsInDirectory(top_directory_name, sdk_root_length+1):
- yield idl
- # next external roots
- if external_roots:
- for root in external_roots:
- root = os.path.normpath(root)
- for idl in _IdlsInDirectory(root, len(root) + 1):
- yield idl
- @dataclass
- class TargetFilter:
- # If set, only the specified files are accepted for codegen
- file_type: Optional[IdlFileType] = None
- # If non-empty only the given paths will be code-generated
- path_glob: List[str] = field(default_factory=list)
- # TODO: the build GlobMatcher is more complete by supporting `{}` grouping
- # For now this limited glob seems sufficient.
- class GlobMatcher:
- def __init__(self, pattern: str):
- self.pattern = pattern
- def matches(self, s: str):
- return fnmatch.fnmatch(s, self.pattern)
- def FindPregenerationTargets(sdk_root: str, external_roots: Optional[List[str]], filter: TargetFilter, runner):
- """Finds all relevand pre-generation targets in the given
- SDK root.
- Pre-generation targets are based on zap and matter files with options
- on what rules to pregenerate and how.
- """
- generators = [
- # Jinja-based codegen
- CodegenJavaJNIPregenerator(sdk_root),
- CodegenJavaClassPregenerator(sdk_root),
- CodegenCppAppPregenerator(sdk_root),
- CodegenCppClustersTLVMetaPregenerator(sdk_root),
- CodegenCppProtocolsTLVMetaPregenerator(sdk_root),
- # ZAP codegen
- ZapApplicationPregenerator(sdk_root),
- ]
- path_matchers = [GlobMatcher(pattern) for pattern in filter.path_glob]
- for idl in _FindAllIdls(sdk_root, external_roots):
- if filter.file_type is not None:
- if idl.file_type != filter.file_type:
- logging.debug(f"Will not process file of type {idl.file_type}: {idl.relative_path}")
- continue
- if path_matchers:
- if all([not matcher.matches(idl.relative_path) for matcher in path_matchers]):
- logging.debug(f"Glob not matched for {idl.relative_path}")
- continue
- for generator in generators:
- if generator.Accept(idl):
- yield generator.CreateTarget(idl, runner=runner)
|