Skip to content

Commit

Permalink
Support project variable in nametemplates
Browse files Browse the repository at this point in the history
  • Loading branch information
yaqwsx committed Oct 17, 2023
1 parent 1a7bcae commit d7b2198
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 3 deletions.
6 changes: 4 additions & 2 deletions docs/fabrication/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ All commands also support the following options:
- `--nametemplate <str>`: If you want to name your files differently, specify
this option. This option takes a string that should contain `{}`. This string
will be replaced by `gerber`, `pos` or `bom` in the out file names. The
extension is appended automatically. [Variables in text](../panelization/cli.md#available-variables-in-text)
are also supported eg: `{boardTitle}_rev{boardRevision}_{date}_{}`.
extension is appended automatically. [Variables in
text](../panelization/cli.md#available-variables-in-text) are also supported
eg: `{boardTitle}_rev{boardRevision}_{date}_{}`. The project variables are
available with the `user-` prefix; e.g., `MFR: {user-mfr}```

Each of the fab command also take additional, manufacturer specific, options.
See documentation for the individual manufacturer below:
Expand Down
3 changes: 2 additions & 1 deletion kikit/fab/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from dataclasses import dataclass
import re
from typing import OrderedDict
from kikit.project import KiCADProject
from pcbnewTransition import pcbnew, isV6, isV7
from math import sin, cos, radians
from kikit.common import *
Expand Down Expand Up @@ -228,7 +229,7 @@ def ensureValidBoard(filename):
def expandNameTemplate(template: str, filetype: str, board: pcbnew.BOARD) -> str:
if re.findall(r"\{.*\}", template) == []:
raise RuntimeError(f"The filename template '{template} must contain at least one variable name")
textVars = kikitTextVars(board)
textVars = kikitTextVars(board, KiCADProject(board.GetFileName()).textVars)
try:
return template.format(filetype, **textVars)
except KeyError as e:
Expand Down
83 changes: 83 additions & 0 deletions kikit/project.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
from typing import Union, Optional, Dict, Any
from pathlib import Path
from string import Template
from functools import cached_property
from pcbnewTransition import pcbnew
import json


class KiCADProject:
"""
This code represents a KiCAD project and allows easy access to individual
files without the need to hassle with project names.
"""
def __init__(self, path: Union[str, Path]) -> None:
self.projectdir: Path = Path(path).resolve()
name = None
if str(path).endswith(".kicad_pro"):
name = self.projectdir.name[:-len(".kicad_pro")]
self.projectdir = self.projectdir.parent
elif str(path).endswith(".kicad_pcb"):
name = self.projectdir.name[:-len(".kicad_pcb")]
self.projectdir = self.projectdir.parent
else:
if not self.projectdir.is_dir():
raise RuntimeError(f"The project directory {self.projectdir} is not a directory")
name = self._resolveProjectName(self.projectdir)
self._name: str = name

@staticmethod
def _resolveProjectName(path: Path) -> str:
candidate: Optional[str] = None
for item in path.iterdir():
if not item.name.endswith(".kicad_pro"):
continue
if candidate is not None:
raise RuntimeError(f"There are multiple projects ({candidate} " +
f"and {item.name}) in directory {path}. Not " +
f"clear which one to choose.")
candidate = item.name
if candidate is not None:
return candidate[:-len(".kicad_pro")]
raise RuntimeError(f"No project found in {path}")

@property
def projectPath(self) -> Path:
return self.projectdir / f"{self._name}.kicad_pro"

@property
def boardPath(self) -> Path:
return self.projectdir / f"{self._name}.kicad_pcb"

@property
def schemaPath(self) -> Path:
return self.projectdir / f"{self._name}.kicad_sch"

@property
def dirPath(self) -> Path:
return self.projectdir

def has(self, file: Union[str, Path]):
return (self.projectdir / file).exists()

def expandText(self, text: str):
"""
Given KiCAD text expand
"""
try:
return Template(text).substitute(self.textVars)
except KeyError as e:
raise RuntimeError(f"Requested text '{text}' expects project variable '{e}' which is missing") from None

@property
def board(self) -> pcbnew.BOARD:
return pcbnew.LoadBoard(str(self.getBoard()))

@cached_property
def projectJson(self) -> Dict[str, Any]:
with open(self.projectPath, "r", encoding="utf-8") as f:
return json.load(f)

@cached_property
def textVars(self) -> Dict[str, str]:
return self.projectJson.get("text_variables", {})

0 comments on commit d7b2198

Please sign in to comment.