Now the docstring for string options can specify a list of allowed values

This reduces the number of setters/getters we need to write.
On the other side the time to validate the YAML is increased.
This commit is contained in:
Salvador E. Tropea 2020-07-02 09:25:06 -03:00
parent ec35d2443f
commit 1ca21efe94
8 changed files with 54 additions and 76 deletions

View File

@ -289,7 +289,7 @@ Most options are the same you'll find in the KiCad dialogs.
- `blacklist`: [string=''] List of comma separated blacklisted components or prefixes with *. E.g. 'X1,MH*'.
- `blacklist_empty_val`: [boolean=false] Blacklist components with empty value.
- `board_rotation`: [number=0] Board rotation in degrees (-180 to 180). Will be rounded to multiple of 5.
- `bom_view`: [string='left-right'] Default BOM view {bom-only,left-right,top-bottom}.
- `bom_view`: [string='left-right'] [bom-only,left-right,top-bottom] Default BOM view.
- `checkboxes`: [string='Sourced,Placed'] Comma separated list of checkbox columns.
- `dark_mode`: [boolean=false] Default to dark mode.
- `dnp_field`: [string=''] Name of the extra field that indicates do not populate status. Components with this field not empty will be
@ -300,7 +300,7 @@ Most options are the same you'll find in the KiCad dialogs.
- `highlight_pin1`: [boolean=false] Highlight pin1 by default.
- `include_nets`: [boolean=false] Include netlist information in output..
- `include_tracks`: [boolean=false] Include track/zone information in output. F.Cu and B.Cu layers only.
- `layer_view`: [string='FB'] Default layer view {F,FB,B}.
- `layer_view`: [string='FB'] [F,FB,B] Default layer view.
- `name_format`: [string='ibom'] Output file name format supports substitutions:
%f : original pcb file name without extension.
%p : pcb/project title from pcb metadata.
@ -325,7 +325,7 @@ Most options are the same you'll find in the KiCad dialogs.
For more information: https://github.com/INTI-CMNB/KiBoM
This output is what you get from the 'Tools/Generate Bill of Materials' menu in eeschema.
* Options:
- `format`: [string='HTML'] can be `HTML` or `CSV`.
- `format`: [string='HTML'] [HTML,CSV] format for the BoM.
* PDF (Portable Document Format)
* Type: `pdf`
@ -366,10 +366,10 @@ Most options are the same you'll find in the KiCad dialogs.
* Description: Generates the file with position information for the PCB components, used by the pick and place machine.
This output is what you get from the 'File/Fabrication output/Footprint poistion (.pos) file' menu in pcbnew.
* Options:
- `format`: [string='ASCII'] can be ASCII or CSV.
- `format`: [string='ASCII'] [ASCII,CSV] format for the position file.
- `only_smd`: [boolean=true] only include the surface mount components.
- `separate_files_for_front_and_back`: [boolean=true] generate two separated files, one for the top and another for the bottom.
- `units`: [string='millimeters'] can be millimeters or inches.
- `units`: [string='millimeters'] [millimeters,inches] units used for the positions.
* PS (Postscript)
* Type: `ps`

View File

@ -363,7 +363,7 @@ outputs:
blacklist_empty_val: false
# [number=0] Board rotation in degrees (-180 to 180). Will be rounded to multiple of 5
board_rotation: 0
# [string='left-right'] Default BOM view {bom-only,left-right,top-bottom}
# [string='left-right'] [bom-only,left-right,top-bottom] Default BOM view
bom_view: 'left-right'
# [string='Sourced,Placed'] Comma separated list of checkbox columns
checkboxes: 'Sourced,Placed'
@ -384,7 +384,7 @@ outputs:
include_nets: false
# [boolean=false] Include track/zone information in output. F.Cu and B.Cu layers only
include_tracks: false
# [string='FB'] Default layer view {F,FB,B}
# [string='FB'] [F,FB,B] Default layer view
layer_view: 'FB'
# [string='ibom'] Output file name format supports substitutions:
# %f : original pcb file name without extension.
@ -422,7 +422,7 @@ outputs:
type: 'kibom'
dir: 'Example/kibom_dir'
options:
# [string='HTML'] can be `HTML` or `CSV`
# [string='HTML'] [HTML,CSV] format for the BoM
format: 'HTML'
# PDF (Portable Document Format):
@ -607,13 +607,13 @@ outputs:
type: 'position'
dir: 'Example/position_dir'
options:
# [string='ASCII'] can be ASCII or CSV
# [string='ASCII'] [ASCII,CSV] format for the position file
format: 'ASCII'
# [boolean=true] only include the surface mount components
only_smd: true
# [boolean=true] generate two separated files, one for the top and another for the bottom
separate_files_for_front_and_back: true
# [string='millimeters'] can be millimeters or inches
# [string='millimeters'] [millimeters,inches] units used for the positions
units: 'millimeters'
# PS (Postscript):

View File

@ -23,6 +23,7 @@ class BaseOutput(object):
""" Map the options to class attributes """
attrs = BaseOutput.get_attrs_for(self)
num_range_re = compile(r"\[number=.*\] \[(-?\d+),(-?\d+)\]")
str_values_re = compile(r"\[string=.*\] \[([^\]]+)\]")
for k, v in self._options.items():
# Map known attributes and avoid mapping private ones
if (k[0] == '_') or (k not in attrs):
@ -42,7 +43,6 @@ class BaseOutput(object):
# If the docstring specifies a range in the form [from-to] enforce it
m = num_range_re.match(cur_doc)
if m:
logger.debug('Verificando')
min = float(m.group(1))
max = float(m.group(2))
if v < min or v > max:
@ -50,6 +50,12 @@ class BaseOutput(object):
elif isinstance(cur_val, str):
if not isinstance(v, str):
raise KiPlotConfigurationError("Option `{}` must be a string".format(k))
# If the docstring specifies the allowed values in the form [v1,v2...] enforce it
m = str_values_re.match(cur_doc)
if m:
vals = m.group(1).split(',')
if v not in vals:
raise KiPlotConfigurationError("Option `{}` must be any of {}".format(k, vals))
elif isinstance(v, list):
raise KiPlotConfigurationError("list not yet supported for `{}`".format(k))
# Seems to be ok, map it

View File

@ -3,7 +3,6 @@ from subprocess import (check_output, STDOUT, CalledProcessError)
from .misc import (CMD_IBOM, URL_IBOM, BOM_ERROR)
from .gs import (GS)
from .kiplot import (check_script)
from .error import KiPlotConfigurationError
from kiplot.macros import macros, document, output_class # noqa: F401
from . import log
@ -37,10 +36,10 @@ class IBoM(BaseOutput): # noqa: F821
""" Board rotation in degrees (-180 to 180). Will be rounded to multiple of 5 """
self.checkboxes = 'Sourced,Placed'
""" Comma separated list of checkbox columns """
self._bom_view = 'left-right'
""" Default BOM view {bom-only,left-right,top-bottom} """
self._layer_view = 'FB'
""" Default layer view {F,FB,B} """
self.bom_view = 'left-right'
""" [bom-only,left-right,top-bottom] Default BOM view """
self.layer_view = 'FB'
""" [F,FB,B] Default layer view """
self.name_format = 'ibom'
""" Output file name format supports substitutions:
%f : original pcb file name without extension.
@ -78,28 +77,6 @@ class IBoM(BaseOutput): # noqa: F821
""" Name of the extra field that indicates do not populate status. Components with this field not empty will be
blacklisted """ # pragma: no cover
@property
def bom_view(self):
return self._bom_view
@bom_view.setter
def bom_view(self, val):
valid = ['bom-only', 'left-right', 'top-bottom']
if val not in valid:
raise KiPlotConfigurationError("`bom_view` must be any of "+str(valid))
self._bom_view = val
@property
def layer_view(self):
return self._layer_view
@layer_view.setter
def layer_view(self, val):
valid = ['F', 'FB', 'B']
if val not in valid:
raise KiPlotConfigurationError("`layer_view` must be any of "+str(valid))
self._layer_view = val
def run(self, output_dir, board):
check_script(CMD_IBOM, URL_IBOM)
logger.debug('Doing Interactive BoM')

View File

@ -1,7 +1,6 @@
import os
from glob import (glob)
from subprocess import (check_output, STDOUT, CalledProcessError)
from .error import KiPlotConfigurationError
from .misc import (CMD_KIBOM, URL_KIBOM, BOM_ERROR)
from .kiplot import (check_script)
from .gs import (GS)
@ -22,18 +21,8 @@ class KiBoM(BaseOutput): # noqa: F821
self._sch_related = True
# Options
with document:
self._format = 'HTML'
""" can be `HTML` or `CSV` """ # pragma: no cover
@property
def format(self):
return self._format
@format.setter
def format(self, val):
if val not in ['HTML', 'CSV']:
raise KiPlotConfigurationError("`format` must be either `HTML` or `CSV`")
self._format = val
self.format = 'HTML'
""" [HTML,CSV] format for the BoM """ # pragma: no cover
def run(self, output_dir, board):
check_script(CMD_KIBOM, URL_KIBOM)

View File

@ -2,7 +2,6 @@ import os
import operator
from datetime import datetime
from pcbnew import (IU_PER_MM, IU_PER_MILS)
from .error import KiPlotConfigurationError
from kiplot.macros import macros, document, output_class # noqa: F401
@ -15,34 +14,14 @@ class Position(BaseOutput): # noqa: F821
super(Position, self).__init__(name, type, description)
# Options
with document:
self._format = 'ASCII'
""" can be ASCII or CSV """
self.format = 'ASCII'
""" [ASCII,CSV] format for the position file """
self.separate_files_for_front_and_back = True
""" generate two separated files, one for the top and another for the bottom """
self.only_smd = True
""" only include the surface mount components """
self._units = 'millimeters'
""" can be millimeters or inches """ # pragma: no cover
@property
def format(self):
return self._format
@format.setter
def format(self, val):
if val not in ['ASCII', 'CSV']:
raise KiPlotConfigurationError("`format` must be either `ASCII` or `CSV`")
self._format = val
@property
def units(self):
return self._units
@units.setter
def units(self, val):
if val not in ['millimeters', 'inches']:
raise KiPlotConfigurationError("`units` must be either `millimeters` or `inches`")
self._units = val
self.units = 'millimeters'
""" [millimeters,inches] units used for the positions """ # pragma: no cover
def _do_position_plot_ascii(self, board, output_dir, columns, modulesStr, maxSizes):
name = os.path.splitext(os.path.basename(board.GetFileName()))[0]

View File

@ -37,6 +37,7 @@ Tests various errors in the config file
- YAML syntax
- Unknown section
- HPGL wrong pen_number
- KiBoM wrong format
For debug information use:
pytest-3 --log-cli-level debug
@ -328,3 +329,10 @@ def test_error_hpgl_pen_num():
ctx.run(EXIT_BAD_CONFIG)
assert ctx.search_err("Option .?pen_number.? outside its range")
ctx.clean_up()
def test_error_bom_wrong_format():
ctx = context.TestContext('BoMWrongFormat', PRJ, 'error_bom_wrong_format', '')
ctx.run(EXIT_BAD_CONFIG)
assert ctx.search_err("Option .?format.? must be any of")
ctx.clean_up()

View File

@ -0,0 +1,19 @@
# Example KiPlot config file
kiplot:
version: 1
outputs:
- name: 'bom_html'
comment: "Bill of Materials in HTML format"
type: kibom
dir: BoM
options:
format: HTM # HTML or CSV
- name: 'bom_csv'
comment: "Bill of Materials in CSV format"
type: kibom
dir: BoM
options:
format: CSV # HTML or CSV