import os import pathlib Import('env') if not hasattr(env, 'Jinja'): Return('env') def _jinja_load_config(env, config_name): searched_paths = [] for scons_path in env['JINJA_CONFIG_SEARCHPATH']: if hasattr(scons_path, 'abspath'): scons_path = scons_path.abspath path = pathlib.Path(scons_path) / f'{config_name}.yml' if path.exists(): with path.open('r') as file: import yaml return yaml.safe_load(file) searched_paths.append(f'\n{path}') joined_paths = ''.join(searched_paths) raise Exception(f'Could not find Jinja config file "{config_name}.yml". Searched: {joined_paths}') def _wrap_jinja(orig_jinja): def _wrapped(env, target, **kwargs): if 'source' not in kwargs: kwargs['source'] = f'{target}.jinja' target = orig_jinja(**kwargs) if 'depends' in kwargs: for dependency in kwargs['depends']: env.Depends(target, dependency) # env.Depends(alias_prepare, target) return target return _wrapped def _find_file(env, fname): for path in env['JINJA_FILE_SEARCHPATH']: fullpath = os.path.join(path.abspath, fname) if os.path.exists(fullpath): return env.File(fullpath) return None def _file_size(env, fname: str) -> int: file = _find_file(env, fname) if not file: env.Error(f'File does not exist: {fname}. Searched in: {[d.abspath for d in env["JINJA_FILE_SEARCHPATH"]]}') return file.get_size() def _file_content_hex(env, fname: str) -> str: file = _find_file(env, fname) if not file: env.Error(f'File does not exist: {fname}. Searched in: {[d.abspath for d in env["JINJA_FILE_SEARCHPATH"]]}') bytes = file.get_contents() return ','.join([hex(byte) for byte in bytes]) env.AddMethod(_wrap_jinja(env.Jinja), 'Jinja') env.Append(JINJA_FILTERS = {'load_config': _jinja_load_config}) env.Append(JINJA_GLOBALS = { 'file_size': lambda *args: _file_size(env, *args), 'file_content_hex': lambda *args: _file_content_hex(env, *args) }) env.Append(JINJA_TEMPLATE_SEARCHPATH = ['data/jinja']) env['JINJA_CONFIG_SEARCHPATH'] = [env.Dir('#data/config')] env['JINJA_FILE_SEARCHPATH'] = [env.Dir('#')] Return('env')