diff --git a/kiplot/bom/bom_writer.py b/kiplot/bom/bom_writer.py index 19975485..81fa1994 100644 --- a/kiplot/bom/bom_writer.py +++ b/kiplot/bom/bom_writer.py @@ -32,6 +32,11 @@ def write_bom(filename, ext, groups, headings, cfg): # Allow renaming the columns head_names = [h if h.lower() not in cfg.column_rename else cfg.column_rename[h.lower()] for h in headings] result = False + # Some stats + cfg.n_groups = len(groups) + cfg.n_total = sum([g.get_count() for g in groups]) + cfg.n_fitted = sum([g.get_count() for g in groups if g.is_fitted()]) + cfg.n_build = cfg.n_fitted * cfg.number # CSV file writing if ext in ["csv", "tsv", "txt"]: result = write_csv(filename, ext, groups, headings, head_names, cfg) diff --git a/kiplot/bom/csv_writer.py b/kiplot/bom/csv_writer.py index 3d7c04ad..8305bc7c 100644 --- a/kiplot/bom/csv_writer.py +++ b/kiplot/bom/csv_writer.py @@ -27,11 +27,6 @@ def write_csv(filename, ext, groups, headings, head_names, cfg): elif ext == "tsv" or ext == "txt": delimiter = "\t" - n_groups = len(groups) - n_total = sum([g.get_count() for g in groups]) - n_fitted = sum([g.get_count() for g in groups if g.is_fitted()]) - n_build = n_fitted * cfg.number - with open(filename, "wt") as f: writer = csv.writer(f, delimiter=delimiter, lineterminator="\n") # Headers @@ -63,11 +58,11 @@ def write_csv(filename, ext, groups, headings, head_names, cfg): for i in range(5): writer.writerow([]) - writer.writerow(["Component Groups:", n_groups]) - writer.writerow(["Component Count:", n_total]) - writer.writerow(["Fitted Components:", n_fitted]) + writer.writerow(["Component Groups:", cfg.n_groups]) + writer.writerow(["Component Count:", cfg.n_total]) + writer.writerow(["Fitted Components:", cfg.n_fitted]) writer.writerow(["Number of PCBs:", cfg.number]) - writer.writerow(["Total components:", n_build]) + writer.writerow(["Total components:", cfg.n_build]) writer.writerow(["Schematic Revision:", cfg.revision]) writer.writerow(["Schematic Date:", cfg.date]) writer.writerow(["PCB Variant:", ' + '.join(cfg.variant)]) diff --git a/kiplot/bom/html_writer.py b/kiplot/bom/html_writer.py index 1400152e..08cf9251 100644 --- a/kiplot/bom/html_writer.py +++ b/kiplot/bom/html_writer.py @@ -84,11 +84,6 @@ def write_html(filename, groups, headings, head_names, cfg): head_names = [list of headings to display in the BoM file] prefs = BomPref object """ - n_groups = len(groups) - n_total = sum([g.get_count() for g in groups]) - n_fitted = sum([g.get_count() for g in groups if g.is_fitted()]) - n_build = n_fitted * cfg.number - link_datasheet = cfg.datasheet_as_link link_digikey = None if cfg.digikey_link: @@ -107,18 +102,18 @@ def write_html(filename, groups, headings, head_names, cfg): html.write("

KiBoM PCB Bill of Materials

\n") if not cfg.hide_pcb_info: html.write('\n') - html.write("\n".format(source=cfg.source)) + html.write("\n".format(cfg.source)) # html.write("\n".format(date=cfg.date)) Same as schematic - html.write("\n".format(version=cfg.revision)) - html.write("\n".format(date=cfg.date)) - html.write("\n".format(variant=', '.join(cfg.variant))) + html.write("\n".format(cfg.revision)) + html.write("\n".format(cfg.date)) + html.write("\n".format(', '.join(cfg.variant))) # html.write("\n".format(version=net.getTool())) TODO? - html.write("\n".format(n=n_groups)) - html.write("\n".format(n=n_total)) - html.write("\n".format(n=n_fitted)) - html.write("\n".format(n=cfg.number)) + html.write("\n".format(cfg.n_groups)) + html.write("\n".format(cfg.n_total)) + html.write("\n".format(cfg.n_fitted)) + html.write("\n".format(cfg.number)) html.write("\n". - format(n=cfg.number, t=n_build)) + format(n=cfg.number, t=cfg.n_build)) html.write("
Source File{source}
Source File{}
BoM Date{date}
Schematic Revision{version}
Schematic Date{date}
PCB Variant{variant}
Schematic Revision{}
Schematic Date{}
PCB Variant{}
KiCad Version{version}
Component Groups{n}
Component Count (per PCB){n}
Fitted Components (per PCB){n}
Number of PCBs{n}
Component Groups{}
Component Count (per PCB){}
Fitted Components (per PCB){}
Number of PCBs{}
Total Component Count
(for {n} PCBs)
{t}
\n") html.write("
\n") diff --git a/kiplot/bom/xlsx_writer.py b/kiplot/bom/xlsx_writer.py index 6be43b75..130b5e39 100644 --- a/kiplot/bom/xlsx_writer.py +++ b/kiplot/bom/xlsx_writer.py @@ -65,11 +65,6 @@ def write_xlsx(filename, groups, col_fields, head_names, cfg): logger.error('Python xlsxwriter module not installed (Debian: python3-xlsxwriter)') return False - n_groups = len(groups) - n_total = sum([g.get_count() for g in groups]) - n_fitted = sum([g.get_count() for g in groups if g.is_fitted()]) - n_build = n_fitted * cfg.number - workbook = Workbook(filename) worksheet = workbook.add_worksheet() @@ -136,11 +131,11 @@ def write_xlsx(filename, groups, col_fields, head_names, cfg): title_fmt.set_bold() formats = [title_fmt, cellformat_left] - row_count = add_info(worksheet, column_widths, row_count, formats, "Component Groups:", n_groups) - row_count = add_info(worksheet, column_widths, row_count, formats, "Component Count:", n_total) - row_count = add_info(worksheet, column_widths, row_count, formats, "Fitted Components:", n_fitted) + row_count = add_info(worksheet, column_widths, row_count, formats, "Component Groups:", cfg.n_groups) + row_count = add_info(worksheet, column_widths, row_count, formats, "Component Count:", cfg.n_total) + row_count = add_info(worksheet, column_widths, row_count, formats, "Fitted Components:", cfg.n_fitted) row_count = add_info(worksheet, column_widths, row_count, formats, "Number of PCBs:", cfg.number) - row_count = add_info(worksheet, column_widths, row_count, formats, "Total components:", n_build) + row_count = add_info(worksheet, column_widths, row_count, formats, "Total components:", cfg.n_build) row_count = add_info(worksheet, column_widths, row_count, formats, "Schematic Revision:", cfg.revision) row_count = add_info(worksheet, column_widths, row_count, formats, "Schematic Date:", cfg.date) # row_count = add_info(worksheet, column_widths, row_count, formats, "BoM Date:", cfg.date) Same as sch diff --git a/kiplot/bom/xml_writer.py b/kiplot/bom/xml_writer.py index 8e1570f3..bddb394e 100644 --- a/kiplot/bom/xml_writer.py +++ b/kiplot/bom/xml_writer.py @@ -17,11 +17,6 @@ def write_xml(filename, groups, headings, head_names, cfg): headings = [list of headings to display in the BoM file] cfg = BomPref object """ - n_groups = len(groups) - n_total = sum([g.get_count() for g in groups]) - n_fitted = sum([g.get_count() for g in groups if g.is_fitted()]) - n_build = n_fitted * cfg.number - attrib = {} attrib['Schematic_Source'] = cfg.source attrib['Schematic_Revision'] = cfg.revision @@ -29,11 +24,11 @@ def write_xml(filename, groups, headings, head_names, cfg): attrib['PCB_Variant'] = ', '.join(cfg.variant) # attrib['BOM_Date'] = net.getDate() same as schematic # attrib['KiCad_Version'] = net.getTool() TODO? - attrib['Component_Groups'] = str(n_groups) - attrib['Component_Count'] = str(n_total) - attrib['Fitted_Components'] = str(n_fitted) + attrib['Component_Groups'] = str(cfg.n_groups) + attrib['Component_Count'] = str(cfg.n_total) + attrib['Fitted_Components'] = str(cfg.n_fitted) attrib['Number_of_PCBs'] = str(cfg.number) - attrib['Total_Components'] = str(n_build) + attrib['Total_Components'] = str(cfg.n_build) xml = ElementTree.Element('KiCad_BOM', attrib=attrib, encoding='utf-8') for group in groups: diff --git a/kiplot/kicad/config.py b/kiplot/kicad/config.py index 72089205..f702f2be 100644 --- a/kiplot/kicad/config.py +++ b/kiplot/kicad/config.py @@ -1,5 +1,9 @@ """ KiCad configuration classes. + +Notes about coverage: +I'm excluding all the Darwin and Windows code from coverage. +I don't know how to test it on GitHub CI/CD. """ import os import re @@ -14,7 +18,8 @@ from .. import log # Check python version to determine which version of ConfirParser to import if sys.version_info.major >= 3: import configparser as ConfigParser -else: +else: # pragma: no cover + # For future Python 2 support import ConfigParser logger = log.get_logger(__name__) @@ -71,10 +76,10 @@ class LibAlias(object): lib.descr = un_quote(m.group(5)) return lib - def __str__(self): - if not self.name: - return 'empty LibAlias' - return self.name+' -> `'+self.uri+'`' +# def __str__(self): +# if not self.name: +# return 'empty LibAlias' +# return self.name+' -> `'+self.uri+'`' class KiConf(object): @@ -125,7 +130,7 @@ class KiConf(object): cfg = os.path.join(home, '.config', 'kicad', KICAD_COMMON) if os.path.isfile(cfg): return cfg - elif system == 'Darwin': + elif system == 'Darwin': # pragma: no cover # MacOSX: ~/Library/Preferences/kicad/ home = os.environ.get('HOME') if not home: @@ -134,7 +139,7 @@ class KiConf(object): cfg = os.path.join(home, 'Library', 'Preferences', 'kicad', KICAD_COMMON) if os.path.isfile(cfg): return cfg - elif system == 'Windows': + elif system == 'Windows': # pragma: no cover # Windows: C:\Users\username\AppData\Roaming\kicad # or C:\Documents and Settings\username\Application Data\kicad username = os.environ.get('username') @@ -173,7 +178,7 @@ class KiConf(object): dir = os.path.join(sysconfig.get_path('data', 'posix_prefix'), share) if os.path.isdir(dir): return dir - elif system == 'Darwin': + elif system == 'Darwin': # pragma: no cover app_data = os.path.join('Library', 'Application Support', 'kicad', 'library') home = os.environ.get('HOME') if home: @@ -183,7 +188,7 @@ class KiConf(object): dir = os.path.join('/', app_data) if os.path.isdir(dir): return dir - elif system == 'Windows': + elif system == 'Windows': # pragma: no cover dir = os.path.join('C:', 'Program Files', 'KiCad', share) if os.path.isdir(dir): return dir diff --git a/kiplot/out_bom.py b/kiplot/out_bom.py index 4b127056..af1f90fd 100644 --- a/kiplot/out_bom.py +++ b/kiplot/out_bom.py @@ -262,6 +262,8 @@ class BoM(BaseOutput): # noqa: F821 Used to generate the BoM in CSV, HTML, TSV, TXT, XML or XLSX format using the internal BoM. Is compatible with KiBoM, but doesn't need to update the XML netlist because the components are loaded from the schematic. + Important differences with KiBoM output: + - All options are in the main `options` section, not in `conf` subsection. This output is what you get from the 'Tools/Generate Bill of Materials' menu in eeschema. """ def __init__(self): super().__init__()