Files
github-actions[bot] 5c97379765 sunnypilot v2026.003.000 release
date: 2026-08-01T16:05:18
master commit: 3a05c03079d796f533f342489b3f681cfd21f98d
2026-08-01 16:09:01 +08:00

93 lines
3.0 KiB
Python
Executable File

#!/usr/bin/env python3
import importlib
import os
import re
from pathlib import Path
generator_path = os.path.dirname(os.path.realpath(__file__))
include_pattern = re.compile(r'CM_ "IMPORT (.*?)";\n')
def _read_dbc(src_dir: str, filename: str, extra_files: dict[str, str] | None = None) -> str:
if extra_files and filename in extra_files:
return extra_files[filename]
with open(os.path.join(src_dir, filename), encoding='utf-8') as file_in:
return file_in.read()
def _create_dbc_content(src_dir: str, filename: str, extra_files: dict[str, str] | None = None) -> str:
dbc_file_in = _read_dbc(src_dir, filename, extra_files)
includes = include_pattern.findall(dbc_file_in)
parts = ['CM_ "AUTOGENERATED FILE, DO NOT EDIT";\n']
for include_filename in includes:
parts.append(f'\n\nCM_ "Imported file {include_filename} starts here";\n')
parts.append(_read_dbc(src_dir, include_filename, extra_files))
parts.append(f'\nCM_ "{filename} starts here";\n')
core_dbc = include_pattern.sub('', dbc_file_in)
parts.append(core_dbc)
return ''.join(parts)
def _collect_script_outputs() -> dict[str, dict[str, str]]:
"""Import and call generate() from each sub-generator script.
Returns {dir_name: {filename: content}}."""
outputs: dict[str, dict[str, str]] = {}
for py_file in sorted(Path(generator_path).rglob("*.py")):
if py_file.name.startswith("test_") or py_file.name == "generator.py":
continue
dir_name = py_file.parent.name
module_name = f"opendbc.dbc.generator.{dir_name}.{py_file.stem}"
mod = importlib.import_module(module_name)
if hasattr(mod, 'generate'):
outputs.setdefault(dir_name, {}).update(mod.generate())
return outputs
def generate_all() -> dict[str, str]:
"""Generate all DBC content in memory. Returns {name: content} where name has no .dbc extension."""
script_outputs = _collect_script_outputs()
result = {}
for src_dir, _, filenames in os.walk(generator_path):
if src_dir == generator_path:
continue
dir_name = os.path.basename(src_dir)
extra = script_outputs.get(dir_name, {})
# all non-_ .dbc files: on-disk templates + script-generated
all_dbc_files = {f for f in filenames if f.endswith('.dbc') and not f.startswith('_')}
all_dbc_files |= {f for f in extra if not f.startswith('_')}
for filename in sorted(all_dbc_files):
output_name = filename.replace('.dbc', '_generated')
content = _create_dbc_content(src_dir, filename, extra)
result[output_name] = content
return result
def create_all(output_path: str):
"""Generate all DBC files and write them to output_path (for backward compatibility)."""
import glob
generated_suffix = '_generated.dbc'
# clear out old generated DBCs
for f in glob.glob(os.path.join(output_path, f"*{generated_suffix}")):
os.remove(f)
for name, content in generate_all().items():
with open(os.path.join(output_path, name + '.dbc'), 'w', encoding='utf-8') as f:
f.write(content)
if __name__ == "__main__":
opendbc_root = os.path.join(generator_path, '../')
create_all(opendbc_root)