Files
sunnypilot/selfdrive/car/docs.py
Adeeb Shihadeh 16ec56398c add openpilot prefix to imports (#29498)
* add openpilot prefix to imports

* more

* more

* fix docs

* fix linter

* bump submodules

* fix patched tests

* update dynamic imports

* debug

* Revert "debug"

This reverts commit db5e13b9911cc74438bee123bc3430da6c31b24b.

* fix pm test
old-commit-hash: a9626f95b6
2023-08-20 20:49:55 -07:00

83 lines
3.1 KiB
Python
Executable File

#!/usr/bin/env python3
import argparse
from collections import defaultdict
import jinja2
import os
from enum import Enum
from natsort import natsorted
from typing import Dict, List
from cereal import car
from openpilot.common.basedir import BASEDIR
from openpilot.selfdrive.car import gen_empty_fingerprint
from openpilot.selfdrive.car.docs_definitions import CarInfo, Column, CommonFootnote, PartType
from openpilot.selfdrive.car.car_helpers import interfaces, get_interface_attr
def get_all_footnotes() -> Dict[Enum, int]:
all_footnotes = list(CommonFootnote)
for footnotes in get_interface_attr("Footnote", ignore_none=True).values():
all_footnotes.extend(footnotes)
return {fn: idx + 1 for idx, fn in enumerate(all_footnotes)}
CARS_MD_OUT = os.path.join(BASEDIR, "docs", "CARS.md")
CARS_MD_TEMPLATE = os.path.join(BASEDIR, "selfdrive", "car", "CARS_template.md")
def get_all_car_info() -> List[CarInfo]:
all_car_info: List[CarInfo] = []
footnotes = get_all_footnotes()
for model, car_info in get_interface_attr("CAR_INFO", combine_brands=True).items():
# If available, uses experimental longitudinal limits for the docs
CP = interfaces[model][0].get_params(model, fingerprint=gen_empty_fingerprint(),
car_fw=[car.CarParams.CarFw(ecu="unknown")], experimental_long=True, docs=True)
if CP.dashcamOnly or car_info is None:
continue
# A platform can include multiple car models
if not isinstance(car_info, list):
car_info = (car_info,)
for _car_info in car_info:
if not hasattr(_car_info, "row"):
_car_info.init_make(CP)
_car_info.init(CP, footnotes)
all_car_info.append(_car_info)
# Sort cars by make and model + year
sorted_cars: List[CarInfo] = natsorted(all_car_info, key=lambda car: car.name.lower())
return sorted_cars
def group_by_make(all_car_info: List[CarInfo]) -> Dict[str, List[CarInfo]]:
sorted_car_info = defaultdict(list)
for car_info in all_car_info:
sorted_car_info[car_info.make].append(car_info)
return dict(sorted_car_info)
def generate_cars_md(all_car_info: List[CarInfo], template_fn: str) -> str:
with open(template_fn, "r") as f:
template = jinja2.Template(f.read(), trim_blocks=True, lstrip_blocks=True)
footnotes = [fn.value.text for fn in get_all_footnotes()]
cars_md: str = template.render(all_car_info=all_car_info, PartType=PartType,
group_by_make=group_by_make, footnotes=footnotes,
Column=Column)
return cars_md
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Auto generates supported cars documentation",
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument("--template", default=CARS_MD_TEMPLATE, help="Override default template filename")
parser.add_argument("--out", default=CARS_MD_OUT, help="Override default generated filename")
args = parser.parse_args()
with open(args.out, 'w') as f:
f.write(generate_cars_md(get_all_car_info(), args.template))
print(f"Generated and written to {args.out}")