Added import for globals.

This commit is contained in:
Salvador E. Tropea 2021-12-02 10:33:19 -03:00
parent 5291af250c
commit 6392124f9f
8 changed files with 85 additions and 10 deletions

View File

@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- skip_top: top components aren't rotated. - skip_top: top components aren't rotated.
- skip_bottom: bottom components aren't rotated. - skip_bottom: bottom components aren't rotated.
- XLSX BoM: option to control the logo scale (#84) - XLSX BoM: option to control the logo scale (#84)
- Import mechanism for filters and variants (#88) - Import mechanism for filters, variants and globals (#88)
- PDF PCB Print: option `hide_excluded` to hide components marked by the - PDF PCB Print: option `hide_excluded` to hide components marked by the
`exclude_filter`. `exclude_filter`.
https://forum.kicad.info/t/fab-drawing-for-only-through-hole-parts/ https://forum.kicad.info/t/fab-drawing-for-only-through-hole-parts/

View File

@ -1877,9 +1877,10 @@ import:
outputs: LIST_OF_OUTPUTS outputs: LIST_OF_OUTPUTS
filters: LIST_OF_FILTERS filters: LIST_OF_FILTERS
variants: LIST_OF_VARIANTS variants: LIST_OF_VARIANTS
global: LIST_OF_GLOBALS
``` ```
This syntax is flexible. If you don't define which `outputs`, `filters` and/or `variants` all will be imported. So you can just omit them, like this: This syntax is flexible. If you don't define which `outputs`, `filters`, `variants` and/or `global` all will be imported. So you can just omit them, like this:
```yaml ```yaml
import: import:
@ -1904,9 +1905,11 @@ import:
outputs: all outputs: all
filters: all filters: all
variants: none variants: none
global: none
``` ```
This will import all outputs and filters, but not variants. This will import all outputs and filters, but not variants or globals.
Also note that imported globals has more precendence than the ones defined in the same file.
## Usage ## Usage

View File

@ -817,9 +817,10 @@ import:
outputs: LIST_OF_OUTPUTS outputs: LIST_OF_OUTPUTS
filters: LIST_OF_FILTERS filters: LIST_OF_FILTERS
variants: LIST_OF_VARIANTS variants: LIST_OF_VARIANTS
global: LIST_OF_GLOBALS
``` ```
This syntax is flexible. If you don't define which `outputs`, `filters` and/or `variants` all will be imported. So you can just omit them, like this: This syntax is flexible. If you don't define which `outputs`, `filters`, `variants` and/or `global` all will be imported. So you can just omit them, like this:
```yaml ```yaml
import: import:
@ -844,9 +845,11 @@ import:
outputs: all outputs: all
filters: all filters: all
variants: none variants: none
global: none
``` ```
This will import all outputs and filters, but not variants. This will import all outputs and filters, but not variants or globals.
Also note that imported globals has more precendence than the ones defined in the same file.
## Usage ## Usage

View File

@ -16,7 +16,7 @@ from collections import OrderedDict
from .error import (KiPlotConfigurationError, config_error) from .error import (KiPlotConfigurationError, config_error)
from .kiplot import (load_board) from .kiplot import (load_board)
from .misc import (NO_YAML_MODULE, EXIT_BAD_ARGS, EXAMPLE_CFG, WONT_OVERWRITE, W_NOOUTPUTS, W_UNKOUT, W_NOFILTERS, from .misc import (NO_YAML_MODULE, EXIT_BAD_ARGS, EXAMPLE_CFG, WONT_OVERWRITE, W_NOOUTPUTS, W_UNKOUT, W_NOFILTERS,
W_NOVARIANTS) W_NOVARIANTS, W_NOGLOBALS)
from .gs import GS from .gs import GS
from .registrable import RegOutput, RegVariant, RegFilter from .registrable import RegOutput, RegVariant, RegFilter
from .pre_base import BasePreFlight from .pre_base import BasePreFlight
@ -37,6 +37,7 @@ except ImportError:
class CfgYamlReader(object): class CfgYamlReader(object):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.imported_globals = {}
def _check_version(self, v): def _check_version(self, v):
if not isinstance(v, dict): if not isinstance(v, dict):
@ -164,6 +165,9 @@ class CfgYamlReader(object):
logger.debug("Parsing global options: {}".format(gb)) logger.debug("Parsing global options: {}".format(gb))
if not isinstance(gb, dict): if not isinstance(gb, dict):
config_error("Incorrect `global` section (must be a dict)") config_error("Incorrect `global` section (must be a dict)")
if self.imported_globals:
gb.update(self.imported_globals)
logger.debug("Global options + imported: {}".format(gb))
# Parse all keys inside it # Parse all keys inside it
glb = GS.global_opts_class() glb = GS.global_opts_class()
glb.set_tree(gb) glb.set_tree(gb)
@ -235,7 +239,7 @@ class CfgYamlReader(object):
RegOutput.add_filters(sel_fils) RegOutput.add_filters(sel_fils)
logger.debug('Filters loaded from `{}`: {}'.format(fn_rel, sel_fils.keys())) logger.debug('Filters loaded from `{}`: {}'.format(fn_rel, sel_fils.keys()))
if fils is None and explicit_fils and 'filters' not in data: if fils is None and explicit_fils and 'filters' not in data:
logger.warning(W_NOOUTPUTS+"No filters found in `{}`".format(fn_rel)) logger.warning(W_NOFILTERS+"No filters found in `{}`".format(fn_rel))
def _parse_import_variants(self, vars, explicit_vars, fn_rel, data): def _parse_import_variants(self, vars, explicit_vars, fn_rel, data):
if (vars is None or len(vars) > 0) and 'variants' in data: if (vars is None or len(vars) > 0) and 'variants' in data:
@ -255,7 +259,29 @@ class CfgYamlReader(object):
RegOutput.add_variants(sel_vars) RegOutput.add_variants(sel_vars)
logger.debug('Variants loaded from `{}`: {}'.format(fn_rel, sel_vars.keys())) logger.debug('Variants loaded from `{}`: {}'.format(fn_rel, sel_vars.keys()))
if vars is None and explicit_vars and 'variants' not in data: if vars is None and explicit_vars and 'variants' not in data:
logger.warning(W_NOOUTPUTS+"No variants found in `{}`".format(fn_rel)) logger.warning(W_NOVARIANTS+"No variants found in `{}`".format(fn_rel))
def _parse_import_globals(self, globals, explicit_globals, fn_rel, data):
if (globals is None or len(globals) > 0) and 'global' in data:
i_globals = data['global']
if not isinstance(i_globals, dict):
config_error("Incorrect `global` section (must be a dict), while importing from {}".format(fn_rel))
if globals is not None:
sel_globals = {}
for f in globals:
if f in i_globals:
sel_globals[f] = i_globals[f]
else:
logger.warning(W_UNKOUT+"can't import `{}` global from `{}` (missing)".format(f, fn_rel))
else:
sel_globals = i_globals
if len(sel_globals) == 0:
logger.warning(W_NOGLOBALS+"No globals found in `{}`".format(fn_rel))
else:
self.imported_globals.update(sel_globals)
logger.debug('Globals loaded from `{}`: {}'.format(fn_rel, sel_globals.keys()))
if globals is None and explicit_globals and 'global' not in data:
logger.warning(W_NOGLOBALS+"No globals found in `{}`".format(fn_rel))
def _parse_import(self, imp, name): def _parse_import(self, imp, name):
""" Get imports """ """ Get imports """
@ -271,12 +297,14 @@ class CfgYamlReader(object):
outs = None outs = None
fils = [] fils = []
vars = [] vars = []
globals = []
explicit_outs = True explicit_outs = True
explicit_fils = False explicit_fils = False
explicit_vars = False explicit_vars = False
explicit_outs = False
elif isinstance(entry, dict): elif isinstance(entry, dict):
fn = outs = fils = vars = None fn = outs = fils = vars = globals = None
explicit_outs = explicit_fils = explicit_vars = False explicit_outs = explicit_fils = explicit_vars = explicit_globals = False
for k, v in entry.items(): for k, v in entry.items():
if k == 'file': if k == 'file':
if not isinstance(v, str): if not isinstance(v, str):
@ -291,6 +319,9 @@ class CfgYamlReader(object):
elif k == 'variants': elif k == 'variants':
vars = self._parse_import_items('variants', fn, v) vars = self._parse_import_items('variants', fn, v)
explicit_vars = True explicit_vars = True
elif k == 'global':
globals = self._parse_import_items('global', fn, v)
explicit_globals = True
else: else:
self._config_error_import(fn, "unknown import entry `{}`".format(str(v))) self._config_error_import(fn, "unknown import entry `{}`".format(str(v)))
if fn is None: if fn is None:
@ -309,6 +340,8 @@ class CfgYamlReader(object):
self._parse_import_filters(fils, explicit_fils, fn_rel, data) self._parse_import_filters(fils, explicit_fils, fn_rel, data)
# Variants # Variants
self._parse_import_variants(vars, explicit_vars, fn_rel, data) self._parse_import_variants(vars, explicit_vars, fn_rel, data)
# Globals
self._parse_import_globals(globals, explicit_globals, fn_rel, data)
return outputs return outputs
def load_yaml(self, fstream): def load_yaml(self, fstream):

View File

@ -207,6 +207,7 @@ W_NOFILTERS = '(W068) '
W_NOVARIANTS = '(W069) ' W_NOVARIANTS = '(W069) '
W_NOENDLIB = '(W070) ' W_NOENDLIB = '(W070) '
W_NEEDSPCB = '(W071) ' W_NEEDSPCB = '(W071) '
W_NOGLOBALS = '(W072) '
class Rect(object): class Rect(object):

View File

@ -816,3 +816,12 @@ def test_import_1(test_dir):
ctx.search_err(r'Outputs loaded from `tests/yaml_samples/gerber_inner.kibot.yaml`: \[\'gerbers\', \'result\'\]') ctx.search_err(r'Outputs loaded from `tests/yaml_samples/gerber_inner.kibot.yaml`: \[\'gerbers\', \'result\'\]')
ctx.search_err(r'Outputs loaded from `tests/yaml_samples/ibom.kibot.yaml`: \[\'interactive_bom\'\]') ctx.search_err(r'Outputs loaded from `tests/yaml_samples/ibom.kibot.yaml`: \[\'interactive_bom\'\]')
ctx.clean_up() ctx.clean_up()
def test_import_2(test_dir):
prj = 'test_v5'
ctx = context.TestContext(test_dir, 'test_import_2', prj, 'import_test_2', '')
ctx.run(extra=['-vvv'])
ctx.expect_out_file(POS_DIR+'/test_v5_(bottom_pos).pos')
ctx.expect_out_file(POS_DIR+'/test_v5_(top_pos).pos')
ctx.clean_up()

View File

@ -0,0 +1,5 @@
kibot:
version: 1
global:
output: '%f_(%i).%x'

View File

@ -0,0 +1,21 @@
kibot:
version: 1
import:
# Here we change the global.output pattern
- file: global_import.kibot.yaml
global:
# The import will override it
output: '%f-%i.%x'
outputs:
- name: 'position'
comment: "Pick and place file"
type: position
dir: positiondir
options:
format: ASCII # CSV or ASCII format
units: millimeters # millimeters or inches
separate_files_for_front_and_back: true
only_smd: true