Implemented the new variants mechanism in the internal BoM.
This commit is contained in:
parent
a19c6157b7
commit
0bdce78004
104
kibot/bom/bom.py
104
kibot/bom/bom.py
|
|
@ -14,33 +14,10 @@ from copy import deepcopy
|
|||
from .units import compare_values, comp_match
|
||||
from .bom_writer import write_bom
|
||||
from .columnlist import ColumnList
|
||||
from ..misc import DNF
|
||||
from .. import log
|
||||
|
||||
logger = log.get_logger(__name__)
|
||||
# Supported values for "do not fit"
|
||||
DNF = {
|
||||
"dnf": 1,
|
||||
"dnl": 1,
|
||||
"dnp": 1,
|
||||
"do not fit": 1,
|
||||
"do not place": 1,
|
||||
"do not load": 1,
|
||||
"nofit": 1,
|
||||
"nostuff": 1,
|
||||
"noplace": 1,
|
||||
"noload": 1,
|
||||
"not fitted": 1,
|
||||
"not loaded": 1,
|
||||
"not placed": 1,
|
||||
"no stuff": 1,
|
||||
}
|
||||
# String matches for marking a component as "do not change" or "fixed"
|
||||
DNC = {
|
||||
"dnc": 1,
|
||||
"do not change": 1,
|
||||
"no change": 1,
|
||||
"fixed": 1
|
||||
}
|
||||
# RV == Resistor Variable or Varistor
|
||||
# RN == Resistor 'N'(Pack)
|
||||
# RT == Thermistor
|
||||
|
|
@ -412,88 +389,11 @@ def group_components(cfg, components):
|
|||
return groups
|
||||
|
||||
|
||||
def comp_is_fixed(value, config, variants):
|
||||
""" Determine if a component is FIXED or not.
|
||||
Fixed components shouldn't be replaced without express authorization.
|
||||
value: component value (lowercase).
|
||||
config: content of the 'Config' field (lowercase).
|
||||
variants: list of variants to match. """
|
||||
# Check the value field first
|
||||
if value in DNC:
|
||||
return True
|
||||
# Empty is not fixed
|
||||
if not config:
|
||||
return False
|
||||
# Also support space separated list (simple cases)
|
||||
opts = config.split(" ")
|
||||
for opt in opts:
|
||||
if opt in DNC:
|
||||
return True
|
||||
# Normal separator is ","
|
||||
opts = config.split(",")
|
||||
for opt in opts:
|
||||
if opt in DNC:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def comp_is_fitted(value, config, variants):
|
||||
""" Determine if a component will be or not.
|
||||
value: component value (lowercase).
|
||||
config: content of the 'Config' field (lowercase).
|
||||
variants: list of variants to match. """
|
||||
# Check the value field first
|
||||
if value in DNF:
|
||||
return False
|
||||
# Empty value means part is fitted
|
||||
if not config:
|
||||
return True
|
||||
# Also support space separated list (simple cases)
|
||||
opts = config.split(" ")
|
||||
for opt in opts:
|
||||
if opt in DNF:
|
||||
return False
|
||||
# Variants logic
|
||||
opts = config.split(",")
|
||||
# Only fit for ...
|
||||
exclusive = False
|
||||
for opt in opts:
|
||||
opt = opt.strip()
|
||||
# Any option containing a DNF is not fitted
|
||||
if opt in DNF:
|
||||
return False
|
||||
# Options that start with '-' are explicitly removed from certain configurations
|
||||
if opt.startswith("-") and opt[1:] in variants:
|
||||
return False
|
||||
# Options that start with '+' are fitted only for certain configurations
|
||||
if opt.startswith("+"):
|
||||
exclusive = True
|
||||
if opt[1:] in variants:
|
||||
return True
|
||||
# No match
|
||||
return not exclusive
|
||||
|
||||
|
||||
def do_bom(file_name, ext, comps, cfg):
|
||||
# Make the config field name lowercase
|
||||
cfg.fit_field = cfg.fit_field.lower()
|
||||
f_config = cfg.fit_field
|
||||
# Make the variants lowercase
|
||||
variants = [v.lower() for v in cfg.variant]
|
||||
# Solve `fixed` and `fitted` attributes for all components
|
||||
for c in comps:
|
||||
value = c.value.lower()
|
||||
config = c.get_field_value(f_config).lower()
|
||||
c.fitted = comp_is_fitted(value, config, variants)
|
||||
if cfg.debug_level > 2:
|
||||
logger.debug('ref: {} value: {} config: {} variants: {} -> fitted {}'.
|
||||
format(c.ref, value, config, variants, c.fitted))
|
||||
c.fixed = comp_is_fixed(value, config, variants)
|
||||
cfg.variant.filter(comps)
|
||||
# Group components according to group_fields
|
||||
groups = group_components(cfg, comps)
|
||||
# Give a name to empty variant
|
||||
if not variants:
|
||||
cfg.variant = ['default']
|
||||
# Create the BoM
|
||||
logger.debug("Saving BOM File: "+file_name)
|
||||
write_bom(file_name, ext, groups, cfg.columns, cfg)
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ def write_csv(filename, ext, groups, headings, head_names, cfg):
|
|||
if not cfg.csv.hide_pcb_info:
|
||||
writer.writerow(["Project info:"])
|
||||
writer.writerow(["Schematic:", cfg.source])
|
||||
writer.writerow(["Variant:", ' + '.join(cfg.variant)])
|
||||
writer.writerow(["Variant:", cfg.variant.name])
|
||||
writer.writerow(["Revision:", cfg.revision])
|
||||
writer.writerow(["Date:", cfg.date])
|
||||
writer.writerow(["KiCad Version:", cfg.kicad_version])
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ def write_html(filename, groups, headings, head_names, cfg):
|
|||
html.write(' <td class="cell-info">\n')
|
||||
if not cfg.html.hide_pcb_info:
|
||||
html.write(" <b>Schematic</b>: {}<br>\n".format(cfg.source))
|
||||
html.write(" <b>Variant</b>: {}<br>\n".format(', '.join(cfg.variant)))
|
||||
html.write(" <b>Variant</b>: {}<br>\n".format(cfg.variant.name))
|
||||
html.write(" <b>Revision</b>: {}<br>\n".format(cfg.revision))
|
||||
html.write(" <b>Date</b>: {}<br>\n".format(cfg.date))
|
||||
html.write(" <b>KiCad Version</b>: {}<br>\n".format(cfg.kicad_version))
|
||||
|
|
|
|||
|
|
@ -313,7 +313,7 @@ def write_xlsx(filename, groups, col_fields, head_names, cfg):
|
|||
rc = r_info_start
|
||||
if not cfg.xlsx.hide_pcb_info:
|
||||
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Schematic:", cfg.source)
|
||||
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Variant:", ' + '.join(cfg.variant))
|
||||
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Variant:", cfg.variant.name)
|
||||
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Revision:", cfg.revision)
|
||||
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "Date:", cfg.date)
|
||||
rc = add_info(worksheet, column_widths, rc, col1, fmt_info, "KiCad Version:", cfg.kicad_version)
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ def write_xml(filename, groups, headings, head_names, cfg):
|
|||
attrib['Schematic_Source'] = cfg.source
|
||||
attrib['Schematic_Revision'] = cfg.revision
|
||||
attrib['Schematic_Date'] = cfg.date
|
||||
attrib['PCB_Variant'] = ', '.join(cfg.variant)
|
||||
attrib['PCB_Variant'] = cfg.variant.name
|
||||
attrib['KiCad_Version'] = cfg.kicad_version
|
||||
attrib['Component_Groups'] = str(cfg.n_groups)
|
||||
attrib['Component_Count'] = str(cfg.n_total)
|
||||
|
|
|
|||
|
|
@ -45,3 +45,28 @@ PCBDRAW = 'pcbdraw'
|
|||
URL_PCBDRAW = 'https://github.com/INTI-CMNB/pcbdraw'
|
||||
EXAMPLE_CFG = 'example.kibot.yaml'
|
||||
AUTO_SCALE = 0
|
||||
|
||||
# Supported values for "do not fit"
|
||||
DNF = {
|
||||
"dnf": 1,
|
||||
"dnl": 1,
|
||||
"dnp": 1,
|
||||
"do not fit": 1,
|
||||
"do not place": 1,
|
||||
"do not load": 1,
|
||||
"nofit": 1,
|
||||
"nostuff": 1,
|
||||
"noplace": 1,
|
||||
"noload": 1,
|
||||
"not fitted": 1,
|
||||
"not loaded": 1,
|
||||
"not placed": 1,
|
||||
"no stuff": 1,
|
||||
}
|
||||
# String matches for marking a component as "do not change" or "fixed"
|
||||
DNC = {
|
||||
"dnc": 1,
|
||||
"do not change": 1,
|
||||
"no change": 1,
|
||||
"fixed": 1
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,10 +11,12 @@ import os
|
|||
from re import compile, IGNORECASE
|
||||
from .gs import GS
|
||||
from .optionable import Optionable, BaseOptions
|
||||
from .registrable import RegOutput
|
||||
from .error import KiPlotConfigurationError
|
||||
from .macros import macros, document, output_class # noqa: F401
|
||||
from .bom.columnlist import ColumnList, BoMError
|
||||
from .bom.bom import do_bom
|
||||
from .var_kibom import KiBoM
|
||||
from . import log
|
||||
|
||||
logger = log.get_logger(__name__)
|
||||
|
|
@ -207,8 +209,8 @@ class BoMOptions(BaseOptions):
|
|||
with document:
|
||||
self.number = 1
|
||||
""" Number of boards to build (components multiplier) """
|
||||
self.variant = Optionable
|
||||
""" [string|list(string)=''] Board variant(s), used to determine which components
|
||||
self.variant = ''
|
||||
""" Board variant(s), used to determine which components
|
||||
are output to the BoM. """
|
||||
self.output = GS.def_global_output
|
||||
""" filename for the output (%i=bom)"""
|
||||
|
|
@ -228,7 +230,8 @@ class BoMOptions(BaseOptions):
|
|||
self.merge_blank_fields = True
|
||||
""" Component groups with blank fields will be merged into the most compatible group, where possible """
|
||||
self.fit_field = 'Config'
|
||||
""" Field name used to determine if a particular part is to be fitted (also DNC and variants) """
|
||||
""" Field name used to determine if a particular part is to be fitted (also DNC, not for variants).
|
||||
This value is used only when no variants are specified """
|
||||
self.group_fields = GroupFields
|
||||
""" [list(string)] List of fields used for sorting individual components into groups.
|
||||
Components which match (comparing *all* fields) will be grouped together.
|
||||
|
|
@ -316,16 +319,18 @@ class BoMOptions(BaseOptions):
|
|||
col = col[:-1]
|
||||
return col
|
||||
|
||||
@staticmethod
|
||||
def _normalize_variant(variant):
|
||||
if isinstance(variant, type):
|
||||
variant = []
|
||||
elif isinstance(variant, str):
|
||||
if variant:
|
||||
variant = [variant]
|
||||
else:
|
||||
variant = []
|
||||
return variant
|
||||
def _normalize_variant(self):
|
||||
""" Replaces the name of the variant by an object handling it. """
|
||||
if self.variant:
|
||||
if self.variant not in RegOutput._def_variants:
|
||||
raise KiPlotConfigurationError("Unknown variant name `{}`".format(self.variant))
|
||||
self.variant = RegOutput._def_variants[self.variant]
|
||||
else:
|
||||
# If no variant is specified use the KiBoM variant class with basic functionality
|
||||
self.variant = KiBoM()
|
||||
self.variant.config_field = self.fit_field
|
||||
self.variant.variant = []
|
||||
self.variant.name = 'default'
|
||||
|
||||
def config(self):
|
||||
super().config()
|
||||
|
|
@ -372,8 +377,10 @@ class BoMOptions(BaseOptions):
|
|||
for r in self.exclude_any:
|
||||
r.column = self._fix_ref_field(r.column)
|
||||
r.regex = compile(r.regex, flags=IGNORECASE)
|
||||
# Variants, ensure a list
|
||||
self.variant = self._normalize_variant(self.variant)
|
||||
# Make the config field name lowercase
|
||||
self.fit_field = self.fit_field.lower()
|
||||
# Variants, make it an object
|
||||
self._normalize_variant()
|
||||
# Columns
|
||||
self.column_rename = {}
|
||||
self.join = []
|
||||
|
|
|
|||
|
|
@ -0,0 +1,141 @@
|
|||
# -*- 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)
|
||||
"""
|
||||
Implements the KiBoM variants mechanism.
|
||||
"""
|
||||
from .optionable import Optionable
|
||||
from .gs import GS
|
||||
from .misc import DNF, DNC
|
||||
from .macros import macros, document, variant_class # noqa: F401
|
||||
from . import log
|
||||
|
||||
logger = log.get_logger(__name__)
|
||||
|
||||
|
||||
@variant_class
|
||||
class KiBoM(BaseVariant): # noqa: F821
|
||||
""" KiBoM variant style
|
||||
The Config field (configurable) contains a comma separated list of variant directives.
|
||||
-VARIANT excludes a component from VARIANT.
|
||||
+VARIANT includes the component only if we are using this variant. """
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
with document:
|
||||
self.config_field = 'Config'
|
||||
""" Name of the field used to clasify components """
|
||||
self.variant = Optionable
|
||||
""" [string|list(string)=''] Board variant(s) """
|
||||
|
||||
def config(self):
|
||||
super().config()
|
||||
# Variants, ensure a list
|
||||
if isinstance(self.variant, type):
|
||||
self.variant = []
|
||||
elif isinstance(self.variant, str):
|
||||
if self.variant:
|
||||
self.variant = [self.variant]
|
||||
else:
|
||||
self.variant = []
|
||||
self.variant = [v.lower() for v in self.variant]
|
||||
# Config field must be lowercase
|
||||
self.config_field = self.config_field.lower()
|
||||
|
||||
@staticmethod
|
||||
def basic_comp_is_fitted(value, config):
|
||||
""" Basic `fitted` criteria, no variants.
|
||||
value: component value (lowercase).
|
||||
config: content of the 'Config' field (lowercase). """
|
||||
# Check the value field first
|
||||
if value in DNF:
|
||||
return False
|
||||
# Empty value means part is fitted
|
||||
if not config:
|
||||
return True
|
||||
# Also support space separated list (simple cases)
|
||||
opts = config.split(" ")
|
||||
for opt in opts:
|
||||
if opt in DNF:
|
||||
return False
|
||||
# Normal separator is ","
|
||||
opts = config.split(",")
|
||||
for opt in opts:
|
||||
if opt in DNF:
|
||||
return False
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def basic_comp_is_fixed(value, config):
|
||||
""" Basic `fixed` criteria, no variants
|
||||
Fixed components shouldn't be replaced without express authorization.
|
||||
value: component value (lowercase).
|
||||
config: content of the 'Config' field (lowercase). """
|
||||
# Check the value field first
|
||||
if value in DNC:
|
||||
return True
|
||||
# Empty is not fixed
|
||||
if not config:
|
||||
return False
|
||||
# Also support space separated list (simple cases)
|
||||
opts = config.split(" ")
|
||||
for opt in opts:
|
||||
if opt in DNC:
|
||||
return True
|
||||
# Normal separator is ","
|
||||
opts = config.split(",")
|
||||
for opt in opts:
|
||||
if opt in DNC:
|
||||
return True
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def _base_filter(comps, f_config):
|
||||
""" Fill the `fixed` and `fitted` using the basic criteria.
|
||||
No variant is applied in this step. """
|
||||
logger.debug("- Generic KiBoM rules")
|
||||
for c in comps:
|
||||
value = c.value.lower()
|
||||
config = c.get_field_value(f_config).lower()
|
||||
c.fitted = KiBoM.basic_comp_is_fitted(value, config)
|
||||
if GS.debug_level > 2:
|
||||
logger.debug('ref: {} value: {} config: {} -> fitted {}'.
|
||||
format(c.ref, value, config, c.fitted))
|
||||
c.fixed = KiBoM.basic_comp_is_fixed(value, config)
|
||||
|
||||
def variant_comp_is_fitted(self, value, config):
|
||||
""" Apply the variants to determine if this component will be fitted.
|
||||
value: component value (lowercase).
|
||||
config: content of the 'Config' field (lowercase). """
|
||||
# Variants logic
|
||||
opts = config.split(",")
|
||||
# Only fit for ...
|
||||
exclusive = False
|
||||
for opt in opts:
|
||||
opt = opt.strip()
|
||||
# Options that start with '-' are explicitly removed from certain configurations
|
||||
if opt.startswith("-") and opt[1:] in self.variant:
|
||||
return False
|
||||
# Options that start with '+' are fitted only for certain configurations
|
||||
if opt.startswith("+"):
|
||||
exclusive = True
|
||||
if opt[1:] in self.variant:
|
||||
return True
|
||||
# No match
|
||||
return not exclusive
|
||||
|
||||
def filter(self, comps):
|
||||
logger.debug("Applying KiBoM style filter `{}`".format(self.name))
|
||||
self._base_filter(comps, self.config_field)
|
||||
logger.debug("- Variant specific rules")
|
||||
for c in comps:
|
||||
if not c.fitted:
|
||||
# Don't check if we already discarded it during the basic test
|
||||
continue
|
||||
value = c.value.lower()
|
||||
config = c.get_field_value(self.config_field).lower()
|
||||
c.fitted = self.variant_comp_is_fitted(value, config)
|
||||
if not c.fitted and GS.debug_level > 2:
|
||||
logger.debug('ref: {} value: {} config: {} variant: {} -> False'.
|
||||
format(c.ref, value, config, self.variant))
|
||||
|
|
@ -81,6 +81,7 @@ KIBOM_STATS = [KIBOM_TEST_GROUPS+len(KIBOM_TEST_EXCLUDE),
|
|||
len(KIBOM_TEST_COMPONENTS),
|
||||
1,
|
||||
len(KIBOM_TEST_COMPONENTS)]
|
||||
VARIANTE_PRJ_INFO = ['kibom-variante', 'default', 'A', '2020-03-12', None]
|
||||
LINK_HEAD = ['References', 'Part', 'Value', 'Quantity Per PCB', 'digikey#', 'digikey_alt#', 'manf#']
|
||||
LINKS_COMPONENTS = ['J1', 'J2', 'R1']
|
||||
LINKS_EXCLUDE = ['C1']
|
||||
|
|
@ -1158,82 +1159,54 @@ def test_int_bom_missing_lib():
|
|||
ctx.clean_up()
|
||||
|
||||
|
||||
def test_int_bom_variant_t1_1():
|
||||
def test_int_bom_variant_t1():
|
||||
prj = 'kibom-variante'
|
||||
ctx = context.TestContextSCH('test_int_bom_variant_t1_1', prj, 'int_bom_var_v1_csv', BOM_DIR)
|
||||
ctx.run()
|
||||
rows, header, info = ctx.load_csv(prj+'-bom.csv')
|
||||
ref_column = header.index(REF_COLUMN_NAME)
|
||||
check_kibom_test_netlist(rows, ref_column, 2, ['R3', 'R4'], ['R1', 'R2'])
|
||||
ctx.search_err(r'Field Config of component (.*) contains extra spaces')
|
||||
ctx.clean_up()
|
||||
|
||||
|
||||
def test_int_bom_variant_t1_2():
|
||||
prj = 'kibom-variante'
|
||||
ctx = context.TestContextSCH('test_int_bom_variant_t1_2', prj, 'int_bom_var_v2_csv', BOM_DIR)
|
||||
ctx.run()
|
||||
rows, header, info = ctx.load_csv(prj+'-bom.csv')
|
||||
ref_column = header.index(REF_COLUMN_NAME)
|
||||
check_kibom_test_netlist(rows, ref_column, 1, ['R2', 'R4'], ['R1', 'R3'])
|
||||
ctx.clean_up()
|
||||
|
||||
|
||||
def test_int_bom_variant_t1_3():
|
||||
prj = 'kibom-variante'
|
||||
ctx = context.TestContextSCH('test_int_bom_variant_t1_3', prj, 'int_bom_var_v3_csv', BOM_DIR)
|
||||
ctx.run()
|
||||
rows, header, info = ctx.load_csv(prj+'-bom.csv')
|
||||
ref_column = header.index(REF_COLUMN_NAME)
|
||||
check_kibom_test_netlist(rows, ref_column, 1, ['R2', 'R3'], ['R1', 'R4'])
|
||||
ctx.clean_up()
|
||||
|
||||
|
||||
def test_int_bom_variant_t1_4():
|
||||
prj = 'kibom-variante'
|
||||
ctx = context.TestContextSCH('test_int_bom_variant_t1_4', prj, 'int_bom_simple_csv', BOM_DIR)
|
||||
ctx = context.TestContextSCH('test_int_bom_variant_t1', prj, 'int_bom_var_t1_csv', BOM_DIR)
|
||||
ctx.run()
|
||||
# No variant
|
||||
logging.debug("* No variant")
|
||||
rows, header, info = ctx.load_csv(prj+'-bom.csv')
|
||||
ref_column = header.index(REF_COLUMN_NAME)
|
||||
check_kibom_test_netlist(rows, ref_column, 2, ['R4'], ['R1', 'R2', 'R3'])
|
||||
ctx.clean_up()
|
||||
|
||||
|
||||
def test_int_bom_variant_t1_5():
|
||||
prj = 'kibom-variante'
|
||||
ctx = context.TestContextSCH('test_int_bom_variant_t1_5', prj, 'int_bom_var_v1v3_csv', BOM_DIR)
|
||||
ctx.run()
|
||||
rows, header, info = ctx.load_csv(prj+'-bom.csv')
|
||||
ref_column = header.index(REF_COLUMN_NAME)
|
||||
VARIANTE_PRJ_INFO[1] = 'default'
|
||||
check_csv_info(info, VARIANTE_PRJ_INFO, [4, 20, 3, 1, 3])
|
||||
# V1
|
||||
logging.debug("* t1_v1 variant")
|
||||
rows, header, info = ctx.load_csv(prj+'-bom_(V1).csv')
|
||||
check_kibom_test_netlist(rows, ref_column, 2, ['R3', 'R4'], ['R1', 'R2'])
|
||||
ctx.search_err(r'Field Config of component (.*) contains extra spaces')
|
||||
VARIANTE_PRJ_INFO[1] = 't1_v1'
|
||||
check_csv_info(info, VARIANTE_PRJ_INFO, [4, 20, 2, 1, 2])
|
||||
# V2
|
||||
logging.debug("* t1_v2 variant")
|
||||
rows, header, info = ctx.load_csv(prj+'-bom_(V2).csv')
|
||||
check_kibom_test_netlist(rows, ref_column, 1, ['R2', 'R4'], ['R1', 'R3'])
|
||||
VARIANTE_PRJ_INFO[1] = 't1_v2'
|
||||
check_csv_info(info, VARIANTE_PRJ_INFO, [3, 20, 2, 1, 2])
|
||||
# V3
|
||||
logging.debug("* t1_v3 variant")
|
||||
rows, header, info = ctx.load_csv(prj+'-bom_V3.csv')
|
||||
check_kibom_test_netlist(rows, ref_column, 1, ['R2', 'R3'], ['R1', 'R4'])
|
||||
VARIANTE_PRJ_INFO[1] = 't1_v3'
|
||||
check_csv_info(info, VARIANTE_PRJ_INFO, [3, 20, 2, 1, 2])
|
||||
# V1,V3
|
||||
logging.debug("* `bla bla` variant")
|
||||
rows, header, info = ctx.load_csv(prj+'-bom_bla_bla.csv')
|
||||
check_kibom_test_netlist(rows, ref_column, 1, ['R2', 'R3'], ['R1', 'R4'])
|
||||
VARIANTE_PRJ_INFO[1] = 'bla bla'
|
||||
check_csv_info(info, VARIANTE_PRJ_INFO, [3, 20, 2, 1, 2])
|
||||
ctx.clean_up()
|
||||
|
||||
|
||||
def test_int_bom_variant_t2_1():
|
||||
def test_int_bom_variant_t2():
|
||||
prj = 'kibom-variant_2'
|
||||
ctx = context.TestContextSCH('test_int_bom_variant_t2_1', prj, 'int_bom_var_production_csv', BOM_DIR)
|
||||
ctx.run()
|
||||
rows, header, info = ctx.load_csv(prj+'-bom.csv')
|
||||
ref_column = header.index(REF_COLUMN_NAME)
|
||||
check_kibom_test_netlist(rows, ref_column, 2, ['C1'], ['R1', 'R2', 'C2'])
|
||||
ctx.clean_up()
|
||||
|
||||
|
||||
def test_int_bom_variant_t2_2():
|
||||
prj = 'kibom-variant_2'
|
||||
ctx = context.TestContextSCH('test_int_bom_variant_t2_2', prj, 'int_bom_var_test_csv', BOM_DIR)
|
||||
ctx.run()
|
||||
rows, header, info = ctx.load_csv(prj+'-bom.csv')
|
||||
ref_column = header.index(REF_COLUMN_NAME)
|
||||
check_kibom_test_netlist(rows, ref_column, 2, ['R2'], ['R1', 'C1', 'C2'])
|
||||
ctx.clean_up()
|
||||
|
||||
|
||||
def test_int_bom_variant_t2_3():
|
||||
prj = 'kibom-variant_2'
|
||||
ctx = context.TestContextSCH('test_int_bom_variant_t2_3', prj, 'int_bom_simple_csv', BOM_DIR)
|
||||
ctx = context.TestContextSCH('test_int_bom_variant_t2', prj, 'int_bom_var_t2_csv', BOM_DIR)
|
||||
ctx.run()
|
||||
rows, header, info = ctx.load_csv(prj+'-bom.csv')
|
||||
ref_column = header.index(REF_COLUMN_NAME)
|
||||
check_kibom_test_netlist(rows, ref_column, 1, ['C1', 'C2'], ['R1', 'R2'])
|
||||
rows, header, info = ctx.load_csv(prj+'-bom_(production).csv')
|
||||
check_kibom_test_netlist(rows, ref_column, 2, ['C1'], ['R1', 'R2', 'C2'])
|
||||
rows, header, info = ctx.load_csv(prj+'-bom_(test).csv')
|
||||
check_kibom_test_netlist(rows, ref_column, 2, ['R2'], ['R1', 'C1', 'C2'])
|
||||
ctx.clean_up()
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
# Example KiBot config file
|
||||
kibot:
|
||||
version: 1
|
||||
|
||||
outputs:
|
||||
- name: 'bom_internal'
|
||||
comment: "Bill of Materials in CSV format"
|
||||
type: bom
|
||||
dir: BoM
|
||||
options:
|
||||
variant: production
|
||||
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
# Example KiBot config file
|
||||
kibot:
|
||||
version: 1
|
||||
|
||||
|
||||
variants:
|
||||
- name: 't1_v1'
|
||||
comment: 'Test 1 Variant V1'
|
||||
type: kibom
|
||||
file_id: '_(V1)'
|
||||
variant: V1
|
||||
|
||||
- name: 't1_v2'
|
||||
comment: 'Test 1 Variant V2'
|
||||
type: kibom
|
||||
file_id: '_(V2)'
|
||||
variant: V2
|
||||
|
||||
- name: 't1_v3'
|
||||
comment: 'Test 1 Variant V3'
|
||||
type: kibom
|
||||
file_id: '_V3'
|
||||
variant: V3
|
||||
|
||||
- name: 'bla bla'
|
||||
comment: 'Test 1 Variant V1+V3'
|
||||
type: kibom
|
||||
file_id: '_bla_bla'
|
||||
variant: ['V1', 'V3']
|
||||
|
||||
outputs:
|
||||
- name: 'bom_internal'
|
||||
comment: "Bill of Materials in CSV format"
|
||||
type: bom
|
||||
dir: BoM
|
||||
|
||||
- name: 'bom_internal_v1'
|
||||
comment: "Bill of Materials in CSV format for variant t1_v1"
|
||||
type: bom
|
||||
dir: BoM
|
||||
options:
|
||||
variant: t1_v1
|
||||
|
||||
- name: 'bom_internal_v2'
|
||||
comment: "Bill of Materials in CSV format for variant t1_v2"
|
||||
type: bom
|
||||
dir: BoM
|
||||
options:
|
||||
variant: t1_v2
|
||||
|
||||
- name: 'bom_internal_v3'
|
||||
comment: "Bill of Materials in CSV format for variant t1_v3"
|
||||
type: bom
|
||||
dir: BoM
|
||||
options:
|
||||
variant: t1_v3
|
||||
|
||||
- name: 'bom_internal_bla_bla'
|
||||
comment: "Bill of Materials in CSV format for variant `bla bla`"
|
||||
type: bom
|
||||
dir: BoM
|
||||
options:
|
||||
variant: 'bla bla'
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
# Example KiBot config file
|
||||
kibot:
|
||||
version: 1
|
||||
|
||||
variants:
|
||||
- name: 'production'
|
||||
comment: 'Production variant'
|
||||
type: kibom
|
||||
file_id: '_(production)'
|
||||
variant: production
|
||||
|
||||
- name: 'test'
|
||||
comment: 'Test variant'
|
||||
type: kibom
|
||||
file_id: '_(test)'
|
||||
variant: test
|
||||
|
||||
outputs:
|
||||
- name: 'bom_internal'
|
||||
comment: "Bill of Materials in CSV format"
|
||||
type: bom
|
||||
dir: BoM
|
||||
|
||||
- name: 'bom_internal_production'
|
||||
comment: "Bill of Materials in CSV format for production"
|
||||
type: bom
|
||||
dir: BoM
|
||||
options:
|
||||
variant: production
|
||||
|
||||
- name: 'bom_internal_test'
|
||||
comment: "Bill of Materials in CSV format for test"
|
||||
type: bom
|
||||
dir: BoM
|
||||
options:
|
||||
variant: test
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
# Example KiBot config file
|
||||
kibot:
|
||||
version: 1
|
||||
|
||||
outputs:
|
||||
- name: 'bom_internal'
|
||||
comment: "Bill of Materials in CSV format"
|
||||
type: bom
|
||||
dir: BoM
|
||||
options:
|
||||
variant: test
|
||||
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
# Example KiBot config file
|
||||
kibot:
|
||||
version: 1
|
||||
|
||||
outputs:
|
||||
- name: 'bom_internal'
|
||||
comment: "Bill of Materials in CSV format"
|
||||
type: bom
|
||||
dir: BoM
|
||||
options:
|
||||
variant: V1
|
||||
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
# Example KiBot config file
|
||||
kibot:
|
||||
version: 1
|
||||
|
||||
outputs:
|
||||
- name: 'bom_internal'
|
||||
comment: "Bill of Materials in CSV format"
|
||||
type: bom
|
||||
dir: BoM
|
||||
options:
|
||||
variant: ['V1', 'V3']
|
||||
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
# Example KiBot config file
|
||||
kibot:
|
||||
version: 1
|
||||
|
||||
outputs:
|
||||
- name: 'bom_internal'
|
||||
comment: "Bill of Materials in CSV format"
|
||||
type: bom
|
||||
dir: BoM
|
||||
options:
|
||||
variant: V2
|
||||
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
# Example KiBot config file
|
||||
kibot:
|
||||
version: 1
|
||||
|
||||
outputs:
|
||||
- name: 'bom_internal'
|
||||
comment: "Bill of Materials in CSV format"
|
||||
type: bom
|
||||
dir: BoM
|
||||
options:
|
||||
variant: V3
|
||||
|
||||
Loading…
Reference in New Issue