add shared_bom support

This commit is contained in:
Laurier Loiselle 2023-01-24 17:34:15 -05:00
parent b3a86f4a83
commit bbbf3fb0e9
No known key found for this signature in database
GPG Key ID: 345920CC72089A3F
5 changed files with 42 additions and 8 deletions

View File

@ -26,7 +26,7 @@ Possible group names:
- `tutorial` to process`tutorial/{readme.md,tutorial*.*}` - `tutorial` to process`tutorial/{readme.md,tutorial*.*}`
- `demos` to process`examples/demo*.*` - `demos` to process`examples/demo*.*`
Affected filetypes: `.gv`, `.bom.tsv`, `.png`, `.svg`, `.html` Affected filetypes: `.gv`, `.tsv`, `.png`, `.svg`, `.html`
## Usage hints ## Usage hints

View File

@ -30,6 +30,7 @@ def parse(
output_name: Union[None, str] = None, output_name: Union[None, str] = None,
image_paths: Union[Path, str, List] = [], image_paths: Union[Path, str, List] = [],
extra_metadata: Dict = {}, extra_metadata: Dict = {},
shared_bom: Dict = {},
) -> Any: ) -> Any:
""" """
This function takes an input, parses it as a WireViz Harness file, This function takes an input, parses it as a WireViz Harness file,
@ -114,6 +115,7 @@ def parse(
metadata=Metadata(**yaml_data.get("metadata", {}), **extra_metadata), metadata=Metadata(**yaml_data.get("metadata", {}), **extra_metadata),
options=Options(**yaml_data.get("options", {})), options=Options(**yaml_data.get("options", {})),
tweak=Tweak(**yaml_data.get("tweak", {})), tweak=Tweak(**yaml_data.get("tweak", {})),
shared_bom=shared_bom,
) )
# others # others
# store mapping of components to their respective template # store mapping of components to their respective template

View File

@ -15,7 +15,6 @@ MAX_DESCRIPTION = 40
BomEntry = namedtuple("BomEntry", "category qty designators") BomEntry = namedtuple("BomEntry", "category qty designators")
BomHash = namedtuple("BomHash", BOM_HASH_FIELDS) BomHash = namedtuple("BomHash", BOM_HASH_FIELDS)
BomHashList = namedtuple("BomHashList", BOM_HASH_FIELDS)
PartNumberInfo = namedtuple("PartNumberInfo", "pn manufacturer mpn supplier spn") PartNumberInfo = namedtuple("PartNumberInfo", "pn manufacturer mpn supplier spn")
# TODO: different BOM modes # TODO: different BOM modes

View File

@ -21,6 +21,7 @@ format_codes = {
"P": "pdf", "P": "pdf",
"s": "svg", "s": "svg",
"t": "tsv", "t": "tsv",
"b": "shared_bom",
} }
@ -119,6 +120,8 @@ def cli(file, format, prepend, output_dir, output_name, version):
else: else:
prepend_input = "" prepend_input = ""
harness = None
shared_bom = {}
sheet_current = 1 sheet_current = 1
# run WireVIz on each input file # run WireVIz on each input file
for file in filepaths: for file in filepaths:
@ -151,14 +154,20 @@ def cli(file, format, prepend, output_dir, output_name, version):
for p in prepend: for p in prepend:
image_paths.add(Path(p).parent) image_paths.add(Path(p).parent)
wv.parse( harness = wv.parse(
yaml_input, yaml_input,
output_formats=output_formats, return_types=("harness"),
output_formats=[f for f in output_formats if f != "shared_bom"],
output_dir=_output_dir, output_dir=_output_dir,
output_name=_output_name, output_name=_output_name,
image_paths=list(image_paths), image_paths=list(image_paths),
extra_metadata=extra_metadata, extra_metadata=extra_metadata,
shared_bom=shared_bom,
) )
if "shared_bom" in output_formats:
_output_dir = file.parent if not output_dir else output_dir
harness.output(str(Path(_output_dir) / "shared_bom"), fmt="shared_bom")
shared_bom = harness.shared_bom
print() # blank line after execution print() # blank line after execution

View File

@ -3,7 +3,7 @@
from collections import defaultdict from collections import defaultdict
from dataclasses import dataclass, field from dataclasses import dataclass, field
from pathlib import Path from pathlib import Path
from typing import List from typing import Dict, List
from graphviz import Graph from graphviz import Graph
@ -45,6 +45,7 @@ class Harness:
options: Options options: Options
tweak: Tweak tweak: Tweak
additional_bom_items: List[AdditionalComponent] = field(default_factory=list) additional_bom_items: List[AdditionalComponent] = field(default_factory=list)
shared_bom: Dict = field(default_factory=dict)
def __post_init__(self): def __post_init__(self):
self.connectors = {} self.connectors = {}
@ -119,9 +120,21 @@ class Harness:
), # x[0] = key, x[1] = value ), # x[0] = key, x[1] = value
) )
) )
# assign BOM IDs
for id, key in enumerate(self.bom.keys(), 1): next_id = len(self.shared_bom) + 1
self.bom[key]["id"] = id # TODO: for each harness, track a (harness_name, qty) pair
for key, values in self.bom.items():
if key in self.shared_bom:
self.shared_bom[key]["qty"] += values["qty"]
values["id"] = self.shared_bom[key]["id"]
continue
self.shared_bom[key] = values
self.shared_bom[key]["id"] = next_id
values["id"] = next_id
next_id += 1
# print(f'bom length: {len(self.bom)}, shared_bom length: {len(self.shared_bom)}') # for debugging
# set BOM IDs within components (for BOM bubbles) # set BOM IDs within components (for BOM bubbles)
for item in all_bom_relevant_items: for item in all_bom_relevant_items:
if item.ignore_in_bom: if item.ignore_in_bom:
@ -131,6 +144,12 @@ class Harness:
continue continue
item.bom_id = self.bom[item.bom_hash]["id"] item.bom_id = self.bom[item.bom_hash]["id"]
self.bom = dict(
sorted(
self.bom.items(),
key=lambda x: (x[1]["id"],),
)
)
# print_bom_table(self.bom) # for debugging # print_bom_table(self.bom) # for debugging
def _add_to_internal_bom(self, item: Component): def _add_to_internal_bom(self, item: Component):
@ -412,6 +431,11 @@ class Harness:
if "csv" in fmt: if "csv" in fmt:
# TODO: implement CSV output (preferrably using CSV library) # TODO: implement CSV output (preferrably using CSV library)
print("CSV output is not yet supported") print("CSV output is not yet supported")
if "shared_bom" in fmt:
shared_bomlist = bom_list(self.shared_bom)
shared_bom_tsv = bom2tsv(shared_bomlist)
open_file_write(f"{filename}.tsv").write(shared_bom_tsv)
# HTML output # HTML output
if "html" in fmt: if "html" in fmt:
generate_html_output(filename, bomlist, self.metadata, self.options) generate_html_output(filename, bomlist, self.metadata, self.options)