import argparse import os.path import sys from pathlib import Path from typing import List, Union from jinja2 import Environment, PackageLoader, select_autoescape from ee.kicad import read_schematics from ee.project import Project def ninja_path_filter(s: Union[Path, str, List[str]]) -> str: if isinstance(s, Path): s = str(s) if isinstance(s, str): return s. \ replace("$", "$$"). \ replace(" ", "$ ") elif isinstance(s, list): if len(s) == 1: return ninja_path_filter(s[0]) return "$\n" + " $\n".join([" " + ninja_path_filter(path) for path in s]) else: raise Exception("Unsupported argument type: {}".format(type(s))) def parent_dir_filter(s: Union[str, Path]) -> Path: return Path(s).parent def basename_filter(s: Union[str, Path]) -> str: return os.path.basename(str(s)) def noext_filter(s: Union[str, Path]) -> str: return os.path.splitext(os.path.basename(str(s)))[0] def generate(project: Project): def _create_env(): e = Environment( loader=PackageLoader(__name__, "templates"), autoescape=select_autoescape(["html", "xml"]), keep_trailing_newline=True, ) e.filters["ninja_path"] = ninja_path_filter e.filters["parent_dir"] = parent_dir_filter e.filters["basename"] = basename_filter e.filters["noext"] = noext_filter return e part_dbs = [] params = { "ee": "{} -m ee".format(os.path.relpath(sys.executable, Path("."))), "project": project, "part_dbs": part_dbs, } gerber_zip = None if project.cfg.has_section("kicad-project"): kp = project.cfg["kicad-project"] if "sch" in kp: sch_path = Path(project.cfg["kicad-project"]["sch"]) sch = read_schematics(str(sch_path)) sch_files = sorted([s.path for s in sch.schematics]) params["sch"] = sch_path params["sch_files"] = sch_files if "pcb" in kp: params["pcb"] = Path(project.cfg["kicad-project"]["pcb"]) gerber_zip = "prod/gerber.zip" # TODO: read from config distributors = ["digikey"] params["distributors"] = distributors if gerber_zip is not None: params["gerber_zip"] = gerber_zip # ee_dir = sch_path.parent / "ee" build_ninja = project.project_dir / "build.ninja" ee_ninja = project.project_dir / "ee.ninja" parts_yaml_files = [path for path in project.project_dir.iterdir() if str(path).endswith("-parts.yaml")] params["parts_yaml_files"] = parts_yaml_files # Local part databases first part_dbs.extend([parent_dir_filter(p) / noext_filter(p) for p in parts_yaml_files]) part_dbs.extend([Path("ee") / d / "parts" for d in distributors]) if not build_ninja.exists(): with build_ninja.open("w") as f: f.writelines(["# This file was generated by eetools. Add your own rules and build commands\n", "# here, but keep the include line as we'll update ee.ninja for you when your\n", "# configuration changes\n", "\n", "include ee.ninja\n"]) with ee_ninja.open("w") as f: env = _create_env() template = env.get_template("build.ninja.j2") f.write(template.render(**params)) parser = argparse.ArgumentParser() args = parser.parse_args() generate(Project.load())