diff --git a/src/wireviz/wireviz.py b/src/wireviz/wireviz.py index 83dba1e..102a203 100755 --- a/src/wireviz/wireviz.py +++ b/src/wireviz/wireviz.py @@ -9,12 +9,13 @@ import sys from typing import Any, List import yaml -if __name__== '__main__': +if __name__ == '__main__': sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) from wireviz import wv_colors from wireviz.wv_helper import nested, int2tuple, awg_equiv, flatten2d, tuplelist2tsv + class Harness: def __init__(self): @@ -44,38 +45,38 @@ class Harness: dot.body.append('// https://github.com/formatc1702/WireViz') font = 'arial' dot.attr('graph', rankdir='LR', - ranksep='2', - bgcolor='white', - nodesep='0.33', - fontname=font) + ranksep='2', + bgcolor='white', + nodesep='0.33', + fontname=font) dot.attr('node', shape='record', - style='filled', - fillcolor='white', - fontname=font) + style='filled', + fillcolor='white', + fontname=font) dot.attr('edge', style='bold', - fontname=font) + fontname=font) # prepare ports on connectors depending on which side they will connect for k, c in self.cables.items(): for x in c.connections: - if x.from_port is not None: # connect to left + if x.from_port is not None: # connect to left self.connectors[x.from_name].ports_right = True - if x.to_port is not None: # connect to right + if x.to_port is not None: # connect to right self.connectors[x.to_name].ports_left = True for k, n in self.connectors.items(): if n.category == 'ferrule': infostring = '{type}{subtype} {color}'.format(type=n.type, - subtype=', {}'.format(n.subtype) if n.subtype else '', - color=wv_colors.translate_color(n.color, self.color_mode) if n.color else '') + subtype=', {}'.format(n.subtype) if n.subtype else '', + color=wv_colors.translate_color(n.color, self.color_mode) if n.color else '') infostring_l = infostring if n.ports_right else '' infostring_r = infostring if n.ports_left else '' dot.node(k, shape='none', - style='filled', - margin='0', - orientation = '0' if n.ports_left else '180', - label='''< + style='filled', + margin='0', + orientation='0' if n.ports_left else '180', + label='''< @@ -85,16 +86,16 @@ class Harness: >'''.format(infostring_l=infostring_l, - infostring_r=infostring_r, - colorbar=''.format(wv_colors.translate_color(n.color, 'HEX')) if n.color else '')) + infostring_r=infostring_r, + colorbar=''.format(wv_colors.translate_color(n.color, 'HEX')) if n.color else '')) - else: # not a ferrule + else: # not a ferrule # a = attributes a = [n.type, n.subtype, '{}-pin'.format(n.pincount) if n.show_pincount else ''] # p = pinout - p = [[],[],[]] + p = [[], [], []] for pinnumber, pinname in zip(n.pinnumbers, n.pinout): if n.hide_disconnected_pins and not n.visible_pins.get(pinnumber, False): continue @@ -108,7 +109,7 @@ class Harness: dot.node(k, label=nested(l)) if len(n.loops) > 0: - dot.attr('edge',color='#000000:#ffffff:#000000') + dot.attr('edge', color='#000000:#ffffff:#000000') if n.ports_left: loop_side = 'l' loop_dir = 'w' @@ -124,27 +125,28 @@ class Harness: for k, c in self.cables.items(): # a = attributes a = ['{}x'.format(len(c.colors)) if c.show_wirecount else '', - '{} {}{}'.format(c.gauge, c.gauge_unit, ' ({} AWG)'.format(awg_equiv(c.gauge)) if c.gauge_unit == 'mm\u00B2' and c.show_equiv else '') if c.gauge else '', # TODO: show equiv + '{} {}{}'.format(c.gauge, c.gauge_unit, ' ({} AWG)'.format(awg_equiv(c.gauge)) if c.gauge_unit == + 'mm\u00B2' and c.show_equiv else '') if c.gauge else '', # TODO: show equiv '+ S' if c.shield else '', '{} m'.format(c.length) if c.length > 0 else ''] a = list(filter(None, a)) - html = '
{infostring_l}
' # name+attributes table - html = html + '' # spacer between attributes and wires + html = html + '' # spacer between attributes and wires - html = html + '' # main table if c.notes: - html = html + ''.format(c.notes) # notes table - html = html + '' # spacer at the end + html = html + ''.format(c.notes) # notes table + html = html + '' # spacer at the end html = html + '
' # main table + html = '' # name+attributes table + html = html + '' # attribute row + html = html + '
' # main table - html = html + '' # name+attributes table + html = html + '
' # name+attributes table if c.show_name: html = html + ''.format(colspan=len(a), name=c.name) - html = html + '' # attribute row + html = html + '' # attribute row for attrib in a: html = html + ''.format(attrib=attrib) - html = html + '' # attribute row - html = html + '
{name}
{attrib}
 
 
' # conductor table + html = html + '
' # conductor table - for i, x in enumerate(c.colors,1): + for i, x in enumerate(c.colors, 1): p = [] p.append(''.format(i)) p.append(wv_colors.translate_color(x, self.color_mode)) @@ -154,55 +156,63 @@ class Harness: html = html + ''.format(bla) html = html + '' bgcolor = wv_colors.translate_color(x, 'hex') - html = html + ''.format(colspan=len(p), bgcolor=bgcolor if bgcolor != '' else '#ffffff', port='w{}'.format(i)) + html = html + ''.format( + colspan=len(p), bgcolor=bgcolor if bgcolor != '' else '#ffffff', port='w{}'.format(i)) if c.shield: p = ['', 'Shield', ''] - html = html + '' # spacer + html = html + '' # spacer html = html + '' for bla in p: html = html + ''.format(bla) html = html + '' - html = html + ''.format(colspan=len(p), bgcolor=wv_colors.translate_color(x, 'hex'), port='ws') + html = html + ''.format( + colspan=len(p), bgcolor=wv_colors.translate_color(x, 'hex'), port='ws') - html = html + '' # spacer at the end + html = html + '' # spacer at the end - html = html + '
{}
 
 
{}
 
 
' # conductor table + html = html + '
' # conductor table html = html + '
{}
 
{}
 
' # main table # connections for x in c.connections: - if isinstance(x.via_port, int): # check if it's an actual wire and not a shield - search_color = c.colors[x.via_port-1] + if isinstance(x.via_port, int): # check if it's an actual wire and not a shield + search_color = c.colors[x.via_port - 1] if search_color in wv_colors.color_hex: - dot.attr('edge',color='#000000:{wire_color}:#000000'.format(wire_color=wv_colors.color_hex[search_color])) - else: # color name not found - dot.attr('edge',color='#000000:#ffffff:#000000') - else: # it's a shield connection - dot.attr('edge',color='#000000') + dot.attr('edge', color='#000000:{wire_color}:#000000'.format( + wire_color=wv_colors.color_hex[search_color])) + else: # color name not found + dot.attr('edge', color='#000000:#ffffff:#000000') + else: # it's a shield connection + dot.attr('edge', color='#000000') - if x.from_port is not None: # connect to left + if x.from_port is not None: # connect to left from_ferrule = self.connectors[x.from_name].category == 'ferrule' - code_left_1 = '{from_name}{from_port}:e'.format(from_name=x.from_name, from_port=':p{}r'.format(x.from_port) if not from_ferrule else '') - code_left_2 = '{via_name}:w{via_wire}:w'.format(via_name=c.name, via_wire=x.via_port, via_subport='i' if c.show_pinout else '') + code_left_1 = '{from_name}{from_port}:e'.format( + from_name=x.from_name, from_port=':p{}r'.format(x.from_port) if not from_ferrule else '') + code_left_2 = '{via_name}:w{via_wire}:w'.format( + via_name=c.name, via_wire=x.via_port, via_subport='i' if c.show_pinout else '') dot.edge(code_left_1, code_left_2) from_string = '{}:{}'.format(x.from_name, x.from_port) if not from_ferrule else '' html = html.replace(''.format(x.via_port), from_string) - if x.to_port is not None: # connect to right + if x.to_port is not None: # connect to right to_ferrule = self.connectors[x.to_name].category == 'ferrule' - code_right_1 = '{via_name}:w{via_wire}:e'.format(via_name=c.name, via_wire=x.via_port, via_subport='o' if c.show_pinout else '') - code_right_2 = '{to_name}{to_port}:w'.format(to_name=x.to_name, to_port=':p{}l'.format(x.to_port) if not to_ferrule else '') + code_right_1 = '{via_name}:w{via_wire}:e'.format( + via_name=c.name, via_wire=x.via_port, via_subport='o' if c.show_pinout else '') + code_right_2 = '{to_name}{to_port}:w'.format( + to_name=x.to_name, to_port=':p{}l'.format(x.to_port) if not to_ferrule else '') dot.edge(code_right_1, code_right_2) to_string = '{}:{}'.format(x.to_name, x.to_port) if not to_ferrule else '' html = html.replace(''.format(x.via_port), to_string) - dot.node(c.name, label='<{html}>'.format(html=html), shape='box', style='filled,dashed' if c.category=='bundle' else '', margin='0', fillcolor='white') + dot.node(c.name, label='<{html}>'.format(html=html), shape='box', + style='filled,dashed' if c.category == 'bundle' else '', margin='0', fillcolor='white') return dot @@ -215,14 +225,14 @@ class Harness: d.save(filename='{}.gv'.format(filename), directory=directory) # bom output bom_list = self.bom_list() - with open('{}.bom.tsv'.format(filename),'w') as file: + with open('{}.bom.tsv'.format(filename), 'w') as file: file.write(tuplelist2tsv(bom_list)) # HTML output - with open('{}.html'.format(filename),'w') as file: + with open('{}.html'.format(filename), 'w') as file: file.write('') file.write('

Diagram

') - with open('{}.svg'.format(filename),'r') as svg: + with open('{}.svg'.format(filename), 'r') as svg: for l in svg: file.write(l) @@ -236,7 +246,8 @@ class Harness: for row in listy[1:]: file.write('') for i, item in enumerate(row): - file.write('{content}'.format(content=item, align='align="right"' if listy[0][i] == 'Qty' else '')) + file.write('{content}'.format( + content=item, align='align="right"' if listy[0][i] == 'Qty' else '')) file.write('') file.write('') @@ -249,30 +260,35 @@ class Harness: # connectors types = Counter([(v.type, v.subtype, v.pincount) for v in self.connectors.values()]) for type in types: - items = {k: v for k, v in self.connectors.items() if (v.type, v.subtype, v.pincount) == type} + items = {k: v for k, v in self.connectors.items() if (v.type, v.subtype, v.pincount) == type} shared = next(iter(items.values())) designators = list(items.keys()) designators.sort() - name = 'Connector{type}{subtype}{pincount}{color}'.format(type = ', {}'.format(shared.type) if shared.type else '', - subtype = ', {}'.format(shared.subtype) if shared.subtype else '', - pincount = ', {} pins'.format(shared.pincount) if shared.category != 'ferrule' else '', - color = ', {}'.format(shared.color) if shared.color else '') - item = {'item': name, 'qty': len(designators), 'unit': '', 'designators': designators if shared.category != 'ferrule' else ''} + name = 'Connector{type}{subtype}{pincount}{color}'.format(type=', {}'.format(shared.type) if shared.type else '', + subtype=', {}'.format( + shared.subtype) if shared.subtype else '', + pincount=', {} pins'.format( + shared.pincount) if shared.category != 'ferrule' else '', + color=', {}'.format(shared.color) if shared.color else '') + item = {'item': name, 'qty': len(designators), 'unit': '', + 'designators': designators if shared.category != 'ferrule' else ''} bom_connectors.append(item) - bom_connectors = sorted(bom_connectors, key=lambda k: k['item']) # https://stackoverflow.com/a/73050 + bom_connectors = sorted(bom_connectors, key=lambda k: k['item']) # https://stackoverflow.com/a/73050 bom.extend(bom_connectors) # cables types = Counter([(v.category, v.gauge, v.gauge_unit, v.wirecount, v.shield) for v in self.cables.values()]) for type in types: - items = {k: v for k, v in self.cables.items() if (v.category, v.gauge, v.gauge_unit, v.wirecount, v.shield) == type} + items = {k: v for k, v in self.cables.items() if ( + v.category, v.gauge, v.gauge_unit, v.wirecount, v.shield) == type} shared = next(iter(items.values())) if shared.category != 'bundle': designators = list(items.keys()) designators.sort() total_length = sum(i.length for i in items.values()) - name = 'Cable, {wirecount}{gauge}{shield}'.format(wirecount = shared.wirecount, - gauge = ' x {} {}'.format(shared.gauge, shared.gauge_unit) if shared.gauge else ' wires', - shield = ' shielded' if shared.shield else '') + name = 'Cable, {wirecount}{gauge}{shield}'.format(wirecount=shared.wirecount, + gauge=' x {} {}'.format( + shared.gauge, shared.gauge_unit) if shared.gauge else ' wires', + shield=' shielded' if shared.shield else '') item = {'item': name, 'qty': round(total_length, 3), 'unit': 'm', 'designators': designators} bom_cables.append(item) # bundles (ignores wirecount) @@ -287,7 +303,8 @@ class Harness: for bundle in items.values(): # add each wire from each bundle to the wirelist for color in bundle.colors: - wirelist.append({'gauge': shared.gauge, 'gauge_unit': shared.gauge_unit, 'length': shared.length, 'color': color, 'designator': bundle.name}) + wirelist.append({'gauge': shared.gauge, 'gauge_unit': shared.gauge_unit, + 'length': shared.length, 'color': color, 'designator': bundle.name}) # join similar wires from all the bundles to a single BOM item types = Counter([(v['gauge'], v['gauge_unit'], v['color']) for v in wirelist]) for type in types: @@ -299,10 +316,10 @@ class Harness: designators.sort() total_length = sum(i['length'] for i in items) name = 'Wire{gauge}{color}'.format(gauge=', {} {}'.format(shared['gauge'], shared['gauge_unit']) if shared['gauge'] else '', - color=', {}'.format(shared['color']) if shared['color'] != '' else '') + color=', {}'.format(shared['color']) if shared['color'] != '' else '') item = {'item': name, 'qty': round(total_length, 3), 'unit': 'm', 'designators': designators} bom_cables.append(item) - bom_cables = sorted(bom_cables, key=lambda k: k['item']) # https://stackoverflow.com/a/73050 + bom_cables = sorted(bom_cables, key=lambda k: k['item']) # https://stackoverflow.com/a/73050 bom.extend(bom_cables) return bom @@ -310,15 +327,16 @@ class Harness: bom = self.bom() keys = ['item', 'qty', 'unit', 'designators'] bom_list = [] - bom_list.append([k.capitalize() for k in keys]) # create header row with keys + bom_list.append([k.capitalize() for k in keys]) # create header row with keys for item in bom: - item_list = [item.get(key, '') for key in keys] # fill missing values with blanks + item_list = [item.get(key, '') for key in keys] # fill missing values with blanks for i, subitem in enumerate(item_list): - if isinstance(subitem, List): # convert any lists into comma separated strings + if isinstance(subitem, List): # convert any lists into comma separated strings item_list[i] = ', '.join(subitem) bom_list.append(item_list) return bom_list + @dataclass class Connector: name: str @@ -356,7 +374,7 @@ class Connector: # create default lists for pinnumbers (sequential) and pinouts (blank) if not specified if not self.pinnumbers: - self.pinnumbers = list(range(1,self.pincount + 1)) + self.pinnumbers = list(range(1, self.pincount + 1)) if not self.pinout: self.pinout = [''] * self.pincount @@ -369,13 +387,14 @@ class Connector: def activate_pin(self, pin): self.visible_pins[pin] = True + @dataclass class Cable: name: str - category : str = None + category: str = None type: str = None gauge: float = None - gauge_unit : str = None + gauge_unit: str = None show_equiv: bool = False length: float = 0 wirecount: int = None @@ -389,38 +408,38 @@ class Cable: def __post_init__(self): - if isinstance(self.gauge, str): # gauge and unit specified + if isinstance(self.gauge, str): # gauge and unit specified try: g, u = self.gauge.split(' ') except: raise Exception('Gauge must be a number, or number and unit separated by a space') self.gauge = g - self.gauge_unit = u.replace('mm2','mm\u00B2') - elif self.gauge is not None: # gauge specified, assume mm2 + self.gauge_unit = u.replace('mm2', 'mm\u00B2') + elif self.gauge is not None: # gauge specified, assume mm2 if self.gauge_unit is None: self.gauge_unit = 'mm\u00B2' else: - pass # gauge not specified + pass # gauge not specified self.connections = [] - if self.wirecount: # number of wires explicitly defined - if self.colors: # use custom color palette (partly or looped if needed) + if self.wirecount: # number of wires explicitly defined + if self.colors: # use custom color palette (partly or looped if needed) pass - elif self.color_code: # use standard color palette (partly or looped if needed) + elif self.color_code: # use standard color palette (partly or looped if needed) if self.color_code not in wv_colors.COLOR_CODES: raise Exception('Unknown color code') self.colors = wv_colors.COLOR_CODES[self.color_code] - else: # no colors defined, add dummy colors + else: # no colors defined, add dummy colors self.colors = [''] * self.wirecount # make color code loop around if more wires than colors if self.wirecount > len(self.colors): - m = self.wirecount // len(self.colors) + 1 - self.colors = self.colors * int(m) + m = self.wirecount // len(self.colors) + 1 + self.colors = self.colors * int(m) # cut off excess after looping self.colors = self.colors[:self.wirecount] - else: # wirecount implicit in length of color list + else: # wirecount implicit in length of color list if not self.colors: raise Exception('Unknown number of wires. Must specify wirecount or colors (implicit length)') self.wirecount = len(self.colors) @@ -430,21 +449,23 @@ class Cable: def connect(self, from_name, from_pin, via_pin, to_name, to_pin): from_pin = int2tuple(from_pin) - via_pin = int2tuple(via_pin) - to_pin = int2tuple(to_pin) + via_pin = int2tuple(via_pin) + to_pin = int2tuple(to_pin) if len(from_pin) != len(to_pin): raise Exception('from_pin must have the same number of elements as to_pin') for i, x in enumerate(from_pin): # self.connections.append((from_name, from_pin[i], via_pin[i], to_name, to_pin[i])) self.connections.append(Connection(from_name, from_pin[i], via_pin[i], to_name, to_pin[i])) + @dataclass class Connection: from_name: Any from_port: Any - via_port: Any - to_name: Any - to_port: Any + via_port: Any + to_name: Any + to_port: Any + def parse(yaml_input, file_out=None, generate_bom=False): @@ -457,16 +478,16 @@ def parse(yaml_input, file_out=None, generate_bom=False): # if str is of the format '#-#', it is treated as a range (inclusive) and expanded output = [] if not isinstance(yaml_data, list): - yaml_data = [yaml_data,] + yaml_data = [yaml_data, ] for e in yaml_data: e = str(e) - if '-' in e: # list of pins + if '-' in e: # list of pins a, b = tuple(map(int, e.split('-'))) if a < b: - for x in range(a,b+1): + for x in range(a, b + 1): output.append(x) elif a > b: - for x in range(a,b-1,-1): + for x in range(a, b - 1, -1): output.append(x) elif a == b: output.append(a) @@ -487,8 +508,8 @@ def parse(yaml_input, file_out=None, generate_bom=False): h = Harness() # add items - sections = ['connectors','cables','ferrules','connections'] - types = [dict, dict, dict, list] + sections = ['connectors', 'cables', 'ferrules', 'connections'] + types = [dict, dict, dict, list] for sec, ty in zip(sections, types): if sec in yaml_data and type(yaml_data[sec]) == ty: if len(yaml_data[sec]) > 0: @@ -501,8 +522,8 @@ def parse(yaml_input, file_out=None, generate_bom=False): elif sec == 'ferrules': pass else: - pass # section exists but is empty - else: # section does not exist, create empty section + pass # section exists but is empty + else: # section does not exist, create empty section if ty == dict: yaml_data[sec] = {} elif ty == list: @@ -511,23 +532,23 @@ def parse(yaml_input, file_out=None, generate_bom=False): # add connections ferrule_counter = 0 for con in yaml_data['connections']: - if len(con) == 3: # format: connector -- cable -- connector + if len(con) == 3: # format: connector -- cable -- connector for c in con: - if len(list(c.keys())) != 1: # check that each entry in con has only one key, which is the designator + if len(list(c.keys())) != 1: # check that each entry in con has only one key, which is the designator raise Exception('Too many keys') from_name = list(con[0].keys())[0] - via_name = list(con[1].keys())[0] - to_name = list(con[2].keys())[0] + via_name = list(con[1].keys())[0] + to_name = list(con[2].keys())[0] - if not check_designators([from_name,via_name,to_name],('connectors','cables','connectors')): - print([from_name,via_name,to_name]) + if not check_designators([from_name, via_name, to_name], ('connectors', 'cables', 'connectors')): + print([from_name, via_name, to_name]) raise Exception('Bad connection definition (3)') from_pins = expand(con[0][from_name]) - via_pins = expand(con[1][via_name]) - to_pins = expand(con[2][to_name]) + via_pins = expand(con[1][via_name]) + to_pins = expand(con[2][to_name]) if len(from_pins) != len(via_pins) or len(via_pins) != len(to_pins): raise Exception('List length mismatch') @@ -539,7 +560,7 @@ def parse(yaml_input, file_out=None, generate_bom=False): for c in con: if type(c) is dict: - if len(list(c.keys())) != 1: # check that each entry in con has only one key, which is the designator + if len(list(c.keys())) != 1: # check that each entry in con has only one key, which is the designator raise Exception('Too many keys') # hack to make the format for ferrules compatible with the formats for connectors and cables @@ -553,21 +574,20 @@ def parse(yaml_input, file_out=None, generate_bom=False): con[1][name] = name from_name = list(con[0].keys())[0] - to_name = list(con[1].keys())[0] + to_name = list(con[1].keys())[0] - con_cbl = check_designators([from_name, to_name],('connectors','cables')) - cbl_con = check_designators([from_name, to_name],('cables','connectors')) - con_con = check_designators([from_name, to_name],('connectors','connectors')) + con_cbl = check_designators([from_name, to_name], ('connectors', 'cables')) + cbl_con = check_designators([from_name, to_name], ('cables', 'connectors')) + con_con = check_designators([from_name, to_name], ('connectors', 'connectors')) - - fer_cbl = check_designators([from_name, to_name],('ferrules','cables')) - cbl_fer = check_designators([from_name, to_name],('cables','ferrules')) + fer_cbl = check_designators([from_name, to_name], ('ferrules', 'cables')) + cbl_fer = check_designators([from_name, to_name], ('cables', 'ferrules')) if not con_cbl and not cbl_con and not con_con and not fer_cbl and not cbl_fer: raise Exception('Wrong designators') from_pins = expand(con[0][from_name]) - to_pins = expand(con[1][to_name]) + to_pins = expand(con[1][to_name]) if con_cbl or cbl_con or con_con: if len(from_pins) != len(to_pins): @@ -577,18 +597,18 @@ def parse(yaml_input, file_out=None, generate_bom=False): for (from_pin, to_pin) in zip(from_pins, to_pins): if con_cbl: h.connect(from_name, from_pin, to_name, to_pin, None, None) - else: # cbl_con + else: # cbl_con h.connect(None, None, from_name, from_pin, to_name, to_pin) elif con_con: - cocon_coname = list(con[0].keys())[0] + cocon_coname = list(con[0].keys())[0] from_pins = expand(con[0][from_name]) - to_pins = expand(con[1][to_name]) + to_pins = expand(con[1][to_name]) for (from_pin, to_pin) in zip(from_pins, to_pins): h.loop(cocon_coname, from_pin, to_pin) if fer_cbl or cbl_fer: from_pins = expand(con[0][from_name]) - to_pins = expand(con[1][to_name]) + to_pins = expand(con[1][to_name]) if fer_cbl: ferrule_name = from_name @@ -610,11 +630,11 @@ def parse(yaml_input, file_out=None, generate_bom=False): else: h.connect(None, None, cable_name, cable_pin, ferrule_id, 1) - else: raise Exception('Wrong number of connection parameters') - h.output(filename=file_out, format=('png','svg'), gen_bom=generate_bom, view=False) + h.output(filename=file_out, format=('png', 'svg'), gen_bom=generate_bom, view=False) + def parse_file(yaml_file, file_out=None, generate_bom=False): with open(yaml_file, 'r') as file: @@ -630,12 +650,12 @@ def parse_file(yaml_file, file_out=None, generate_bom=False): def parse_cmdline(): parser = argparse.ArgumentParser( - description='Generate cable and wiring harness documentation from YAML descriptions' - ) + description='Generate cable and wiring harness documentation from YAML descriptions' + ) parser.add_argument('input_file', action='store', type=str, metavar='YAML_FILE') - parser.add_argument('-o', '--output_file', action='store', type=str, metavar='OUTPUT') + parser.add_argument('-o', '--output_file', action='store', type=str, metavar='OUTPUT') parser.add_argument('--generate-bom', action='store_true', default=True) @@ -645,6 +665,7 @@ def parse_cmdline(): return args + def main(): args = parse_cmdline() @@ -667,12 +688,13 @@ def main(): if not args.output_file: file_out = args.input_file pre, _ = os.path.splitext(file_out) - file_out = pre # extension will be added by graphviz output function + file_out = pre # extension will be added by graphviz output function else: file_out = args.output_file file_out = os.path.abspath(file_out) parse(yaml_input, file_out=file_out, generate_bom=args.generate_bom) + if __name__ == '__main__': main()