Added the basic infraestructure for variants.

Now variants are defined separately so we can apply the variants for
more than one output.
It will also allow different variant semantics.
This commit is contained in:
Salvador E. Tropea 2020-08-28 16:46:24 -03:00
parent ab8550796d
commit 3be45edf07
8 changed files with 144 additions and 59 deletions

View File

@ -17,7 +17,7 @@ from .error import (KiPlotConfigurationError, config_error)
from .kiplot import (load_board)
from .misc import (NO_YAML_MODULE, EXIT_BAD_ARGS, EXAMPLE_CFG, WONT_OVERWRITE)
from .gs import GS
from .reg_out import RegOutput
from .registrable import RegOutput, RegVariant
from .pre_base import BasePreFlight
# Logger
@ -80,6 +80,50 @@ class CfgYamlReader(object):
return o_out
def _parse_outputs(self, v):
outputs = []
if isinstance(v, list):
for o in v:
outputs.append(self._parse_output(o))
else:
config_error("`outputs` must be a list")
return outputs
def _parse_variant(self, o_tree):
try:
name = o_tree['name']
if not name:
raise KeyError
except KeyError:
config_error("Variant needs a name in: "+str(o_tree))
try:
otype = o_tree['type']
except KeyError:
config_error("Variant `"+name+"` needs a type")
# Is a valid type?
if not RegVariant.is_registered(otype):
config_error("Unknown variant type: `{}`".format(otype))
# Load it
name_type = "`"+name+"` ("+otype+")"
logger.debug("Parsing variant "+name_type)
o_var = RegVariant.get_class_for(otype)()
o_var.set_tree(o_tree)
try:
o_var.config()
except KiPlotConfigurationError as e:
config_error("In section `"+name_type+"`: "+str(e))
return o_var
def _parse_variants(self, v):
variants = {}
if isinstance(v, list):
for o in v:
o_var = self._parse_variant(o)
variants[o_var.name] = o_var
else:
config_error("`variants` must be a list")
return variants
def _parse_preflight(self, pf):
logger.debug("Parsing preflight options: {}".format(pf))
if not isinstance(pf, dict):
@ -131,12 +175,10 @@ class CfgYamlReader(object):
self._parse_preflight(v)
elif k == 'global':
self._parse_global(v)
elif k == 'variants':
RegOutput.set_variants(self._parse_variants(v))
elif k == 'outputs':
if isinstance(v, list):
for o in v:
outputs.append(self._parse_output(o))
else:
config_error("`outputs` must be a list")
outputs = self._parse_outputs(v)
else:
config_error('Unknown section `{}` in config.'.format(k))
if version is None:

View File

@ -56,7 +56,7 @@ def _import(name, path):
def _load_actions(path):
logger.debug("Importing from "+path)
lst = glob(os.path.join(path, 'out_*.py')) + glob(os.path.join(path, 'pre_*.py'))
lst = glob(os.path.join(path, 'out_*.py')) + glob(os.path.join(path, 'pre_*.py')) + glob(os.path.join(path, 'var_*.py'))
for p in lst:
name = os.path.splitext(os.path.basename(p))[0]
logger.debug("- Importing "+name)

View File

@ -122,6 +122,17 @@ def output_class(tree, **kw):
return _do_wrap_class_register(tree, 'out_base', 'BaseOutput')
def variant_class(tree, **kw):
"""A decorator to wrap a class with:
from .var_base import BaseVariant
... Class definition
BaseVariant.register(CLASS_NAME_LOWER_STRING, CLASS_NAME)
Allowing to register the class as a variant. """
return _do_wrap_class_register(tree, 'var_base', 'BaseVariant')
def pre_class(tree, **kw):
"""A decorator to wrap a class with:

View File

@ -3,7 +3,7 @@
# Copyright (c) 2020 Instituto Nacional de Tecnología Industrial
# License: GPL-3.0
# Project: KiBot (formerly KiPlot)
from .reg_out import RegOutput
from .registrable import RegOutput
from .macros import macros, document # noqa: F401
from . import log
@ -11,8 +11,6 @@ logger = log.get_logger(__name__)
class BaseOutput(RegOutput):
_registered = {}
def __init__(self):
super().__init__()
with document:

View File

@ -3,40 +3,26 @@
# Copyright (c) 2020 Instituto Nacional de Tecnología Industrial
# License: GPL-3.0
# Project: KiBot (formerly KiPlot)
from .gs import (GS)
from .log import (get_logger)
from .gs import GS
from .registrable import Registrable
from .log import get_logger
logger = get_logger(__name__)
class BasePreFlight(object):
class BasePreFlight(Registrable):
_registered = {}
_in_use = {}
_options = {}
def __init__(self, name, value):
super().__init__()
self._value = value
self._name = name
self._sch_related = False
self._pcb_related = False
self._enabled = True
@staticmethod
def register(name, aclass):
BasePreFlight._registered[name] = aclass
@staticmethod
def is_registered(name):
return name in BasePreFlight._registered
@staticmethod
def get_registered():
return BasePreFlight._registered
@staticmethod
def get_class_for(name):
return BasePreFlight._registered[name]
@staticmethod
def add_preflight(o_pre):
BasePreFlight._in_use[o_pre._name] = o_pre

View File

@ -1,30 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 Salvador E. Tropea
# Copyright (c) 2020 Instituto Nacional de Tecnología Industrial
# License: GPL-3.0
# Project: KiBot (formerly KiPlot)
from .optionable import Optionable
class RegOutput(Optionable):
""" This class adds the mechanism to register outputs """
_registered = {}
def __init__(self):
super().__init__()
@staticmethod
def register(name, aclass):
RegOutput._registered[name] = aclass
@staticmethod
def is_registered(name):
return name in RegOutput._registered
@staticmethod
def get_class_for(name):
return RegOutput._registered[name]
@staticmethod
def get_registered():
return RegOutput._registered

54
kibot/registrable.py Normal file
View File

@ -0,0 +1,54 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 Salvador E. Tropea
# Copyright (c) 2020 Instituto Nacional de Tecnología Industrial
# License: GPL-3.0
# Project: KiBot (formerly KiPlot)
from .optionable import Optionable
class Registrable(object):
""" This class adds the mechanism to register plug-ins """
def __init__(self):
super().__init__()
@classmethod
def register(cl, name, aclass):
cl._registered[name] = aclass
@classmethod
def is_registered(cl, name):
return name in cl._registered
@classmethod
def get_class_for(cl, name):
return cl._registered[name]
@classmethod
def get_registered(cl):
return cl._registered
class RegOutput(Optionable, Registrable):
""" An optionable that is also registrable.
Used by BaseOutput.
Here because it doesn't need macros. """
_registered = {}
# List of defined variants
_def_variants = {}
def __init__(self):
super().__init__()
@staticmethod
def set_variants(variants):
RegOutput._def_variants = variants
class RegVariant(Optionable, Registrable):
""" An optionable that is also registrable.
Used by BaseVariant.
Here because it doesn't need macros. """
_registered = {}
def __init__(self):
super().__init__()

24
kibot/var_base.py Normal file
View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 Salvador E. Tropea
# Copyright (c) 2020 Instituto Nacional de Tecnología Industrial
# License: GPL-3.0
# Project: KiBot (formerly KiPlot)
from .registrable import RegVariant
from .macros import macros, document # noqa: F401
class BaseVariant(RegVariant):
def __init__(self):
super().__init__()
with document:
self.name = ''
""" Used to identify this particular variant definition """
self.type = ''
""" Type of variant """
self.comment = ''
""" A comment for documentation purposes """
self.file_id = ''
""" Text to use as the """
def __str__(self):
return "'{}' ({}) [{}]".format(self.comment, self.name, self.type)