Delayed the outputs configuration until last moment.

Now we set the data tree, but only configure the used outputs.
This gives a chance to setup things like the PCB and SCH meta-data.
This commit is contained in:
Salvador E. Tropea 2020-07-22 18:26:12 -03:00
parent a4c0df7fb5
commit 53d840a5b1
12 changed files with 51 additions and 38 deletions

View File

@ -54,7 +54,7 @@ from logging import DEBUG
from . import log
log.set_domain('kiplot')
from .gs import (GS)
from .kiplot import (generate_outputs, load_actions)
from .kiplot import (generate_outputs, load_actions, config_output)
from .pre_base import (BasePreFlight)
from .config_reader import (CfgYamlReader, print_outputs_help, print_output_help, print_preflights_help, create_example)
from .misc import (NO_PCB_FILE, NO_SCH_FILE, EXIT_BAD_ARGS)
@ -74,6 +74,7 @@ def list_pre_and_outs(logger, outputs):
if len(outputs):
logger.info('Outputs:')
for o in outputs:
config_output(o)
logger.info('- '+str(o))

View File

@ -41,14 +41,14 @@ class CfgYamlReader(object):
config_error("Unknown KiPlot config version: "+str(version))
return version
def _parse_output(self, o_obj):
def _parse_output(self, o_tree):
try:
name = o_obj['name']
name = o_tree['name']
except KeyError:
config_error("Output needs a name in: "+str(o_obj))
config_error("Output needs a name in: "+str(o_tree))
try:
otype = o_obj['type']
otype = o_tree['type']
except KeyError:
config_error("Output `"+name+"` needs a type")
@ -60,11 +60,10 @@ class CfgYamlReader(object):
# Load it
logger.debug("Parsing output options for "+name_type)
o_out = RegOutput.get_class_for(otype)()
# Apply the options
try:
o_out.config(o_obj)
except KiPlotConfigurationError as e:
config_error("In section '"+name+"' ("+otype+"): "+str(e))
o_out.set_tree(o_tree)
# Set the data we already know, so we can skip the configurations that aren't requested
o_out.name = name
o_out.type = otype
return o_out

View File

@ -38,8 +38,8 @@ class DrillMarks(AnyLayerOptions):
raise KiPlotConfigurationError("Unknown drill mark type: {}".format(val))
self._drill_marks = val
def config(self, tree):
super().config(tree)
def config(self):
super().config()
self._drill_marks = DrillMarks._drill_marks_map[self._drill_marks]
def _configure_plot_ctrl(self, po, output_dir):

View File

@ -145,6 +145,13 @@ def get_output_dir(o_dir):
return outdir
def config_output(out):
try:
out.config()
except KiPlotConfigurationError as e:
config_error("In section '"+out.name+"' ("+out.type+"): "+str(e))
def generate_outputs(outputs, target, invert, skip_pre):
logger.debug("Starting outputs for board {}".format(GS.pcb_file))
preflight_checks(skip_pre)
@ -158,12 +165,13 @@ def generate_outputs(outputs, target, invert, skip_pre):
board = None
for out in outputs:
if (n == 0) or ((out.name in target) ^ invert):
logger.info('- '+str(out))
# Should we load the PCB?
if out.is_pcb() and (board is None):
board = load_board()
if out.is_sch():
GS.check_sch()
config_output(out)
logger.info('- '+str(out))
try:
out.run(get_output_dir(out.dir), board)
except PlotError as e:

View File

@ -70,10 +70,10 @@ class Layer(Optionable):
""" A description for the layer, for documentation purposes """ # pragma: no cover
self._unkown_is_error = True
def config(self, tree):
super().config(tree)
def config(self):
super().config()
if not self.layer:
raise KiPlotConfigurationError("Missing or empty `layer` attribute for layer entry ({})".format(tree))
raise KiPlotConfigurationError("Missing or empty `layer` attribute for layer entry ({})".format(self._tree))
if not self.description:
if self.layer in Layer.DEFAULT_LAYER_DESC:
self.description = Layer.DEFAULT_LAYER_DESC[self.layer]

View File

@ -117,7 +117,8 @@ class Optionable(object):
# Create an object for the valid class
v = cur_val()
# Delegate the validation to the object
v.config(new_val)
v.set_tree(new_val)
v.config()
elif isinstance(v, list):
new_val = []
for element in v:
@ -127,7 +128,8 @@ class Optionable(object):
format(element, valid, e_type))
if isinstance(element, dict):
nv = cur_val()
nv.config(element)
nv.set_tree(element)
nv.config()
new_val.append(nv)
else:
new_val.append(element)
@ -135,9 +137,11 @@ class Optionable(object):
# Seems to be ok, map it
setattr(self, alias if is_alias else k, v)
def config(self, tree):
def set_tree(self, tree):
self._tree = tree
if tree:
def config(self):
if self._tree:
self._perform_config_mapping()
def get_attrs_for(self):

View File

@ -53,10 +53,10 @@ class AnyDrill(BaseOptions):
'svg': PLOT_FORMAT_SVG,
'pdf': PLOT_FORMAT_PDF
}
self._map_ext = { 'hpgl': 'plt', 'ps': 'ps', 'gerber': 'gbr', 'dxf': 'dxf', 'svg': 'svg', 'pdf': 'pdf' }
self._map_ext = {'hpgl': 'plt', 'ps': 'ps', 'gerber': 'gbr', 'dxf': 'dxf', 'svg': 'svg', 'pdf': 'pdf'}
def config(self, tree):
super().config(tree)
def config(self):
super().config()
# Solve the map for both cases
if isinstance(self.map, str):
self.map_ext = self._map_ext[self.map]

View File

@ -122,8 +122,8 @@ class AnyLayer(BaseOutput):
""" [list(dict)|list(string)|string] [all,selected,copper,technical,user]
List of PCB layers to plot """ # pragma: no cover
def config(self, tree):
super().config(tree)
def config(self):
super().config()
# We need layers
if isinstance(self.layers, type):
raise KiPlotConfigurationError("Missing `layers` list")

View File

@ -37,8 +37,8 @@ class BaseOutput(RegOutput):
""" True for outputs that works on the PCB """
return not self._sch_related
def config(self, tree):
super().config(tree)
def config(self):
super().config()
if getattr(self, 'options', None) and isinstance(self.options, type):
# No options, get the defaults
self.options = self.options()

View File

@ -44,8 +44,8 @@ class PcbDrawStyle(Optionable):
if not self._color_re.match(color):
raise KiPlotConfigurationError('Invalid color for `{}` use `#rrggbb` with hex digits'.format(name))
def config(self, tree):
super().config(tree)
def config(self):
super().config()
self.validate_color('board')
self.validate_color('copper')
self.validate_color('board')
@ -67,8 +67,8 @@ class PcbDrawRemap(Optionable):
def __init__(self):
super().__init__()
def config(self, tree):
self._tree = tree
def config(self):
pass
class PcbDrawOptions(BaseOptions):
@ -105,8 +105,8 @@ class PcbDrawOptions(BaseOptions):
self.output = '%f-%i.%x'
""" name for the generated file """ # pragma: no cover
def config(self, tree):
super().config(tree)
def config(self):
super().config()
# Libs
if isinstance(self.libs, type):
self.libs = None

View File

@ -62,8 +62,8 @@ class PDF_Pcb_Print(BaseOutput): # noqa: F821
""" [list(dict)|list(string)|string] [all,selected,copper,technical,user]
List of PCB layers to include in the PDF """ # pragma: no cover
def config(self, tree):
super().config(tree)
def config(self):
super().config()
# We need layers
if isinstance(self.layers, type):
raise KiPlotConfigurationError("Missing `layers` list")

View File

@ -36,8 +36,8 @@ class FiltersOptions(Optionable):
self.filters = FilterOptions
""" [list(dict)] DRC/ERC errors to be ignored """ # pragma: no cover
def config(self, tree):
super().config(tree)
def config(self):
super().config()
parsed = None
for f in self.filters:
where = ' (in `{}` filter)'.format(f.filter) if f.filter else ''
@ -62,7 +62,8 @@ class Filters(BasePreFlight): # noqa: F821
""" [list(dict)] A list of entries to filter out ERC/DRC messages """
def __init__(self, name, value):
f = FiltersOptions()
f.config({'filters': value})
f.set_tree({'filters': value})
f.config()
super().__init__(name, f.filters)
def get_example():