parent
c35ad9ea0f
commit
1824d56876
|
|
@ -52,7 +52,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
(#103)
|
||||
- A mechanism to avoid running some outputs by default. (#112)
|
||||
- New preflights:
|
||||
- Commands to replace tags in the schematic and PCB. (#93)
|
||||
- Commands to replace tags in the schematic and PCB (KiCad 5). (#93)
|
||||
Also a mechanism to define variables in KiCad 6. (#161)
|
||||
- Annotate power components. (#76)
|
||||
- Annotate according to PCB coordinates (#93)
|
||||
- Now you can compress files relative to the current working directory.
|
||||
|
|
|
|||
|
|
@ -173,6 +173,9 @@ This section is used to specify tasks that will be executed before generating an
|
|||
- `tag_delimiter`: [string='@'] Character used to indicate the beginning and the end of a tag.
|
||||
Don't change it unless you really know about KiCad's file formats.
|
||||
- `text`: [string=''] Text to insert instead of the tag.
|
||||
- `set_text_variables`: [dict|list(dict)] Defines KiCad 6 variables.
|
||||
They are expanded using ${VARIABLE}, and stored in the project file.
|
||||
This preflight replaces `pcb_replace` and `sch_replace` when using KiCad 6.
|
||||
- `update_qr`: [boolean=false] Update the QR codes.
|
||||
Complements the `qr_lib` output.
|
||||
The KiCad 6 files and the KiCad 5 PCB needs manual update, generating a new library isn't enough.
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ preflight:
|
|||
command: 'git log -1 --format="%h" $KIBOT_PCB_NAME'
|
||||
before: 'Git hash: <'
|
||||
after: '>'
|
||||
|
||||
# [boolean=false] Runs the DRC (Distance Rules Check). To ensure we have a valid PCB.
|
||||
# The report file name is controlled by the global output pattern (%i=drc %x=txt).
|
||||
run_drc: true
|
||||
|
|
@ -61,7 +60,14 @@ preflight:
|
|||
command: 'git log -1 --format="%h" $KIBOT_SCH_NAME'
|
||||
before: 'Git hash: <'
|
||||
after: '>'
|
||||
|
||||
# [dict|list(dict)] Defines KiCad 6 variables.
|
||||
# They are expanded using ${VARIABLE}, and stored in the project file.
|
||||
# This preflight replaces `pcb_replace` and `sch_replace` when using KiCad 6.
|
||||
set_text_variables:
|
||||
- name: 'git_hash'
|
||||
command: 'git log -1 --format="%h" $KIBOT_PCB_NAME'
|
||||
before: 'Git hash: <'
|
||||
after: '>'
|
||||
# [boolean=false] Update the QR codes.
|
||||
# Complements the `qr_lib` output.
|
||||
# The KiCad 6 files and the KiCad 5 PCB needs manual update, generating a new library isn't enough.
|
||||
|
|
|
|||
|
|
@ -145,8 +145,8 @@ def solve_schematic(a_schematic, a_board_file, config):
|
|||
# Look for a schematic with a PCB and/or project
|
||||
for sch in schematics:
|
||||
base = os.path.splitext(sch)[0]
|
||||
if os.path.isfile(base+'.pro') or os.path.isfile(base+'.kicad_pro') or \
|
||||
os.path.isfile(base+'.kicad_pcb'):
|
||||
if (os.path.isfile(base+'.pro') or os.path.isfile(base+'.kicad_pro') or
|
||||
os.path.isfile(base+'.kicad_pcb')):
|
||||
schematic = sch
|
||||
break
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ class Base_Replace(BasePreFlight): # noqa: F821
|
|||
"\n - tag: '@git_hash@'"
|
||||
"\n command: 'git log -1 --format=\"%h\" $KIBOT_{}_NAME'"
|
||||
"\n before: 'Git hash: <'"
|
||||
"\n after: '>'\n".format(cls._context, cls._context))
|
||||
"\n after: '>'".format(cls._context, cls._context))
|
||||
|
||||
def replace(self, file):
|
||||
logger.debug('Applying replacements to `{}`'.format(file))
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ class PCB_ReplaceOptions(Base_ReplaceOptions):
|
|||
@pre_class
|
||||
class PCB_Replace(Base_Replace): # noqa: F821
|
||||
""" [dict] Replaces tags in the schematic. I.e. to insert the git hash or last revision date.
|
||||
This is useful for KiCad 5, use `set_text_variables` when using KiCad 6.
|
||||
This pre-flight modifies the PCB. Even when a back-up is done use it carefully """
|
||||
_context = 'PCB'
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ class SCH_ReplaceOptions(Base_ReplaceOptions):
|
|||
@pre_class
|
||||
class SCH_Replace(Base_Replace): # noqa: F821
|
||||
""" [dict] Replaces tags in the schematic. I.e. to insert the git hash or last revision date.
|
||||
This is useful for KiCad 5, use `set_text_variables` when using KiCad 6.
|
||||
This pre-flight modifies the schematics. Even when a back-up is done use it carefully """
|
||||
_context = 'SCH'
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,122 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2022 Salvador E. Tropea
|
||||
# Copyright (c) 2022 Instituto Nacional de Tecnología Industrial
|
||||
# License: GPL-3.0
|
||||
# Project: KiBot (formerly KiPlot)
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
from subprocess import run, PIPE
|
||||
from .error import KiPlotConfigurationError
|
||||
from .misc import FAILED_EXECUTE, W_EMPTREP
|
||||
from .optionable import Optionable
|
||||
from .pre_base import BasePreFlight
|
||||
from .gs import GS
|
||||
from .macros import macros, document, pre_class # noqa: F401
|
||||
from . import log
|
||||
|
||||
logger = log.get_logger()
|
||||
|
||||
|
||||
class KiCadVariable(Optionable):
|
||||
""" KiCad variable definition """
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._unkown_is_error = True
|
||||
with document:
|
||||
self.name = ''
|
||||
""" Name of the variable. The `version` variable will be expanded using `${version}` """
|
||||
self.variable = None
|
||||
""" {name} """
|
||||
self.text = ''
|
||||
""" Text to insert instead of the variable """
|
||||
self.command = ''
|
||||
""" Command to execute to get the text, will be used only if `text` is empty """
|
||||
self.before = ''
|
||||
""" Text to add before the output of `command` """
|
||||
self.after = ''
|
||||
""" Text to add after the output of `command` """
|
||||
|
||||
def config(self, parent):
|
||||
super().config(parent)
|
||||
if not self.name:
|
||||
raise KiPlotConfigurationError("Missing variable name ({})".format(str(self._tree)))
|
||||
|
||||
|
||||
class Set_Text_VariablesOptions(Optionable):
|
||||
""" A list of KiCad variables """
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
with document:
|
||||
self.variables = KiCadVariable
|
||||
""" [dict|list(dict)] Variables """
|
||||
|
||||
def config(self, parent):
|
||||
super().config(parent)
|
||||
if isinstance(self.variables, type):
|
||||
self.variables = []
|
||||
elif isinstance(self.variables, KiCadVariable):
|
||||
self.variables = [self.variables]
|
||||
|
||||
|
||||
@pre_class
|
||||
class Set_Text_Variables(BasePreFlight): # noqa: F821
|
||||
""" [dict|list(dict)] Defines KiCad 6 variables.
|
||||
They are expanded using ${VARIABLE}, and stored in the project file.
|
||||
This preflight replaces `pcb_replace` and `sch_replace` when using KiCad 6 """
|
||||
def __init__(self, name, value):
|
||||
f = Set_Text_VariablesOptions()
|
||||
f.set_tree({'variables': value})
|
||||
f.config(self)
|
||||
super().__init__(name, f.variables)
|
||||
|
||||
@classmethod
|
||||
def get_example(cls):
|
||||
""" Returns a YAML value for the example config """
|
||||
return ("\n - name: 'git_hash'"
|
||||
"\n command: 'git log -1 --format=\"%h\" $KIBOT_PCB_NAME'"
|
||||
"\n before: 'Git hash: <'"
|
||||
"\n after: '>'")
|
||||
|
||||
def apply(self):
|
||||
o = self._value
|
||||
if len(o) == 0:
|
||||
return
|
||||
if GS.ki5():
|
||||
raise KiPlotConfigurationError("The `set_text_variables` preflight is for KiCad 6 or newer")
|
||||
pro_name = GS.pcb_file.replace('.kicad_pcb', GS.pro_ext)
|
||||
if not os.path.isfile(pro_name):
|
||||
raise KiPlotConfigurationError("Trying to define KiCad 6 variables but the project is missing ({})".
|
||||
format(pro_name))
|
||||
# Get the current definitions
|
||||
with open(pro_name, 'rt') as f:
|
||||
pro_text = f.read()
|
||||
data = json.loads(pro_text)
|
||||
text_variables = data.get('text_variables', {})
|
||||
logger.debug("- Current variables: {}".format(text_variables))
|
||||
# Define the requested variables
|
||||
os.environ['KIBOT_PCB_NAME'] = GS.pcb_file
|
||||
os.environ['KIBOT_SCH_NAME'] = GS.sch_file
|
||||
for r in o:
|
||||
text = r.text
|
||||
if not text:
|
||||
cmd = ['/bin/bash', '-c', r.command]
|
||||
result = run(cmd, stdout=PIPE, stderr=PIPE, universal_newlines=True)
|
||||
if result.returncode:
|
||||
logger.error('Failed to execute:\n{}\nreturn code {}'.format(r.command, result.returncode))
|
||||
sys.exit(FAILED_EXECUTE)
|
||||
if not result.stdout:
|
||||
logger.warning(W_EMPTREP+"Empty value from `{}` skipping it".format(r.command))
|
||||
continue
|
||||
text = result.stdout.strip()
|
||||
text = r.before + text + r.after
|
||||
logger.debug(' - ' + r.name + ' -> ' + text)
|
||||
text_variables[r.name] = text
|
||||
logger.debug("- New list of variables: {}".format(text_variables))
|
||||
# Store the modified project
|
||||
data['text_variables'] = text_variables
|
||||
GS.make_bkp(pro_name)
|
||||
with open(pro_name, 'wt') as f:
|
||||
f.write(json.dumps(data, sort_keys=True, indent=2))
|
||||
# Force the PCB reload (will reload the project file)
|
||||
GS.board = None
|
||||
|
|
@ -48,7 +48,13 @@
|
|||
"min_clearance": 0.508
|
||||
}
|
||||
},
|
||||
"diff_pair_dimensions": [],
|
||||
"diff_pair_dimensions": [
|
||||
{
|
||||
"gap": 0.0,
|
||||
"via_gap": 0.0,
|
||||
"width": 0.0
|
||||
}
|
||||
],
|
||||
"drc_exclusions": [],
|
||||
"meta": {
|
||||
"filename": "board_design_settings.json",
|
||||
|
|
@ -207,5 +213,7 @@
|
|||
"legacy_lib_list": []
|
||||
},
|
||||
"sheets": [],
|
||||
"text_variables": {}
|
||||
}
|
||||
"text_variables": {
|
||||
"PRUEBITA": "Hola!"
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ import os
|
|||
import sys
|
||||
import logging
|
||||
import re
|
||||
import json
|
||||
from subprocess import run, PIPE
|
||||
# Look for the 'utils' module from where the script is running
|
||||
prev_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
|
@ -231,3 +232,26 @@ def test_pcb_replace_1(test_dir):
|
|||
assert m.group(1) == text
|
||||
finally:
|
||||
os.rename(file_back, file)
|
||||
|
||||
|
||||
def test_set_text_variables_1(test_dir):
|
||||
""" KiCad 6 variables """
|
||||
prj = 'light_control'
|
||||
ctx = context.TestContext(test_dir, 'test_set_text_variables_1', prj, 'set_text_variables_1', '')
|
||||
ctx.run(extra=[])
|
||||
file = os.path.join(ctx.get_board_dir(), ctx.board_name+context.PRO_EXT)
|
||||
file_back = file + '-bak'
|
||||
assert os.path.isfile(file_back), file_back
|
||||
assert os.path.getsize(file_back) > 0
|
||||
try:
|
||||
logging.debug(file)
|
||||
cmd = ['/bin/bash', '-c', "git log -1 --format='%h' " + ctx.board_file]
|
||||
text = "Git_hash:'" + run(cmd, stdout=PIPE, stderr=PIPE, universal_newlines=True).stdout.strip() + "'"
|
||||
with open(file, 'rt') as f:
|
||||
c = f.read()
|
||||
data = json.loads(c)
|
||||
assert 'text_variables' in data
|
||||
assert 'Comment4' in data['text_variables']
|
||||
assert data['text_variables']['Comment4'] == text
|
||||
finally:
|
||||
os.rename(file_back, file)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
# Example KiBot config file
|
||||
kibot:
|
||||
version: 1
|
||||
|
||||
preflight:
|
||||
set_text_variables:
|
||||
- variable: "Comment4"
|
||||
command: git log -1 --format="%h" $KIBOT_PCB_NAME
|
||||
before: "Git_hash:'"
|
||||
after: "'"
|
||||
Loading…
Reference in New Issue