Internal BoM: Added customizable extra info after the title

Closes #199
This commit is contained in:
Salvador E. Tropea 2022-05-20 19:08:20 -03:00
parent fb082fcbb3
commit bb6e962f3d
15 changed files with 185 additions and 114 deletions

View File

@ -10,7 +10,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- New outputs:
- KiCad netlist generation
- IPC-D-356 netlist generation (#197)
- Pattern and text variables expansion on internal BoM title (#198)
- Internal BoM:
- Pattern and text variables expansion in the title (#198)
- Customizable extra info after the title (#199)
### Fixed
- Already configured outputs not created (i.e. when creating reports)

View File

@ -137,13 +137,13 @@ Notes:
[**ImageMagick**](https://imagemagick.org/) (tool) [Debian](https://packages.debian.org/bullseye/imagemagick)
- Optional to:
- Create monochrome prints for `pcb_print`
- Create JPG images for `pcbdraw`
- Create monochrome prints for `pcb_print`
[**RSVG tools**](https://cran.r-project.org/web/packages/rsvg/index.html) (tool) [Debian](https://packages.debian.org/bullseye/librsvg2-bin)
- Optional to:
- Create PDF, PNG, EPS and PS formats for `pcb_print`
- Create PNG and JPG images for `pcbdraw`
- Create PDF, PNG, EPS and PS formats for `pcb_print`
[**Ghostscript**](https://www.ghostscript.com/) (tool) [Debian](https://packages.debian.org/bullseye/ghostscript)
- Optional to create PS files for `pcb_print`
@ -1263,6 +1263,7 @@ Next time you need this list just use an alias, like this:
- `col_colors`: [boolean=true] Use colors to show the field type.
- `datasheet_as_link`: [string=''] Column with links to the datasheet.
- `digikey_link`: [string|list(string)=''] Column/s containing Digi-Key part numbers, will be linked to web page.
- `extra_info`: [string|list(string)=''] Information to put after the title and before the pcb and stats info.
- `generate_dnf`: [boolean=true] Generate a separated section for DNF (Do Not Fit) components.
- `hide_pcb_info`: [boolean=false] Hide project information.
- `hide_stats_info`: [boolean=false] Hide statistics information.
@ -1299,6 +1300,7 @@ Next time you need this list just use an alias, like this:
- `col_colors`: [boolean=true] Use colors to show the field type.
- `datasheet_as_link`: [string=''] Column with links to the datasheet.
- `digikey_link`: [string|list(string)=''] Column/s containing Digi-Key part numbers, will be linked to web page.
- `extra_info`: [string|list(string)=''] Information to put after the title and before the pcb and stats info.
- `generate_dnf`: [boolean=true] Generate a separated section for DNF (Do Not Fit) components.
- `hide_pcb_info`: [boolean=false] Hide project information.
- `hide_stats_info`: [boolean=false] Hide statistics information.

View File

@ -239,6 +239,8 @@ outputs:
datasheet_as_link: ''
# [string|list(string)=''] Column/s containing Digi-Key part numbers, will be linked to web page
digikey_link: ''
# [string|list(string)=''] Information to put after the title and before the pcb and stats info
extra_info: ''
# [boolean=true] Generate a separated section for DNF (Do Not Fit) components
generate_dnf: true
# [boolean=false] Hide project information
@ -303,6 +305,8 @@ outputs:
datasheet_as_link: ''
# [string|list(string)=''] Column/s containing Digi-Key part numbers, will be linked to web page
digikey_link: ''
# [string|list(string)=''] Information to put after the title and before the pcb and stats info
extra_info: ''
# [boolean=true] Generate a separated section for DNF (Do Not Fit) components
generate_dnf: true
# [boolean=false] Hide project information

View File

@ -30,6 +30,7 @@ HEAD_COLOR_B = "#0e4e8e"
HEAD_COLOR_B_L = "#3e7ebe"
STYLE_COMMON = (" .cell-title { vertical-align: bottom; }\n"
" .cell-info { vertical-align: top; padding: 1em;}\n"
" .cell-extra-info { vertical-align: top; padding: 1em;}\n"
" .cell-stats { vertical-align: top; padding: 1em;}\n"
" .title { font-size:2.5em; font-weight: bold; }\n"
" .subtitle { font-size:1.5em; font-weight: bold; }\n"
@ -344,6 +345,17 @@ def write_stats(html, cfg):
html.write('</tr>\n')
def write_extra_info(html, cfg):
if not cfg.html.extra_info:
return
html.write('<tr>\n')
html.write(' <td colspan="2" class="cell-extra-info">\n')
for e in cfg.html.extra_info:
html.write(" <b>{}</b><br>\n".format(e))
html.write(' </td>\n')
html.write('</tr>\n')
def write_html(filename, groups, headings, head_names, cfg):
"""
Write BoM out to a HTML file
@ -413,6 +425,8 @@ def write_html(filename, groups, headings, head_names, cfg):
n = 2
if len(cfg.aggregate) > 1:
n += 2*len(cfg.aggregate)
if len(cfg.html.extra_info):
n += 1
html.write(' <td rowspan="{}">\n'.format(n))
if img:
html.write(' <img src="'+img+'" alt="Logo" width="'+str(img_w)+'" height="'+str(img_h)+'">\n')
@ -422,6 +436,7 @@ def write_html(filename, groups, headings, head_names, cfg):
html.write(' <div class="title">'+cfg.html.title+'</div>\n')
html.write(' </td>\n')
html.write('</tr>\n')
write_extra_info(html, cfg)
write_stats(html, cfg)
html.write('</table>\n')

View File

@ -110,9 +110,13 @@ def add_info(worksheet, column_widths, row, col_offset, formats, text, value):
return row + 1
def title_rows(cfg):
return (1 if cfg.xlsx.title else 0)+len(cfg.xlsx.extra_info)
def compute_head_size(cfg):
col_logo = 0 if cfg.xlsx.logo is None else 6
col_info = 1 if cfg.xlsx.title else 0
col_info = title_rows(cfg)
if not (cfg.xlsx.hide_pcb_info and cfg.xlsx.hide_stats_info):
col_info += 5
if len(cfg.aggregate) > 1:
@ -548,6 +552,16 @@ def dis_enable_apis(api_options, cfg):
api_options[api]['enable'] = True
def do_title(cfg, worksheet, col1, length, fmt_title, fmt_info):
r_extra = 0
if cfg.xlsx.title:
worksheet.set_row(0, 32)
worksheet.merge_range(0, col1, 0, length, cfg.xlsx.title, fmt_title)
r_extra = 1
for c, text in enumerate(cfg.xlsx.extra_info):
worksheet.merge_range(c+r_extra, col1, c+r_extra, length, text, fmt_info)
def _create_kicost_sheet(workbook, groups, image_data, fmt_title, fmt_info, fmt_subtitle, fmt_head, fmt_cols, cfg):
if not KICOST_SUPPORT:
logger.warning(W_NOKICOST+'KiCost sheet requested but failed to load KiCost support')
@ -571,7 +585,7 @@ def _create_kicost_sheet(workbook, groups, image_data, fmt_title, fmt_info, fmt_
# Create the worksheets
ws_names = ['Costs', 'Costs (DNF)']
Spreadsheet.PRJ_INFO_ROWS = 5 if len(cfg.aggregate) == 1 else 6
Spreadsheet.PRJ_INFO_START = 1 if len(cfg.aggregate) == 1 else 4
Spreadsheet.PRJ_INFO_START = (1 if len(cfg.aggregate) == 1 else 4)+len(cfg.xlsx.extra_info)
Spreadsheet.ADJUST_ROW_AND_COL_SIZE = True
Spreadsheet.MAX_COL_WIDTH = cfg.xlsx.max_col_width
Spreadsheet.PART_NSEQ_SEPRTR = cfg.ref_separator
@ -648,7 +662,7 @@ def _create_kicost_sheet(workbook, groups, image_data, fmt_title, fmt_info, fmt_
col1 += 1
# PCB & Stats Info
if not (cfg.xlsx.hide_pcb_info and cfg.xlsx.hide_stats_info):
r_info_start = 1 if cfg.xlsx.title else 0
r_info_start = title_rows(cfg)
column_widths = [0]*5 # Column 1 to 5
old_stats = cfg.xlsx.hide_stats_info
cfg.xlsx.hide_stats_info = True
@ -659,9 +673,7 @@ def _create_kicost_sheet(workbook, groups, image_data, fmt_title, fmt_info, fmt_
# Add a worksheet with costs to the spreadsheet
create_worksheet(ss, parts)
# Title
if cfg.xlsx.title:
wks.set_row(0, 32)
wks.merge_range(0, col1, 0, ss.globals_width, cfg.xlsx.title, fmt_title)
do_title(cfg, wks, col1, ss.globals_width, fmt_title, fmt_info[0])
used_parts.append(parts)
# Specs sheets
create_meta_sheets(workbook, used_parts, fmt_head, fmt_cols, cfg, ss)
@ -698,6 +710,7 @@ def write_xlsx(filename, groups, col_fields, head_names, cfg):
"""
if not XLSX_SUPPORT:
logger.error('Python xlsxwriter module not installed (Debian: python3-xlsxwriter)')
logger.error(TRY_INSTALL_CHECK)
return False
link_datasheet = -1
@ -712,8 +725,8 @@ def write_xlsx(filename, groups, col_fields, head_names, cfg):
# Leave space for the logo, title and info
head_size = compute_head_size(cfg)
# First rowe for the information
r_info_start = 1 if cfg.xlsx.title else 0
# First row for the information
r_info_start = title_rows(cfg)
max_width = cfg.xlsx.max_col_width
# #######################
@ -793,9 +806,7 @@ def write_xlsx(filename, groups, col_fields, head_names, cfg):
# Logo
col1 = insert_logo(worksheet, image_data, cfg.xlsx.logo_scale)
# Title
if cfg.xlsx.title:
worksheet.set_row(0, 32)
worksheet.merge_range(0, col1, 0, len(column_widths)-1, cfg.xlsx.title, fmt_title)
do_title(cfg, worksheet, col1, len(column_widths)-1, fmt_title, fmt_info[0])
# PCB & Stats Info
if not (cfg.xlsx.hide_pcb_info and cfg.xlsx.hide_stats_info):
write_info(cfg, r_info_start, worksheet, column_widths, col1, fmt_info, fmt_subtitle)

View File

@ -330,7 +330,7 @@ class Optionable(object):
return Optionable.expand_filename_both(self, name)
@staticmethod
def force_list(val):
def force_list(val, comma_sep=True):
""" Used for values that accept a string or a list of strings.
The string can be a comma separated list """
if isinstance(val, type):
@ -339,7 +339,10 @@ class Optionable(object):
elif isinstance(val, str):
# A string
if val:
val = [v.strip() for v in val.split(',')]
if comma_sep:
val = [v.strip() for v in val.split(',')]
else:
val = [val]
else:
# Empty string
val = []

View File

@ -175,6 +175,8 @@ class BoMLinkable(Optionable):
""" [string|boolean=''] PNG file to use as logo, use false to remove """
self.title = 'KiBot Bill of Materials'
""" BoM title """
self.extra_info = Optionable
""" [string|list(string)=''] Information to put after the title and before the pcb and stats info """
def config(self, parent):
super().config(parent)
@ -192,6 +194,8 @@ class BoMLinkable(Optionable):
self.logo = os.path.abspath(self.logo)
if not os.path.isfile(self.logo):
raise KiPlotConfigurationError('Missing logo file `{}`'.format(self.logo))
# Extra info lines
self.extra_info = Optionable.force_list(self.extra_info, comma_sep=False)
# Datasheet as link
self.datasheet_as_link = self.datasheet_as_link.lower()
@ -313,14 +317,8 @@ class BoMXLSX(BoMLinkable):
if not self.kicost_config:
self.kicost_config = None
# KiCost APIs
if isinstance(self.kicost_api_enable, type):
self.kicost_api_enable = []
elif isinstance(self.kicost_api_enable, str):
self.kicost_api_enable = [self.kicost_api_enable]
if isinstance(self.kicost_api_disable, type):
self.kicost_api_disable = []
elif isinstance(self.kicost_api_disable, str):
self.kicost_api_disable = [self.kicost_api_disable]
self.kicost_api_enable = Optionable.force_list(self.kicost_api_enable)
self.kicost_api_disable = Optionable.force_list(self.kicost_api_disable)
# Specs columns
(self.s_columns, self.s_levels, self.s_comments, self.s_rename,
self.s_join) = self.process_columns_config(self.specs_columns)
@ -604,8 +602,10 @@ class BoMOptions(BaseOptions):
# Here because some variables needs our parent
if self.format == 'html' and self.html.title:
self.html.title = self.expand_filename_both(self.html.title, make_safe=False)
self.html.extra_info = [self.expand_filename_both(t, make_safe=False) for t in self.html.extra_info]
if self.format == 'xlsx' and self.xlsx.title:
self.xlsx.title = self.expand_filename_both(self.xlsx.title, make_safe=False)
self.xlsx.extra_info = [self.expand_filename_both(t, make_safe=False) for t in self.xlsx.extra_info]
# group_fields
if isinstance(self.group_fields, type):
self.group_fields = GroupFields.get_default()

View File

@ -147,21 +147,21 @@ deps = '{\
"name": "ImageMagick",\
"no_cmd_line_version": false,\
"no_cmd_line_version_old": false,\
"output": "pcb_print",\
"output": "pcbdraw",\
"plugin_dirs": null,\
"pypi_name": "ImageMagick",\
"roles": [\
{\
"desc": "Create monochrome prints",\
"mandatory": false,\
"output": "pcb_print",\
"version": null\
},\
{\
"desc": "Create JPG images",\
"mandatory": false,\
"output": "pcbdraw",\
"version": null\
},\
{\
"desc": "Create monochrome prints",\
"mandatory": false,\
"output": "pcb_print",\
"version": null\
}\
],\
"url": "https://imagemagick.org/",\
@ -243,62 +243,10 @@ deps = '{\
"name": "KiCad Automation tools",\
"no_cmd_line_version": false,\
"no_cmd_line_version_old": false,\
"output": "step",\
"output": "svg_pcb_print",\
"plugin_dirs": null,\
"pypi_name": "kiauto",\
"roles": [\
{\
"desc": null,\
"mandatory": true,\
"output": "step",\
"version": [\
1,\
6,\
1\
]\
},\
{\
"desc": null,\
"mandatory": true,\
"output": "netlist",\
"version": [\
1,\
6,\
11\
]\
},\
{\
"desc": null,\
"mandatory": true,\
"output": "render_3d",\
"version": [\
1,\
6,\
8\
]\
},\
{\
"desc": null,\
"mandatory": true,\
"output": "svg_sch_print",\
"version": null\
},\
{\
"desc": null,\
"mandatory": true,\
"output": "pdf_pcb_print",\
"version": [\
1,\
6,\
7\
]\
},\
{\
"desc": null,\
"mandatory": true,\
"output": "pdf_sch_print",\
"version": null\
},\
{\
"desc": null,\
"mandatory": true,\
@ -319,6 +267,58 @@ deps = '{\
5\
]\
},\
{\
"desc": null,\
"mandatory": true,\
"output": "svg_sch_print",\
"version": null\
},\
{\
"desc": null,\
"mandatory": true,\
"output": "pdf_sch_print",\
"version": null\
},\
{\
"desc": null,\
"mandatory": true,\
"output": "pdf_pcb_print",\
"version": [\
1,\
6,\
7\
]\
},\
{\
"desc": null,\
"mandatory": true,\
"output": "netlist",\
"version": [\
1,\
6,\
11\
]\
},\
{\
"desc": null,\
"mandatory": true,\
"output": "step",\
"version": [\
1,\
6,\
1\
]\
},\
{\
"desc": null,\
"mandatory": true,\
"output": "render_3d",\
"version": [\
1,\
6,\
8\
]\
},\
{\
"desc": null,\
"mandatory": true,\
@ -328,13 +328,13 @@ deps = '{\
{\
"desc": null,\
"mandatory": true,\
"output": "run_drc",\
"output": "update_xml",\
"version": null\
},\
{\
"desc": null,\
"mandatory": true,\
"output": "update_xml",\
"output": "run_drc",\
"version": null\
}\
],\
@ -353,20 +353,10 @@ deps = '{\
"name": "KiCost",\
"no_cmd_line_version": false,\
"no_cmd_line_version_old": false,\
"output": "bom",\
"output": "kicost",\
"plugin_dirs": null,\
"pypi_name": "KiCost",\
"roles": [\
{\
"desc": "Find components costs and specs",\
"mandatory": false,\
"output": "bom",\
"version": [\
1,\
1,\
8\
]\
},\
{\
"desc": null,\
"mandatory": true,\
@ -376,6 +366,16 @@ deps = '{\
1,\
7\
]\
},\
{\
"desc": "Find components costs and specs",\
"mandatory": false,\
"output": "bom",\
"version": [\
1,\
1,\
8\
]\
}\
],\
"url": "https://github.com/INTI-CMNB/KiCost",\
@ -559,21 +559,21 @@ deps = '{\
"name": "RSVG tools",\
"no_cmd_line_version": false,\
"no_cmd_line_version_old": false,\
"output": "pcb_print",\
"output": "pcbdraw",\
"plugin_dirs": null,\
"pypi_name": "RSVG tools",\
"roles": [\
{\
"desc": "Create PDF, PNG, EPS and PS formats",\
"mandatory": false,\
"output": "pcb_print",\
"version": null\
},\
{\
"desc": "Create PNG and JPG images",\
"mandatory": false,\
"output": "pcbdraw",\
"version": null\
},\
{\
"desc": "Create PDF, PNG, EPS and PS formats",\
"mandatory": false,\
"output": "pcb_print",\
"version": null\
}\
],\
"url": "https://cran.r-project.org/web/packages/rsvg/index.html",\

View File

@ -1,4 +1,6 @@
,,,KiBot Bill of Materials,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,kibom-variant_2c,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,, 2021-04-06,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,Schematic:,kibom-variant_2c,,,,,Board Qty:,50,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,Variant:,default,,,,,Unit Cost:,0.002,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,Revision:,A,,,,,Total Cost:,0.1,,,,,0,0 of 1 parts found,,,,,0.61,1 of 1 parts found,,,,,0.7292,1 of 1 parts found,,,,,0,0 of 1 parts found,,,,,0.5,1 of 1 parts found,,,,,0.1,1 of 1 parts found,,,,,0,0 of 1 parts found,,,,,0,0 of 1 parts found,,,,,0,0 of 1 parts found

1 KiBot Bill of Materials
2 kibom-variant_2c
3 2021-04-06
4 Schematic: kibom-variant_2c Board Qty: 50
5 Variant: default Unit Cost: 0.002
6 Revision: A Total Cost: 0.1 0 0 of 1 parts found 0.61 1 of 1 parts found 0.7292 1 of 1 parts found 0 0 of 1 parts found 0.5 1 of 1 parts found 0.1 1 of 1 parts found 0 0 of 1 parts found 0 0 of 1 parts found 0 0 of 1 parts found

View File

@ -1,4 +1,6 @@
,,,KiBot Bill of Materials,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,kibom-variant_2c,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,, 2021-04-06,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,Schematic:,kibom-variant_2c,,,,,Board Qty:,50,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,Variant:,default,,,,,Unit Cost:,0.0098,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,Revision:,A,,,,,Total Cost:,0.49,,,,,0,0 of 1 parts found,,,,,1.66,1 of 1 parts found,,,,,2.0089,1 of 1 parts found,,,,,0.49,1 of 1 parts found,,,,,1.8,1 of 1 parts found,,,,,1.8,1 of 1 parts found,,,,,0,1 of 1 parts found,,,,,2.2725,1 of 1 parts found,,,,,0,0 of 1 parts found

1 KiBot Bill of Materials
2 kibom-variant_2c
3 2021-04-06
4 Schematic: kibom-variant_2c Board Qty: 50
5 Variant: default Unit Cost: 0.0098
6 Revision: A Total Cost: 0.49 0 0 of 1 parts found 1.66 1 of 1 parts found 2.0089 1 of 1 parts found 0.49 1 of 1 parts found 1.8 1 of 1 parts found 1.8 1 of 1 parts found 0 1 of 1 parts found 2.2725 1 of 1 parts found 0 0 of 1 parts found

View File

@ -156,13 +156,18 @@ def check_path(rows, comp, ref, sp, val):
return
def check_head_xlsx(r, info, stats, title=DEF_TITLE):
def check_head_xlsx(r, info, stats, title=DEF_TITLE, extra_info=None):
rn = 0
if title:
# First row is just the title
assert r[rn][0] == title
rn += 1
logging.debug('Title Ok')
if extra_info:
for e in extra_info:
assert r[rn][0] == e
rn += 1
logging.debug('Extra `{}` Ok'.format(e))
if info:
info_col = 0
for i, txt in enumerate(info):
@ -180,7 +185,7 @@ def check_head_xlsx(r, info, stats, title=DEF_TITLE):
logging.debug('Stats block Ok')
def check_head_html(r, info, stats, title, logo):
def check_head_html(r, info, stats, title, logo, extra_info):
if title:
assert 'title' in r
assert r['title'] == title
@ -194,6 +199,15 @@ def check_head_html(r, info, stats, title, logo):
else:
assert 'logo' not in r
logging.debug('No logo Ok')
if extra_info:
assert 'extra_info' in r
extra = r['extra_info']
for i, val in enumerate(extra_info):
assert extra[i] == val
logging.debug('Extra info Ok')
else:
assert 'extra_info' not in r
logging.debug('No extra info Ok')
if info:
assert 'info' in r
for i, tit in enumerate(INFO_ROWS):
@ -323,13 +337,13 @@ def test_int_bom_simple_txt(test_dir):
def simple_html_test(ctx, rows, headers, sh_head, prj, do_title=True, do_logo=True, do_info=True, do_stats=True,
a_title=DEF_TITLE):
a_title=DEF_TITLE, extra_info=None):
title = a_title if do_title else None
info = KIBOM_PRJ_INFO if do_info else None
stats = None
if do_stats:
stats = KIBOM_STATS
check_head_html(sh_head, info, stats, title=title, logo=do_logo)
check_head_html(sh_head, info, stats, title=title, logo=do_logo, extra_info=extra_info)
# Test we got the normal and DNF tables
assert len(rows) == 2
assert len(headers) == 2
@ -362,7 +376,7 @@ def simple_html_setup(test_dir, name, ret_val=0):
def test_int_bom_simple_html_1(test_dir):
(rows, headers, sh_head), prj, ctx = simple_html_setup(test_dir, 'int_bom_simple_html_1')
simple_html_test(ctx, rows, headers, sh_head, prj)
simple_html_test(ctx, rows, headers, sh_head, prj, extra_info=['Extra 1: '+prj, 'Extra 2: 2020-03-12'])
def test_int_bom_simple_html_2(test_dir):
@ -442,12 +456,12 @@ def test_int_bom_simple_xml(test_dir):
ctx.clean_up()
def simple_xlsx_verify(ctx, prj, dnf=True, title=DEF_TITLE):
def simple_xlsx_verify(ctx, prj, dnf=True, title=DEF_TITLE, extra_info=None):
ext = 'xlsx'
ctx.run()
out = prj + '-bom.' + ext
rows, header, sh_head = ctx.load_xlsx(out)
check_head_xlsx(sh_head, KIBOM_PRJ_INFO, KIBOM_STATS, title=title)
check_head_xlsx(sh_head, KIBOM_PRJ_INFO, KIBOM_STATS, title=title, extra_info=extra_info)
assert header == KIBOM_TEST_HEAD
ref_column = header.index(REF_COLUMN_NAME)
status_column = header.index(STATUS_COLUMN_NAME)
@ -464,7 +478,7 @@ def simple_xlsx_verify(ctx, prj, dnf=True, title=DEF_TITLE):
def test_int_bom_simple_xlsx_1(test_dir):
prj = 'kibom-test'
ctx = context.TestContextSCH(test_dir, 'test_int_bom_simple_xlsx', prj, 'int_bom_simple_xlsx', BOM_DIR)
simple_xlsx_verify(ctx, prj)
simple_xlsx_verify(ctx, prj, extra_info=['Extra 1: '+prj, 'Extra 2: 2020-03-12'])
def get_column(rows, col, split=True):

View File

@ -591,6 +591,15 @@ class TestContext(object):
inf_entries.append(val)
if inf_entries:
sh_head['info'] = inf_entries
# Extract extra info
m = re.search(r'<td colspan="2" class="cell-extra-info">((?:\s+.*?)+)</td>', body, re.MULTILINE)
if m:
info = m.group(1)
inf_entries = []
for val in re.findall('<b>(.*?)</b><br>', info):
inf_entries.append(val)
if inf_entries:
sh_head['extra_info'] = inf_entries
# Extract stats
m = re.search(r'<td class="cell-stats">((?:\s+.*?)+)</td>', body, re.MULTILINE)
if m:

View File

@ -37,3 +37,4 @@ outputs:
xlsx:
kicost: true
kicost_config: tests/data/kicost_default_config.yaml
extra_info: ['%f', ' %d']

View File

@ -8,5 +8,8 @@ outputs:
type: bom
dir: BoM
options:
format: HTML
variant: ''
html:
extra_info:
- 'Extra 1: %f'
- 'Extra 2: %d'

View File

@ -8,4 +8,7 @@ outputs:
type: bom
dir: BoM
options:
format: XLSX
xlsx:
extra_info:
- 'Extra 1: %f'
- 'Extra 2: %d'