aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2019-03-04 00:06:32 +0100
committerTrygve Laugstøl <trygvis@inamo.no>2019-03-04 00:06:32 +0100
commit5a6ab34565fa3d783337a68e07e3500361c8fcf5 (patch)
treec0d4fd9f6986351a543838fabc3dacf8d9ad5fb1
parent650b4ad3774c4cc454a02073808d981f6873036d (diff)
downloadee-python-5a6ab34565fa3d783337a68e07e3500361c8fcf5.tar.gz
ee-python-5a6ab34565fa3d783337a68e07e3500361c8fcf5.tar.bz2
ee-python-5a6ab34565fa3d783337a68e07e3500361c8fcf5.tar.xz
ee-python-5a6ab34565fa3d783337a68e07e3500361c8fcf5.zip
o PartDB: don't die if the directory exist *and* is empty. Ninja creates
empty parent directories. o PartDB: escape some path names. o new comamnd: "ninja". Generates a build.ninja from a sch. Not done!
-rw-r--r--demo/thirdparty/olinuxino/.gitignore2
-rw-r--r--demo/thirdparty/olinuxino/build.ninja56
-rw-r--r--demo/thirdparty/olinuxino/py/olinuxino.py57
-rw-r--r--src/ee/part/__init__.py6
-rw-r--r--src/ee/tools/__init__.py3
-rw-r--r--src/ee/tools/ninja.py80
-rw-r--r--src/ee/tools/templates/build.ninja.j253
-rw-r--r--src/ee/xml/bom_file_utils.py1
8 files changed, 255 insertions, 3 deletions
diff --git a/demo/thirdparty/olinuxino/.gitignore b/demo/thirdparty/olinuxino/.gitignore
new file mode 100644
index 0000000..a0536f7
--- /dev/null
+++ b/demo/thirdparty/olinuxino/.gitignore
@@ -0,0 +1,2 @@
+ee
+.ninja_*
diff --git a/demo/thirdparty/olinuxino/build.ninja b/demo/thirdparty/olinuxino/build.ninja
new file mode 100644
index 0000000..f25e6ca
--- /dev/null
+++ b/demo/thirdparty/olinuxino/build.ninja
@@ -0,0 +1,56 @@
+ee = ../../../env/bin/python3 -m ee
+sch = ../../../thirdparty/olinuxino/HARDWARE/A64-OLinuXino/A64-OLinuXino_Rev_D/A64-OlinuXino_Rev_D.sch
+sch_files = $
+ ../../../thirdparty/olinuxino/HARDWARE/A64-OLinuXino/A64-OLinuXino_Rev_D/A64-OlinuXino_Rev_D.sch $
+ ../../../thirdparty/olinuxino/HARDWARE/A64-OLinuXino/A64-OLinuXino_Rev_D/NAND$ Flash$ ,$ eMMC,$ T-Card$ and$ Audio.sch $
+ ../../../thirdparty/olinuxino/HARDWARE/A64-OLinuXino/A64-OLinuXino_Rev_D/Power$ Supply,$ Extensions$ and$ MiPi-DSI$ .sch $
+ ../../../thirdparty/olinuxino/HARDWARE/A64-OLinuXino/A64-OLinuXino_Rev_D/USB&HDMI,WiFi&BT,Ethernet,LCD.sch
+pcb = ../../../thirdparty/olinuxino/HARDWARE/A64-OLinuXino/A64-OLinuXino_Rev_D/A64-OlinuXino_Rev_D.kicad_pcb
+
+rule kicad-gerber
+ description = kicad-gerber
+ command = $ee kicad-gerber $
+ --output-dir $gerber_dir $
+ --pcb $pcb
+# mkdir -p $(
+# (cd $(GERBER_DIR); zip tmp.zip $(foreach GBR,$(GERBERS),$(notdir $(GBR))))
+# mv $(GERBER_DIR)/tmp.zip $@
+
+rule kicad-make-bom
+ description = kicad-make-bom $out_dir
+ command = $ee kicad-make-bom --sch $sch --out $out_dir $strategy
+
+rule part-create-distributor-search-list
+ description = part-create-distributor-search-list distributor=$distributor $in_dir => $out_dir
+ command = $ee part-create-distributor-search-list --in $in_dir --out $out_dir
+
+rule digikey-search-parts
+ description = digikey-search-parts
+ command = $ee digikey-search-parts --in $in_dir --out $out_dir
+
+rule digikey-normalize-facts
+ description = digikey-normalize-facts
+ command = $ee digikey-normalize-facts --in $in_dir --out $out_dir
+
+
+build gerbers: phony prod/gerber.zip
+build prod/gerber.zip: kicad-gerber $pcb
+ gerber_dir = prod
+
+build ee/sch/index.xml: kicad-make-bom $sch
+ out_dir = ee/sch
+ strategy = --strategy olinuxino.make_bom_strategy
+
+build ee/digikey/search-list/index.xml: part-create-distributor-search-list ee/sch/index.xml
+ in_dir = ee/sch
+ out_dir = ee/digikey/search-list
+
+build ee/digikey/downloaded/index.xml: digikey-search-parts ee/digikey/search-list/index.xml
+ in_dir = ee/digikey/search-list
+ out_dir = ee/digikey/downloaded
+
+build ee/digikey/normalized/index.xml: digikey-normalize-facts ee/digikey/downloaded/index.xml
+ in_dir = ee/digikey/downloaded
+ out_dir = ee/digikey/normalized
+
+default ee/digikey/normalized/index.xml
diff --git a/demo/thirdparty/olinuxino/py/olinuxino.py b/demo/thirdparty/olinuxino/py/olinuxino.py
new file mode 100644
index 0000000..cc33a81
--- /dev/null
+++ b/demo/thirdparty/olinuxino/py/olinuxino.py
@@ -0,0 +1,57 @@
+import re
+
+from ee.kicad import Component
+from ee.kicad.make_bom import MakeBomStrategy
+from ee.xml import bomFile
+from ee.xml.bom_file_utils import facts
+
+
+class OlinuxinoMakeBomStrategy(MakeBomStrategy):
+ def process_part(self, component: Component, part: bomFile.Part):
+ print(component.ref)
+ print(" value={}".format(component.value))
+ print(" footprint={}".format(component.footprint))
+
+ if component.ref_type == "C":
+ v = component.value
+
+ if v == "NA":
+ print(" NA".format())
+ return part
+
+ na = v.startswith("NA(") and v.endswith(")")
+ v = v[3:-1] if na else v
+
+ r = re.compile("([0-9]+\\.?[0-9]*[pnum]F)/([0-9]+\\.?[0-9]*[k]?V)/([0-9]+%)(?:/([A-Z][0-9][A-Z]))?")
+
+ m = r.match(v)
+
+ if m:
+ capacitance = m.group(1) + " F"
+ voltage = m.group(2) + " V"
+ tolerance = m.group(3) + "%"
+ derating = m.group(4)
+
+ print(" capacitance {}".format(capacitance))
+ print(" voltage {}".format(voltage))
+ print(" tolerance {}".format(tolerance))
+ if derating:
+ print(" derating {}".format(derating))
+ if na:
+ print(" NA".format())
+
+ fs = facts(part, create=True)
+ fs.add_fact(bomFile.Fact(key="capacitance", value=capacitance))
+ fs.add_fact(bomFile.Fact(key="max_voltage", value=voltage))
+ fs.add_fact(bomFile.Fact(key="tolerance", value=tolerance))
+ if derating:
+ fs.add_fact(bomFile.Fact(key="derating", value=derating))
+
+ else:
+ print("FAIL")
+
+ return part
+
+
+def make_bom_strategy():
+ return OlinuxinoMakeBomStrategy()
diff --git a/src/ee/part/__init__.py b/src/ee/part/__init__.py
index cf60dd5..d4d99ac 100644
--- a/src/ee/part/__init__.py
+++ b/src/ee/part/__init__.py
@@ -81,7 +81,9 @@ def save_db(dir_path: Path, db: PartDb):
idx_path = dir_path / "index.xml"
if not idx_path.is_file():
- raise EeException("The given db directory exists, but does not look like a part db dir")
+ # Ninja creates the parent directories out the output..
+ if len(list(dir_path.iterdir())) > 0:
+ raise EeException("The given db directory exists, but does not look like a part db dir")
for p in dir_path.iterdir():
if not p.is_file():
@@ -100,7 +102,7 @@ def save_db(dir_path: Path, db: PartDb):
for part in parts:
id_ = part.id
- path = dir_path / "{}.xml".format(id_)
+ path = dir_path / "{}.xml".format(id_.replace("/", "_"))
with path.open("w") as f:
part.export(outfile=f, level=0, name_=find_root_tag(part))
diff --git a/src/ee/tools/__init__.py b/src/ee/tools/__init__.py
index 68e3adc..12916ca 100644
--- a/src/ee/tools/__init__.py
+++ b/src/ee/tools/__init__.py
@@ -1,4 +1,5 @@
import os.path
+
from colors import color
@@ -13,7 +14,7 @@ def _mkdir_and_open(path):
def mk_parents(path: str):
- dirname = os.path.dirname(path)
+ dirname = os.path.diŒrname(path)
if len(dirname) == 0:
return
diff --git a/src/ee/tools/ninja.py b/src/ee/tools/ninja.py
new file mode 100644
index 0000000..cc090a0
--- /dev/null
+++ b/src/ee/tools/ninja.py
@@ -0,0 +1,80 @@
+import argparse
+import sys
+from pathlib import Path
+from typing import List, Union, Optional
+
+from jinja2 import Environment, PackageLoader, select_autoescape
+
+from ee.kicad import read_schematics
+
+
+def ninja_path_filter(s: Union[str, List[str]]) -> str:
+ 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: str) -> str:
+ return str(Path(s).parent)
+
+
+def generate(sch_path: Path, kicad_bom_strategy: Optional[str]):
+ 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
+ return e
+
+ gerber_zip = "prod/gerber.zip"
+
+ sch = read_schematics(str(sch_path))
+
+ sch_files = sorted([s.path for s in sch.schematics])
+
+ params = {}
+ import os.path
+ params["ee"] = "{} -m ee".format(os.path.relpath(sys.executable, Path(".")))
+ params["sch"] = sch_path
+ params["sch_files"] = sch_files
+
+ params["kicad_bom_strategy"] = kicad_bom_strategy
+
+ params["pcb"] = str(sch_path).replace(".sch", ".kicad_pcb")
+
+ if gerber_zip is not None:
+ params["gerber_zip"] = gerber_zip
+
+ build_ninja = Path("build.ninja")
+
+ with build_ninja.open("w") as f:
+ env = _create_env()
+ template = env.get_template("build.ninja.j2")
+ f.write(template.render(**params))
+
+
+parser = argparse.ArgumentParser()
+
+parser.add_argument("--sch",
+ required=True,
+ metavar="FILE")
+
+parser.add_argument("--kicad-bom-strategy",
+ required=False,
+ metavar="PY CALLABLE")
+
+args = parser.parse_args()
+
+generate(args.sch, args.kicad_bom_strategy)
diff --git a/src/ee/tools/templates/build.ninja.j2 b/src/ee/tools/templates/build.ninja.j2
new file mode 100644
index 0000000..79a2bc1
--- /dev/null
+++ b/src/ee/tools/templates/build.ninja.j2
@@ -0,0 +1,53 @@
+ee = {{ ee }}
+sch = {{ sch | ninja_path }}
+sch_files = {{ sch_files | ninja_path }}
+pcb = {{ pcb | ninja_path }}
+
+rule kicad-gerber
+ description = kicad-gerber
+ command = $ee kicad-gerber $
+ --output-dir $gerber_dir $
+ --pcb $pcb
+# mkdir -p $(
+# (cd $(GERBER_DIR); zip tmp.zip $(foreach GBR,$(GERBERS),$(notdir $(GBR))))
+# mv $(GERBER_DIR)/tmp.zip $@
+
+rule kicad-make-bom
+ description = kicad-make-bom $out_dir
+ command = $ee kicad-make-bom --sch $sch --out $out_dir $strategy
+
+rule part-create-distributor-search-list
+ description = part-create-distributor-search-list distributor=$distributor $in_dir => $out_dir
+ command = $ee part-create-distributor-search-list --in $in_dir --out $out_dir
+
+rule digikey-search-parts
+ description = digikey-search-parts
+ command = $ee digikey-search-parts --in $in_dir --out $out_dir
+
+rule digikey-normalize-facts
+ description = digikey-normalize-facts
+ command = $ee digikey-normalize-facts --in $in_dir --out $out_dir
+
+{% if gerber_zip is defined %}
+build gerbers: phony {{ gerber_zip }}
+build {{ gerber_zip }}: kicad-gerber $pcb
+ gerber_dir = {{ gerber_zip | parent_dir }}
+{%- endif %}
+
+build ee/sch/index.xml: kicad-make-bom $sch
+ out_dir = ee/sch
+ strategy = {{ "--strategy " + kicad_bom_strategy if kicad_bom_strategy else "" }}
+
+build ee/digikey/search-list/index.xml: part-create-distributor-search-list ee/sch/index.xml
+ in_dir = ee/sch
+ out_dir = ee/digikey/search-list
+
+build ee/digikey/downloaded/index.xml: digikey-search-parts ee/digikey/search-list/index.xml
+ in_dir = ee/digikey/search-list
+ out_dir = ee/digikey/downloaded
+
+build ee/digikey/normalized/index.xml: digikey-normalize-facts ee/digikey/downloaded/index.xml
+ in_dir = ee/digikey/downloaded
+ out_dir = ee/digikey/normalized
+
+default ee/digikey/normalized/index.xml
diff --git a/src/ee/xml/bom_file_utils.py b/src/ee/xml/bom_file_utils.py
index 8ef76e0..d1f8be9 100644
--- a/src/ee/xml/bom_file_utils.py
+++ b/src/ee/xml/bom_file_utils.py
@@ -3,6 +3,7 @@ from typing import List, Optional
from ee.xml import bomFile, indexFile
__all__ = [
+ "facts",
"find_root_tag",
"find_pn",
"find_dpn",