diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ba5fb73..2c7aacb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -33,23 +33,4 @@ jobs: -print0 | sort -z | xargs -t0L1 -I {} python {} --3d - name: Check for diffs in UUID caches run: git diff --exit-code - - name: Check for stale entries in UUID caches - run: | - stat --format="%s %n" *.csv | sort -k2 > sizes_before.txt - find . -maxdepth 1 -name '*.csv' \ - -not -name 'uuid_cache_stm_mcu.csv' \ - -not -name 'uuid_cache_connectors.csv' \ - -not -name 'uuid_cache_dfn.csv' \ - -not -name 'uuid_cache_dip.csv' \ - -not -name 'uuid_cache_so.csv' \ - -delete - find . -maxdepth 1 -name 'generate_*.py' \ - -not -name 'generate_stm_mcu.py' \ - -not -name 'generate_modules.py' \ - -not -name 'generate_connectors.py' \ - -not -name 'generate_dfn.py' \ - -not -name 'generate_dip.py' \ - -not -name 'generate_so.py' \ - -print0 | sort -z | xargs -t0L1 python - stat --format="%s %n" *.csv | sort -k2 > sizes_after.txt - diff sizes_before.txt sizes_after.txt + diff --git a/README.md b/README.md index 5619669..0561bdb 100644 --- a/README.md +++ b/README.md @@ -86,19 +86,16 @@ entities are fully type annotated, you even benefit from type checking using ### UUID Caching -In every generator script, you should first initialize the UUID cache: +In every generator script, you should cache UUID entries: ```python -from common import init_cache, save_cache +from common import UuidCache # Initialize UUID cache, load any pre-existing entries -uuid_cache_file = 'uuid_cache_chip.csv' -uuid_cache = init_cache(uuid_cache_file) +with UuidCache('uuid_cache_chip.csv'): + # package generation ``` -The cache is a simple in-memory dictionary. The `init_cache` function will load -any pre-existing cache entries from the file system. - Every generated UUID should have its own stable lookup key. Depending on the script, a wrapper function that generates missing UUIDs on the fly might make sense: @@ -116,12 +113,7 @@ def uuid(category: str, full_name: str, identifier: str, create: bool = True) -> identifier: For example 'pad-1' or 'pin-13'. """ - key = '{}-{}-{}'.format(category, full_name, identifier).lower().replace(' ', '~') - if key not in uuid_cache: - if not create: - raise ValueError('Unknown UUID: {}'.format(key)) - uuid_cache[key] = str(uuid4()) - return uuid_cache[key] + return uuid_cache.get(category, full_name, identifier) pad_uuids = [ uuid('pkg', 'RESC3216X65', 'pad-1'), @@ -129,14 +121,8 @@ pad_uuids = [ ] ``` -At the end of the generator script, all cached UUIDs should be persisted to the -file system. - -```python -# Persist the cache to the file system -save_cache(uuid_cache_file, uuid_cache) -``` - +At the end of the generator script, all cached UUIDs will be persisted to the +file system automatically. ## Testing diff --git a/common.py b/common.py index 6c6429d..8be5e2f 100644 --- a/common.py +++ b/common.py @@ -7,30 +7,64 @@ import re from datetime import datetime from os import path +from uuid import uuid4 from typing import Any, Dict, List, OrderedDict, Union -def init_cache(uuid_cache_file: str) -> Dict[str, str]: - print('Loading cache: {}'.format(uuid_cache_file)) - uuid_cache: OrderedDict[str, str] = collections.OrderedDict() - try: - with open(uuid_cache_file, 'r') as f: - reader = csv.reader(f, delimiter=',', quotechar='"') - for row in reader: - uuid_cache[row[0]] = row[1] - except FileNotFoundError: - pass - return uuid_cache - - -def save_cache(uuid_cache_file: str, uuid_cache: Dict[str, str]) -> None: - print('Saving cache: {}'.format(uuid_cache_file)) - with open(uuid_cache_file, 'w') as f: - writer = csv.writer(f, delimiter=',', quotechar='"', lineterminator='\n') - for k, v in sorted(uuid_cache.items()): - writer.writerow([k, v]) - print('Done, cached {} UUIDs'.format(len(uuid_cache))) +class UuidCache: + def __init__(self, filename: str, stale_check: bool = True): + self.filename = filename + self.used_keys: set[str] = set() + self.entered = False + self.stale_check = stale_check + + self.data: OrderedDict[str, str] = collections.OrderedDict() + print(f'Loading cache: {filename}') + try: + with open(self.filename, 'r') as f: + reader = csv.reader(f, delimiter=',', quotechar='"') + for row in reader: + self.data[row[0]] = row[1] + except FileNotFoundError: + print('Cache file {filename} not found, building new cache') + print(f'Cache has {len(self.data)} entries') + + def __enter__(self) -> 'UuidCache': + self.used_keys = set() + self.entered = True + return self + + def __exit__(self, exception: Any, value: Any, traceback: Any) -> None: + if not exception and self.entered: + self.check_stale() + self.save_cache() + + def save_cache(self) -> None: + print(f'Saving cache: {self.filename}') + with open(self.filename, 'w') as f: + writer = csv.writer(f, delimiter=',', quotechar='"', lineterminator='\n') + for k, v in sorted(self.data.items()): + writer.writerow([k, v]) + print(f'Done, cached {len(self.data)} UUIDs') + + def get(self, *args: Any, create: bool = True) -> str: + key = '-'.join(str(a).lower().replace(' ', '~') for a in args) + if key not in self.data: + if self.entered and create: + self.data[key] = str(uuid4()) + else: + raise KeyError( + f'{key} not found in uuid cache. Entering the context is required for auto-generation' + ) + self.used_keys.add(key) + return self.data[key] + + def check_stale(self) -> None: + if self.stale_check: + stale_keys = {key for key in self.data if key not in self.used_keys} + if stale_keys: + raise RuntimeError(f'There are stale UUIDs in the cache: {stale_keys}') def now() -> str: diff --git a/generate_axial_tht.py b/generate_axial_tht.py index 648e9d6..dc974b6 100644 --- a/generate_axial_tht.py +++ b/generate_axial_tht.py @@ -8,11 +8,10 @@ import sys from math import acos, asin, pi, sqrt from os import path -from uuid import uuid4 from typing import Iterable, List, Optional, Tuple -from common import init_cache, now, save_cache +from common import UuidCache, now from entities.common import ( Align, Angle, @@ -73,16 +72,7 @@ courtyard_excess = 0.4 -# Initialize UUID cache -uuid_cache_file = 'uuid_cache_axial_tht.csv' -uuid_cache = init_cache(uuid_cache_file) - - -def uuid(category: str, full_name: str, identifier: str) -> str: - key = '{}-{}-{}'.format(category, full_name, identifier).lower().replace(' ', '~') - if key not in uuid_cache: - uuid_cache[key] = str(uuid4()) - return uuid_cache[key] +uuid_cache = UuidCache('uuid_cache_axial_tht.csv') def calculate_pad_hole_diameter(max_leg_diameter: float) -> float: @@ -157,7 +147,7 @@ def generate_pkg( ) def _uuid(identifier: str) -> str: - return uuid('pkg', pkg_identifier, identifier) + return uuid_cache.get('pkg', pkg_identifier, identifier) uuid_pkg = _uuid('pkg') @@ -759,7 +749,7 @@ def generate_3d( assembly.save(out_path, fused=True) -if __name__ == '__main__': +def main() -> None: if '--help' in sys.argv or '-h' in sys.argv: print(f'Usage: {sys.argv[0]} [--3d]') print() @@ -1036,4 +1026,7 @@ def generate_3d( generate_3d_models=generate_3d_models, ) - save_cache(uuid_cache_file, uuid_cache) + +if __name__ == '__main__': + with uuid_cache: + main() diff --git a/generate_capacitor_radial_tht.py b/generate_capacitor_radial_tht.py index 5885eed..f8561ff 100644 --- a/generate_capacitor_radial_tht.py +++ b/generate_capacitor_radial_tht.py @@ -4,11 +4,10 @@ import sys from os import path -from uuid import uuid4 from typing import Any, Optional -from common import format_ipc_dimension, init_cache, now, save_cache +from common import UuidCache, format_ipc_dimension, now from entities.common import ( Align, Angle, @@ -76,27 +75,7 @@ 0.8: 1.0, } -# Initialize UUID cache -uuid_cache_file = 'uuid_cache_capacitors_radial_tht.csv' -uuid_cache = init_cache(uuid_cache_file) - - -def uuid(category: str, full_name: str, identifier: str) -> str: - """ - Return a uuid for the specified element. - - Params: - category: - For example 'cmp' or 'pkg'. - full_name: - For example "SOIC127P762X120-16". - identifier: - For example 'pad-1' or 'pin-13'. - """ - key = '{}-{}-{}'.format(category, full_name, identifier).lower().replace(' ', '~') - if key not in uuid_cache: - uuid_cache[key] = str(uuid4()) - return uuid_cache[key] +uuid_cache = UuidCache('uuid_cache_capacitors_radial_tht.csv') def get_variant( @@ -130,7 +109,7 @@ def generate_pkg( variant = get_variant(diameter, height, pitch, lead_width) def _pkg_uuid(identifier: str) -> str: - return uuid('pkg', variant, identifier) + return uuid_cache.get('pkg', variant, identifier) def _create_footprint(footprint_identifier: str, name: str) -> Footprint: def _fpt_uuid(identifier: str) -> str: @@ -456,7 +435,7 @@ def generate_dev( variant = get_variant(diameter, height, pitch, lead_width) def _uuid(identifier: str) -> str: - return uuid('dev', variant, identifier) + return uuid_cache.get('dev', variant, identifier) device = Device( uuid=_uuid('dev'), @@ -477,17 +456,17 @@ def _uuid(identifier: str) -> str: generated_by=GeneratedBy(''), categories=[Category('c011cc6b-b762-498e-8494-d1994f3043cf')], component_uuid=ComponentUUID('c54375c5-7149-4ded-95c5-7462f7301ee7'), - package_uuid=PackageUUID(uuid('pkg', variant, 'pkg')), + package_uuid=PackageUUID(uuid_cache.get('pkg', variant, 'pkg')), ) device.add_pad( ComponentPad( - pad_uuid=uuid('pkg', variant, 'pad-plus'), + pad_uuid=uuid_cache.get('pkg', variant, 'pad-plus'), signal=SignalUUID('e010ecbb-6210-4da3-9270-ebd58656dbf0'), ) ) device.add_pad( ComponentPad( - pad_uuid=uuid('pkg', variant, 'pad-minus'), + pad_uuid=uuid_cache.get('pkg', variant, 'pad-minus'), signal=SignalUUID('af3ffca8-0085-4edb-a775-fcb759f63411'), ) ) @@ -500,7 +479,7 @@ def _uuid(identifier: str) -> str: print('Wrote device {}'.format(name)) -if __name__ == '__main__': +def main() -> None: if '--help' in sys.argv or '-h' in sys.argv: print(f'Usage: {sys.argv[0]} [--3d]') print() @@ -564,4 +543,7 @@ def _uuid(identifier: str) -> str: create_date='2019-12-29T14:14:11Z', ) - save_cache(uuid_cache_file, uuid_cache) + +if __name__ == '__main__': + with uuid_cache: + main() diff --git a/generate_chip.py b/generate_chip.py index 7108c27..8e5a9b4 100644 --- a/generate_chip.py +++ b/generate_chip.py @@ -8,12 +8,11 @@ import sys from os import path -from uuid import uuid4 from typing import Dict, Iterable, Optional, Tuple +from common import UuidCache, now from common import format_ipc_dimension as fd -from common import init_cache, now, save_cache from entities.common import ( Align, Angle, @@ -104,29 +103,7 @@ def get_by_density(length: float, level: str, key: str) -> float: return table[level][key] -# Initialize UUID cache -uuid_cache_file = 'uuid_cache_chip.csv' -uuid_cache = init_cache(uuid_cache_file) - - -def uuid(category: str, full_name: str, identifier: str, create: bool = True) -> str: - """ - Return a uuid for the specified pin. - - Params: - category: - For example 'cmp' or 'pkg'. - full_name: - For example "RESC3216X65". - identifier: - For example 'pad-1' or 'pin-13'. - """ - key = '{}-{}-{}'.format(category, full_name, identifier).lower().replace(' ', '~') - if key not in uuid_cache: - if not create: - raise ValueError('Unknown UUID: {}'.format(key)) - uuid_cache[key] = str(uuid4()) - return uuid_cache[key] +uuid_cache = UuidCache('uuid_cache_chip.csv') class BodyDimensions: @@ -274,7 +251,7 @@ def generate_pkg( ) def _uuid(identifier: str) -> str: - return uuid(category, full_name, identifier) + return uuid_cache.get(category, full_name, identifier) # UUIDs uuid_pkg = _uuid('pkg') @@ -709,7 +686,7 @@ def add_footprint_variant( # Generate 3D models (for certain package types) if package_type in ['RESC', 'CAPC', 'CAPPM', 'INDC']: - uuid_3d = uuid('pkg', full_name, '3d') + uuid_3d = uuid_cache.get('pkg', full_name, '3d') if generate_3d_models: generate_3d(library, package_type, full_name, uuid_pkg, uuid_3d, config) package.add_3d_model(Package3DModel(uuid_3d, Name(full_name))) @@ -874,13 +851,14 @@ def generate_dev( full_keywords = '{},{},{}'.format(size_metric, size_imperial, keywords) def _uuid(identifier: str) -> str: - return uuid(category, full_name, identifier) + return uuid_cache.get(category, full_name, identifier) # UUIDs uuid_dev = _uuid('dev') - pkg = uuid('pkg', pkg_name, 'pkg', create=False) + pkg = uuid_cache.get('pkg', pkg_name, 'pkg', create=False) pads = [ - uuid('pkg', pkg_name, 'pad-{}'.format(i), create=False) for i in (pad_ids or ['1', '2']) + uuid_cache.get('pkg', pkg_name, 'pad-{}'.format(i), create=False) + for i in (pad_ids or ['1', '2']) ] print('Generating dev "{}": {}'.format(full_name, uuid_dev)) @@ -909,7 +887,7 @@ def _uuid(identifier: str) -> str: device.serialize(path.join('out', library, category)) -if __name__ == '__main__': +def main() -> None: if '--help' in sys.argv or '-h' in sys.argv: print(f'Usage: {sys.argv[0]} [--3d]') print() @@ -1288,4 +1266,8 @@ def _uuid(identifier: str) -> str: create_date='2025-01-26T09:18:09Z', pad_ids=['p', 'n'], ) - save_cache(uuid_cache_file, uuid_cache) + + +if __name__ == '__main__': + with uuid_cache: + main() diff --git a/generate_connectors.py b/generate_connectors.py index 9b37d56..113bf16 100644 --- a/generate_connectors.py +++ b/generate_connectors.py @@ -17,11 +17,10 @@ import sys from functools import partial from os import makedirs, path -from uuid import uuid4 from typing import Callable, Iterable, Optional, Tuple -from common import init_cache, now, save_cache +from common import UuidCache, now from entities.common import ( Align, Angle, @@ -117,29 +116,7 @@ KIND_SCREW_TERMINAL = 'screwterminal' -# Initialize UUID cache -uuid_cache_file = 'uuid_cache_connectors.csv' -uuid_cache = init_cache(uuid_cache_file) - - -def uuid(category: str, kind: str, variant: str, identifier: str) -> str: - """ - Return a uuid for the specified pin. - - Params: - category: - For example 'cmp' or 'pkg'. - kind: - For example 'pinheader' or 'pinsocket'. - variant: - For example '1x5-D1.1' or '1x13'. - identifier: - For example 'pad-1' or 'pin-13'. - """ - key = '{}-{}-{}-{}'.format(category, kind, variant, identifier).lower().replace(' ', '~') - if key not in uuid_cache: - uuid_cache[key] = str(uuid4()) - return uuid_cache[key] +uuid_cache = UuidCache('uuid_cache_connectors.csv', stale_check=False) def get_y(pin_number: int, pin_count: int, rows: int, spacing: float, grid_align: bool) -> float: @@ -214,7 +191,7 @@ def generate_pkg( variant = f'{rows}x{per_row}-D{drill:.1f}' def _uuid(identifier: str) -> str: - return uuid(category, kind, variant, identifier) + return uuid_cache.get(category, kind, variant, identifier) uuid_pkg = _uuid('pkg') uuid_pads = [_uuid('pad-{}'.format(p)) for p in range(i)] @@ -401,7 +378,7 @@ def generate_silkscreen_female( pin_count: int, rows: int, ) -> Polygon: - uuid_polygon = uuid(category, kind, variant, 'polygon-contour') + uuid_polygon = uuid_cache.get(category, kind, variant, 'polygon-contour') x = 1.27 * rows + line_width / 2 top_offset = spacing / 2 + line_width / 2 @@ -431,7 +408,7 @@ def generate_silkscreen_male( pin_count: int, rows: int, ) -> Polygon: - uuid_polygon = uuid(category, kind, variant, 'polygon-contour') + uuid_polygon = uuid_cache.get(category, kind, variant, 'polygon-contour') per_row = pin_count // rows x_outer = 1.27 * rows + line_width / 2 @@ -577,7 +554,7 @@ def generate_sym( variant = '{}x{}'.format(rows, per_row) def _uuid(identifier: str) -> str: - return uuid(category, kind, variant, identifier) + return uuid_cache.get(category, kind, variant, identifier) uuid_sym = _uuid('sym') uuid_pins = [_uuid('pin-{}'.format(p)) for p in range(i)] @@ -762,14 +739,14 @@ def generate_cmp( variant = '{}x{}'.format(rows, per_row) def _uuid(identifier: str) -> str: - return uuid(category, kind, variant, identifier) + return uuid_cache.get(category, kind, variant, identifier) uuid_cmp = _uuid('cmp') - uuid_pins = [uuid('sym', kind, variant, 'pin-{}'.format(p)) for p in range(i)] + uuid_pins = [uuid_cache.get('sym', kind, variant, 'pin-{}'.format(p)) for p in range(i)] uuid_signals = [_uuid('signal-{}'.format(p)) for p in range(i)] uuid_variant = _uuid('variant-default') uuid_gate = _uuid('gate-default') - uuid_symbol = uuid('sym', kind, variant, 'sym') + uuid_symbol = uuid_cache.get('sym', kind, variant, 'sym') # General info component = Component( @@ -858,15 +835,15 @@ def generate_dev( broad_variant = '{}x{}'.format(rows, per_row) def _uuid(identifier: str) -> str: - return uuid(category, kind, variant, identifier) + return uuid_cache.get(category, kind, variant, identifier) uuid_dev = _uuid('dev') - uuid_cmp = uuid('cmp', kind, broad_variant, 'cmp') + uuid_cmp = uuid_cache.get('cmp', kind, broad_variant, 'cmp') uuid_signals = [ - uuid('cmp', kind, broad_variant, 'signal-{}'.format(p)) for p in range(i) + uuid_cache.get('cmp', kind, broad_variant, 'signal-{}'.format(p)) for p in range(i) ] - uuid_pkg = uuid('pkg', kind, variant, 'pkg') - uuid_pads = [uuid('pkg', kind, variant, 'pad-{}'.format(p)) for p in range(i)] + uuid_pkg = uuid_cache.get('pkg', kind, variant, 'pkg') + uuid_pads = [uuid_cache.get('pkg', kind, variant, 'pad-{}'.format(p)) for p in range(i)] # General info lines.append('(librepcb_device {}'.format(uuid_dev)) @@ -910,7 +887,7 @@ def _uuid(identifier: str) -> str: ) -if __name__ == '__main__': +def main() -> None: if '--help' in sys.argv or '-h' in sys.argv: print(f'Usage: {sys.argv[0]} [--3d]') print() @@ -1272,4 +1249,7 @@ def _uuid(identifier: str) -> str: create_date='2018-10-17T19:13:41Z', ) - save_cache(uuid_cache_file, uuid_cache) + +if __name__ == '__main__': + with uuid_cache: + main() diff --git a/generate_dfn.py b/generate_dfn.py index 2d2ba4a..641bcfb 100644 --- a/generate_dfn.py +++ b/generate_dfn.py @@ -5,12 +5,11 @@ import sys from os import path -from uuid import uuid4 from typing import List, Optional +from common import UuidCache, now from common import format_ipc_dimension as fd -from common import init_cache, now, save_cache from dfn_configs import JEDEC_CONFIGS, THIRD_CONFIGS, DfnConfig from entities.common import ( Align, @@ -77,27 +76,7 @@ MIN_TRACE = 0.10 -# Initialize UUID cache -uuid_cache_file = 'uuid_cache_dfn.csv' -uuid_cache = init_cache(uuid_cache_file) - - -def uuid(category: str, full_name: str, identifier: str) -> str: - """ - Return a uuid for the specified pin. - - Params: - category: - For example 'cmp' or 'pkg'. - full_name: - For example "SOIC127P762X120-16". - identifier: - For example 'pad-1' or 'pin-13'. - """ - key = '{}-{}-{}'.format(category, full_name, identifier).lower().replace(' ', '~') - if key not in uuid_cache: - uuid_cache[key] = str(uuid4()) - return uuid_cache[key] +uuid_cache = UuidCache('uuid_cache_dfn.csv', stale_check=False) def get_y(pin_number: int, pin_count: int, spacing: float) -> float: @@ -170,7 +149,7 @@ def generate_pkg( full_keywords = 'dfn{},{}'.format(config.pin_count, keywords) def _uuid(identifier: str) -> str: - return uuid(category, full_name, identifier) + return uuid_cache.get(category, full_name, identifier) uuid_pkg = _uuid('pkg') uuid_pads = [_uuid('pad-{}'.format(p)) for p in range(1, config.pin_count + 1)] @@ -642,7 +621,7 @@ def generate_3d( assembly.save(out_path, fused=False) -if __name__ == '__main__': +def main() -> None: if '--help' in sys.argv or '-h' in sys.argv: print(f'Usage: {sys.argv[0]} [--3d]') print() @@ -720,4 +699,7 @@ def generate_3d( else: print('Duplicate name found: {}'.format(name)) - save_cache(uuid_cache_file, uuid_cache) + +if __name__ == '__main__': + with uuid_cache: + main() diff --git a/generate_dip.py b/generate_dip.py index 52f4b44..ddb62fa 100644 --- a/generate_dip.py +++ b/generate_dip.py @@ -159,12 +159,11 @@ """ from os import path -from uuid import uuid4 from typing import Iterable, Optional, Tuple +from common import UuidCache, now from common import format_ipc_dimension as ipc -from common import init_cache, now, save_cache from entities.common import ( Align, Angle, @@ -231,29 +230,7 @@ courtyard_excess = 0.4 -# Initialize UUID cache -uuid_cache_file = 'uuid_cache_dip.csv' -uuid_cache = init_cache(uuid_cache_file) - - -def uuid(category: str, width: str, variant: str, identifier: str) -> str: - """ - Return a uuid for the specified pin. - - Params: - category: - For example 'cmp' or 'pkg'. - width: - For example "7.62" or "15.24". - variant: - For example '8' or '28'. - identifier: - For example 'pad-1' or 'pin-13'. - """ - key = '{}-{}-{}-{}'.format(category, width, variant, identifier).lower().replace(' ', '~') - if key not in uuid_cache: - uuid_cache[key] = str(uuid4()) - return uuid_cache[key] +uuid_cache = UuidCache('uuid_cache_dip.csv', stale_check=False) def get_y(pin_number: int, pin_count: int, spacing: float, grid_align: bool) -> float: @@ -306,7 +283,7 @@ def generate_pkg( def _uuid(identifier: str) -> str: width = '{:.2f}'.format(config.lead_span) - return uuid(category, width, variant, identifier) + return uuid_cache.get(category, width, variant, identifier) uuid_pkg = _uuid('pkg') uuid_pads = [_uuid('pad-{}'.format(p)) for p in range(1, pin_count + 1)] @@ -602,7 +579,7 @@ def add_footprint_variant( print('{}: Wrote package {}'.format(ipc_name, uuid_pkg)) -if __name__ == '__main__': +def main() -> None: generate_pkg( library='LibrePCB_Base.lplib', author='Danilo B.', @@ -637,4 +614,8 @@ def add_footprint_variant( create_date='2018-11-04T23:13:00Z', version='0.2', ) - save_cache(uuid_cache_file, uuid_cache) + + +if __name__ == '__main__': + with uuid_cache: + main() diff --git a/generate_dip_switches.py b/generate_dip_switches.py index f235694..b743b05 100644 --- a/generate_dip_switches.py +++ b/generate_dip_switches.py @@ -4,11 +4,10 @@ import sys from os import path -from uuid import uuid4 from typing import List, Optional, Tuple, Union -from common import init_cache, now, save_cache +from common import UuidCache, now from entities.attribute import Attribute, AttributeType from entities.common import ( Align, @@ -92,19 +91,10 @@ generator = 'librepcb-parts-generator (generate_dip_switches.py)' -# Initialize UUID cache -uuid_cache_file = 'uuid_cache_dip_switches.csv' -uuid_cache = init_cache(uuid_cache_file) +uuid_cache = UuidCache('uuid_cache_dip_switches.csv') -def uuid(category: str, full_name: str, identifier: str) -> str: - key = '{}-{}-{}'.format(category, full_name, identifier).lower().replace(' ', '~') - if key not in uuid_cache: - uuid_cache[key] = str(uuid4()) - return uuid_cache[key] - - -def get_y(pin_index: int, circuits: int, pitch: float) -> float: +def get_y(family: 'Family', pin_index: int, circuits: int, pitch: float) -> float: y0 = (circuits - 1) * pitch / 2 dy = y0 - family.lead_config.pitch_y * (pin_index % circuits) if pin_index < circuits: @@ -223,7 +213,7 @@ def __init__( def uuid_key(self, family: Family) -> str: return ( - '{}-{}'.format(family.pkg_name_prefix, model.name) + '{}-{}'.format(family.pkg_name_prefix, self.name) .lower() .replace(' ', '') .replace(',', 'p') @@ -231,7 +221,7 @@ def uuid_key(self, family: Family) -> str: def get_description(self, family: Family) -> str: s = f'{self.circuits}x DIP switch from {family.manufacturer}.' - s += f'\n\nBody Size: {family.body_size_x:.2f} x {model.body_size_y:.2f} mm' + s += f'\n\nBody Size: {family.body_size_x:.2f} x {self.body_size_y:.2f} mm' if isinstance(family.lead_config, ThtLeadConfig): s += f'\nPitch: {family.lead_config.pitch_x:.2f} x {family.lead_config.pitch_y:.2f} mm' if isinstance(family.lead_config, GullWingLeadConfig): @@ -267,7 +257,7 @@ def generate_sym( full_name = name.format(circuits=circuits, variant=variant) def _uuid(identifier: str) -> str: - return uuid('sym', f'{variant.id}-{circuits:02}', identifier) + return uuid_cache.get('sym', f'{variant.id}-{circuits:02}', identifier) uuid_sym = _uuid('sym') @@ -456,7 +446,7 @@ def generate_cmp( full_name = name.format(circuits=circuits) def _uuid(identifier: str) -> str: - return uuid('cmp', f'{circuits:02}', identifier) + return uuid_cache.get('cmp', f'{circuits:02}', identifier) uuid_cmp = _uuid('cmp') @@ -500,7 +490,7 @@ def _uuid(identifier: str) -> str: for variant in [VARIANT_EU, VARIANT_US]: gate = Gate( _uuid(f'combined-{variant.id}-gate'), - SymbolUUID(uuid_cache[f'sym-{variant.id}-{circuits:02}-sym']), + SymbolUUID(uuid_cache.get(f'sym-{variant.id}-{circuits:02}-sym')), Position(0, 0), Rotation(0), Required(True), @@ -508,8 +498,10 @@ def _uuid(identifier: str) -> str: ) for circuit in range(1, circuits + 1): for letter in ['a', 'b']: - pin_uuid = uuid_cache[f'sym-{variant.id}-{circuits:02}-pin-{circuit:02}{letter}'] - sig_uuid = uuid_cache[f'cmp-{circuits:02}-signal-{circuit:02}{letter}'] + pin_uuid = uuid_cache.get( + f'sym-{variant.id}-{circuits:02}-pin-{circuit:02}{letter}' + ) + sig_uuid = uuid_cache.get(f'cmp-{circuits:02}-signal-{circuit:02}{letter}') display_number = (circuits > 1) and (letter == 'a') gate.add_pin_signal_map( PinSignalMap( @@ -543,15 +535,15 @@ def _uuid(identifier: str) -> str: for circuit in range(1, circuits + 1): gate = Gate( _uuid(f'split-{variant.id}-gate-{circuit:02}'), - SymbolUUID(uuid_cache[f'sym-{variant.id}-01-sym']), + SymbolUUID(uuid_cache.get(f'sym-{variant.id}-01-sym')), Position(0, y0 - (circuit - 1) * spacing), Rotation(0), Required(True), Suffix(str(circuit)), ) for letter in ['a', 'b']: - pin_uuid = uuid_cache[f'sym-{variant.id}-01-pin-01{letter}'] - sig_uuid = uuid_cache[f'cmp-{circuits:02}-signal-{circuit:02}{letter}'] + pin_uuid = uuid_cache.get(f'sym-{variant.id}-01-pin-01{letter}') + sig_uuid = uuid_cache.get(f'cmp-{circuits:02}-signal-{circuit:02}{letter}') gate.add_pin_signal_map( PinSignalMap( pin_uuid, @@ -576,7 +568,7 @@ def generate_pkg( full_name = family.pkg_name_prefix + '_' + model.name.replace(' ', '_') def _uuid(identifier: str) -> str: - return uuid('pkg', model.uuid_key(family), identifier) + return uuid_cache.get('pkg', model.uuid_key(family), identifier) uuid_pkg = _uuid('pkg') @@ -617,7 +609,7 @@ def _uuid(identifier: str) -> str: package.add_pad(PackagePad(uuid=uuid_pkg_pad, name=Name(str(i + 1)))) uuid_fpt_pad = _uuid('default-pad-{}'.format(i + 1)) x = (family.lead_config.pitch_x / 2) * (-1 if (i < model.circuits) else 1) - y = get_y(i, model.circuits, family.lead_config.pitch_y) + y = get_y(family, i, model.circuits, family.lead_config.pitch_y) if isinstance(family.lead_config, ThtLeadConfig): footprint.add_pad( FootprintPad( @@ -719,7 +711,7 @@ def _uuid(identifier: str) -> str: text_x += family.lead_config.pad_size_x / 2 text_x = (text_x + (-window_dx - (line_width / 2))) / 2 for circuit in range(model.circuits): - y = get_y(circuit, model.circuits, family.lead_config.pitch_y) + y = get_y(family, circuit, model.circuits, family.lead_config.pitch_y) footprint.add_polygon( Polygon( uuid=_uuid(f'default-polygon-documentation-window-{circuit}'), @@ -773,7 +765,7 @@ def _uuid(identifier: str) -> str: dx = (family.body_size_x / 2) + (line_width / 2) dx_pin1 = (family.lead_config.pitch_x / 2) - (line_width / 2) dy = (model.body_size_y / 2) + (line_width / 2) - dy_inner = get_y(0, model.circuits, family.lead_config.pitch_y) + dy_inner = get_y(family, 0, model.circuits, family.lead_config.pitch_y) if isinstance(family.lead_config, ThtLeadConfig): dx_pin1 += family.lead_config.pad_diameter / 2 dy_inner += (family.lead_config.pad_diameter / 2) + (line_width / 2) + 0.15 @@ -813,7 +805,9 @@ def _uuid(identifier: str) -> str: Vertex(Position(right, top), Angle(0)), ] for i in range(model.circuits): - y = get_y(model.circuits * 2 - i - 1, model.circuits, family.lead_config.pitch_y) + y = get_y( + family, model.circuits * 2 - i - 1, model.circuits, family.lead_config.pitch_y + ) outline_vertices += [ Vertex(Position(right, y + leads_dy), Angle(0)), Vertex(Position(right_leads, y + leads_dy), Angle(0)), @@ -825,7 +819,7 @@ def _uuid(identifier: str) -> str: Vertex(Position(left, bottom), Angle(0)), ] for i in range(model.circuits): - y = get_y(model.circuits - i - 1, model.circuits, family.lead_config.pitch_y) + y = get_y(family, model.circuits - i - 1, model.circuits, family.lead_config.pitch_y) outline_vertices += [ Vertex(Position(left, y - leads_dy), Angle(0)), Vertex(Position(left_leads, y - leads_dy), Angle(0)), @@ -858,7 +852,7 @@ def _uuid(identifier: str) -> str: right = -left if isinstance(family.lead_config, GullWingLeadConfig): top_leads = ( - get_y(0, model.circuits, family.lead_config.pitch_y) + get_y(family, 0, model.circuits, family.lead_config.pitch_y) + (family.lead_config.width / 2) + courtyard_excess ) @@ -969,7 +963,7 @@ def generate_3d_model( .fillet(0.2) ) for i in range(model.circuits): - y = get_y(i, model.circuits, family.lead_config.pitch_y) + y = get_y(family, i, model.circuits, family.lead_config.pitch_y) body = body.workplane(origin=(0, y), offset=family.body_size_z / 2).box( family.window_size[0], family.window_size[1], @@ -1064,14 +1058,20 @@ def generate_3d_model( 'lead-{}'.format(i + 1), StepColor.LEAD_SMT, location=cq.Location( - (lead_xz[0], get_y(i, model.circuits, family.lead_config.pitch_y), lead_xz[1]) + ( + lead_xz[0], + get_y(family, i, model.circuits, family.lead_config.pitch_y), + lead_xz[1], + ) ), ) assembly.add_body( actuator, 'actuator-{}'.format(i + 1), cq.Color(family.actuator_color), - location=cq.Location((0, get_y(i, model.circuits, family.lead_config.pitch_y), 0)), + location=cq.Location( + (0, get_y(family, i, model.circuits, family.lead_config.pitch_y), 0) + ), ) # Save without fusing for massively better minification! @@ -1090,7 +1090,7 @@ def generate_dev( full_name = f'{family.dev_name_prefix} {model.name}' def _uuid(identifier: str) -> str: - return uuid('dev', model.uuid_key(family), identifier) + return uuid_cache.get('dev', model.uuid_key(family), identifier) uuid_dev = _uuid('dev') @@ -1107,15 +1107,15 @@ def _uuid(identifier: str) -> str: deprecated=Deprecated(False), generated_by=GeneratedBy(''), categories=[Category('e29f0cb3-ef6d-4203-b854-d75150cbae0b')], - component_uuid=ComponentUUID(uuid_cache[f'cmp-{model.circuits:02}-cmp']), - package_uuid=PackageUUID(uuid_cache['pkg-' + model.uuid_key(family) + '-pkg']), + component_uuid=ComponentUUID(uuid_cache.get(f'cmp-{model.circuits:02}-cmp')), + package_uuid=PackageUUID(uuid_cache.get('pkg-' + model.uuid_key(family) + '-pkg')), ) for pad in range(1, (model.circuits * 2) + 1): circuit = pad if (pad <= model.circuits) else ((model.circuits * 2) + 1 - pad) letter = 'a' if (pad <= model.circuits) else 'b' - signal_uuid = uuid_cache[f'cmp-{model.circuits:02}-signal-{circuit:02}{letter}'] - pad_uuid = uuid_cache[f'pkg-{model.uuid_key(family)}-pad-{pad}'] + signal_uuid = uuid_cache.get(f'cmp-{model.circuits:02}-signal-{circuit:02}{letter}') + pad_uuid = uuid_cache.get(f'pkg-{model.uuid_key(family)}-pad-{pad}') device.add_pad(ComponentPad(pad_uuid, SignalUUID(signal_uuid))) for part in model.parts: @@ -1134,7 +1134,7 @@ def _uuid(identifier: str) -> str: device.serialize(path.join('out', library, 'dev')) -if __name__ == '__main__': +def main() -> None: if '--help' in sys.argv or '-h' in sys.argv: print(f'Usage: {sys.argv[0]} [--3d]') print() @@ -1302,4 +1302,7 @@ def _uuid(identifier: str) -> str: model=model, ) - save_cache(uuid_cache_file, uuid_cache) + +if __name__ == '__main__': + with uuid_cache: + main() diff --git a/generate_do.py b/generate_do.py index cadcc75..0016f41 100644 --- a/generate_do.py +++ b/generate_do.py @@ -7,12 +7,11 @@ import sys from os import path -from uuid import uuid4 from typing import Optional +from common import UuidCache, now from common import format_ipc_dimension as fd -from common import init_cache, now, save_cache from entities.common import ( Align, Angle, @@ -68,16 +67,7 @@ line_width = 0.2 -# Initialize UUID cache -uuid_cache_file = 'uuid_cache_do.csv' -uuid_cache = init_cache(uuid_cache_file) - - -def uuid(category: str, full_name: str, identifier: str) -> str: - key = '{}-{}-{}'.format(category, full_name, identifier).lower().replace(' ', '~') - if key not in uuid_cache: - uuid_cache[key] = str(uuid4()) - return uuid_cache[key] +uuid_cache = UuidCache('uuid_cache_do.csv') class DoConfig: @@ -137,7 +127,7 @@ def generate_pkg( """ def _uuid(identifier: str) -> str: - return uuid('pkg', pkg_name, identifier) + return uuid_cache.get('pkg', pkg_name, identifier) uuid_pkg = _uuid('pkg') @@ -483,7 +473,7 @@ def generate_3d( assembly.save(out_path, fused=False) -if __name__ == '__main__': +def main() -> None: if '--help' in sys.argv or '-h' in sys.argv: print(f'Usage: {sys.argv[0]} [--3d]') print() @@ -543,4 +533,7 @@ def generate_3d( create_date='2023-08-15T22:33:08Z', ) - save_cache(uuid_cache_file, uuid_cache) + +if __name__ == '__main__': + with uuid_cache: + main() diff --git a/generate_dpak.py b/generate_dpak.py index d083ad3..63d834f 100644 --- a/generate_dpak.py +++ b/generate_dpak.py @@ -7,12 +7,11 @@ from collections import namedtuple from dataclasses import dataclass from os import path -from uuid import uuid4 from typing import Dict, Iterable, List, Optional, cast +from common import UuidCache, now from common import format_ipc_dimension as fd -from common import init_cache, now, save_cache from entities.common import ( Align, Angle, @@ -118,27 +117,7 @@ } -# Initialize UUID cache -uuid_cache_file = 'uuid_cache_dpak.csv' -uuid_cache = init_cache(uuid_cache_file) - - -def uuid(category: str, full_name: str, identifier: str) -> str: - """ - Return a uuid for the specified pin. - - Params: - category: - For example 'cmp' or 'pkg'. - full_name: - For example "SOIC127P762X120-16". - identifier: - For example 'pad-1' or 'pin-13'. - """ - key = '{}-{}-{}'.format(category, full_name, identifier).lower().replace(' ', '~') - if key not in uuid_cache: - uuid_cache[key] = str(uuid4()) - return uuid_cache[key] +uuid_cache = UuidCache('uuid_cache_dpak.csv') def excess_by_density(pitch: float, level: str) -> Excess: @@ -236,7 +215,7 @@ def generate_pkg( ) + '\n\nGenerated with {}'.format(generator) def _uuid(identifier: str) -> str: - return uuid(category, full_name, identifier) + return uuid_cache.get(category, full_name, identifier) uuid_pkg = _uuid('pkg') uuid_pads = [_uuid('pad-{}'.format(p)) for p in range(1, config.pin_count + 1)] @@ -580,7 +559,7 @@ def _create_outline( add_footprint_variant('density~c', 'Density Level C (min protrusion)', 'C') # Generate 3D models - uuid_3d = uuid('pkg', full_name, '3d') + uuid_3d = uuid_cache.get('pkg', full_name, '3d') if generate_3d_models: generate_3d(library, full_name, uuid_pkg, uuid_3d, config) package.add_3d_model(Package3DModel(uuid_3d, Name(full_name))) @@ -666,7 +645,7 @@ def generate_3d( assembly.save(out_path, fused=False) -if __name__ == '__main__': +def main() -> None: if '--help' in sys.argv or '-h' in sys.argv: print(f'Usage: {sys.argv[0]} [--3d]') print() @@ -719,4 +698,8 @@ def generate_3d( version='0.1', create_date='2026-06-01T08:27:05Z', ) - save_cache(uuid_cache_file, uuid_cache) + + +if __name__ == '__main__': + with uuid_cache: + main() diff --git a/generate_idc.py b/generate_idc.py index ab9abe4..bef2265 100644 --- a/generate_idc.py +++ b/generate_idc.py @@ -11,11 +11,10 @@ from math import sqrt from os import path -from uuid import uuid4 from typing import Iterable, Optional, Tuple -from common import init_cache, now, save_cache +from common import UuidCache, now from entities.common import ( Align, Angle, @@ -75,30 +74,8 @@ pkg_text_height = 1.0 sym_text_height = 2.54 -# Initialize UUID cache -uuid_cache_file = 'uuid_cache_idc.csv' -uuid_cache = init_cache(uuid_cache_file) - -# Initialize UUID cache for connectors -uuid_cache_connectors = init_cache('uuid_cache_connectors.csv') - - -def uuid(category: str, variant: str, identifier: str) -> str: - """ - Return a uuid for the specified object. - - Params: - category: - For example 'cmp' or 'pkg'. - variant: - For example 'cnctech-3020-06-0300' or '1x13'. - identifier: - For example 'pad-1' or 'pin-13'. - """ - key = '{}-{}-{}'.format(category, variant, identifier).lower().replace(' ', '~') - if key not in uuid_cache: - uuid_cache[key] = str(uuid4()) - return uuid_cache[key] +uuid_cache = UuidCache('uuid_cache_idc.csv') +uuid_cache_connectors = UuidCache('uuid_cache_connectors.csv', stale_check=False) class Coord: @@ -213,7 +190,7 @@ def __init__( def generate_pkg(config: Config) -> None: def _uuid(identifier: str) -> str: - return uuid('pkg', config.identifier, identifier) + return uuid_cache.get('pkg', config.identifier, identifier) uuid_pkg = _uuid('pkg') uuid_pads = [_uuid('pad-{}'.format(p)) for p in range(config.pin_count)] @@ -533,12 +510,11 @@ def _create_outline( def generate_dev(config: Config) -> None: def _uuid(category: str, identifier: str) -> str: - return uuid(category, config.identifier, identifier) + return uuid_cache.get(category, config.identifier, identifier) def _uuid_cmp(identifier: str) -> str: variant = '{}x{}'.format(2, config.pin_count // 2) - key = 'cmp-pinheader-{}-{}'.format(variant, identifier).lower().replace(' ', '~') - return uuid_cache_connectors[key] + return uuid_cache_connectors.get('cmp', 'pinheader', variant, identifier) uuid_dev = _uuid('dev', 'dev') uuid_pkg = _uuid('pkg', 'pkg') @@ -577,7 +553,7 @@ def _uuid_cmp(identifier: str) -> str: print('Wrote device {}: {}'.format(uuid_dev, config.dev_name)) -if __name__ == '__main__': +def main() -> None: # CNC Tech configs = ( [ @@ -706,4 +682,7 @@ def _uuid_cmp(identifier: str) -> str: generate_pkg(config=config) generate_dev(config=config) - save_cache(uuid_cache_file, uuid_cache) + +if __name__ == '__main__': + with uuid_cache: + main() diff --git a/generate_jst_sh_connectors.py b/generate_jst_sh_connectors.py index 7408c2a..efbdbde 100644 --- a/generate_jst_sh_connectors.py +++ b/generate_jst_sh_connectors.py @@ -8,11 +8,10 @@ import math from os import path -from uuid import uuid4 from typing import Iterable, Optional -from common import init_cache, now, save_cache +from common import UuidCache, now from entities.attribute import StringAttribute from entities.common import ( Align, @@ -75,10 +74,9 @@ legend_header_spacing = 0 legend_line_width = 0.2 -uuid_cache_jst_file = 'uuid_cache_jst_sh_connectors.csv' -uuid_cache_jst = init_cache(uuid_cache_jst_file) +uuid_cache_jst = UuidCache('uuid_cache_jst_sh_connectors.csv') -uuid_cache_connectors = init_cache('uuid_cache_connectors.csv') +uuid_cache_connectors = UuidCache('uuid_cache_connectors.csv', stale_check=False) # we use these patterns multiple times in the code # that is why we define them here, single source of truth @@ -157,15 +155,8 @@ def variant(mounting_variant: str, circuits: int) -> str: return f'{mounting_variant}{circuits}' -def uuid(category: str, kind: str, variant: str, identifier: str) -> str: - key = '{}-{}-{}-{}'.format(category, kind, variant, identifier).lower().replace(' ', '~') - if key not in uuid_cache_jst: - uuid_cache_jst[key] = str(uuid4()) - return uuid_cache_jst[key] - - def connector_uuid(category: str, connector: Connector, identifier: str) -> str: - return uuid( + return uuid_cache_jst.get( category, connector.type, variant(connector.subtype, connector.circuits), identifier ) @@ -735,9 +726,9 @@ def generate_dev( suction_cap_variant_available: bool, ) -> Device: connector_uuid_stub = f'cmp-pinheader-1x{connector.circuits}' - component_uuid = uuid_cache_connectors[f'{connector_uuid_stub}-cmp'] + component_uuid = uuid_cache_connectors.get(f'{connector_uuid_stub}-cmp') signal_uuids = [ - uuid_cache_connectors[f'{connector_uuid_stub}-signal-{i}'] + uuid_cache_connectors.get(f'{connector_uuid_stub}-signal-{i}') for i in range(connector.circuits) ] @@ -834,7 +825,7 @@ def generate_jst( print(f'wrote device {dev.name.value}: {dev.uuid}') -if __name__ == '__main__': +def main() -> None: create_date = '2024-05-03T17:19:09Z' # units in mm @@ -916,4 +907,7 @@ def generate_jst( rotation=90, ) - save_cache(uuid_cache_jst_file, uuid_cache_jst) + +if __name__ == '__main__': + with uuid_cache_jst: + main() diff --git a/generate_led.py b/generate_led.py index 9272618..1e81212 100644 --- a/generate_led.py +++ b/generate_led.py @@ -5,12 +5,11 @@ import sys from math import acos, asin, degrees, sqrt from os import path -from uuid import uuid4 from typing import Iterable, List, Optional, Tuple +from common import UuidCache, now from common import format_ipc_dimension as fd -from common import init_cache, now, save_cache from entities.common import ( Align, Angle, @@ -75,27 +74,7 @@ pkg_text_height = 1.0 -# Initialize UUID cache -uuid_cache_file = 'uuid_cache_led.csv' -uuid_cache = init_cache(uuid_cache_file) - - -def uuid(category: str, full_name: str, identifier: str) -> str: - """ - Return a uuid for the specified pin. - - Params: - category: - For example 'cmp' or 'pkg'. - full_name: - For example "SOIC127P762X120-16". - identifier: - For example 'pad-1' or 'pin-13'. - """ - key = '{}-{}-{}'.format(category, full_name, identifier).lower().replace(' ', '~') - if key not in uuid_cache: - uuid_cache[key] = str(uuid4()) - return uuid_cache[key] +uuid_cache = UuidCache('uuid_cache_led.csv') class LedConfig: @@ -169,7 +148,7 @@ def generate_pkg( generated_3d_uuids = set() def _uuid(identifier: str) -> str: - return uuid(category, config.pkg_name, identifier) + return uuid_cache.get(category, config.pkg_name, identifier) uuid_pkg = _uuid('pkg') @@ -808,7 +787,7 @@ def generate_dev( for config in configs: def _uuid(identifier: str) -> str: - return uuid(category, config.dev_name, identifier) + return uuid_cache.get(category, config.dev_name, identifier) uuid_dev = _uuid('dev') @@ -826,17 +805,17 @@ def _uuid(identifier: str) -> str: generated_by=GeneratedBy(''), categories=[Category(cmpcat)], component_uuid=ComponentUUID('2b24b18d-bd95-4fb4-8fe6-bce1d020ead4'), - package_uuid=PackageUUID(uuid('pkg', config.pkg_name, 'pkg')), + package_uuid=PackageUUID(uuid_cache.get('pkg', config.pkg_name, 'pkg')), ) device.add_pad( ComponentPad( - pad_uuid=uuid('pkg', config.pkg_name, 'pad-a'), + pad_uuid=uuid_cache.get('pkg', config.pkg_name, 'pad-a'), signal=SignalUUID('f1467b5c-cc7d-44b4-8076-d729f35b3a6a'), ) ) device.add_pad( ComponentPad( - pad_uuid=uuid('pkg', config.pkg_name, 'pad-c'), + pad_uuid=uuid_cache.get('pkg', config.pkg_name, 'pad-c'), signal=SignalUUID('7b023430-b68f-403a-80b8-c7deb12e7a0c'), ) ) @@ -847,7 +826,7 @@ def _uuid(identifier: str) -> str: device.serialize(path.join('out', library, category)) -if __name__ == '__main__': +def main() -> None: if '--help' in sys.argv or '-h' in sys.argv: print(f'Usage: {sys.argv[0]} [--3d]') print() @@ -904,4 +883,7 @@ def _uuid(identifier: str) -> str: create_date='2022-08-31T11:18:33Z', ) - save_cache(uuid_cache_file, uuid_cache) + +if __name__ == '__main__': + with uuid_cache: + main() diff --git a/generate_modules.py b/generate_modules.py index 044953e..94c93e8 100644 --- a/generate_modules.py +++ b/generate_modules.py @@ -7,13 +7,13 @@ import cadquery as cq from cadquery_helpers import StepAssembly, StepColor, StepConstants -from common import init_cache +from common import UuidCache CU_THICKNESS = 0.05 # Initialize UUID caches -connectors_uuid_cache = init_cache('uuid_cache_connectors.csv') +connectors_uuid_cache = UuidCache('uuid_cache_connectors.csv') def get_connector_pkg_uuid(kind: str, pin_count: int, rows: int, drill: float, obj: str) -> str: @@ -21,7 +21,7 @@ def get_connector_pkg_uuid(kind: str, pin_count: int, rows: int, drill: float, o Get the UUID of a connector package item. See generate_connectors.py for details. """ key = f'pkg-{kind}-{rows}x{pin_count // rows}-d{drill:.1f}-{obj}' - return connectors_uuid_cache[key] + return connectors_uuid_cache.get(key) def load_connector_step_model(kind: str, pin_count: int, rows: int, drill: float) -> cq.Assembly: @@ -394,7 +394,7 @@ def generate_rpi_pico(name: str, bottom_pads: bool, headers: bool) -> None: assembly.save(out_path, fused=False) -if __name__ == '__main__': +def main() -> None: # Arduino generate_arduino_uno_r3(name='With Uno', with_board=True) generate_arduino_uno_r3(name='Only Headers', with_board=False) @@ -408,3 +408,7 @@ def generate_rpi_pico(name: str, bottom_pads: bool, headers: bool) -> None: generate_rpi_pico('Pico (THT)', bottom_pads=True, headers=True) generate_rpi_pico('Pico W (SMD)', bottom_pads=False, headers=False) generate_rpi_pico('Pico W (THT)', bottom_pads=False, headers=True) + + +if __name__ == '__main__': + main() diff --git a/generate_molex_picoblade.py b/generate_molex_picoblade.py index dca84a0..b079028 100644 --- a/generate_molex_picoblade.py +++ b/generate_molex_picoblade.py @@ -4,11 +4,10 @@ import sys from os import path -from uuid import uuid4 from typing import List, Optional -from common import init_cache, now, save_cache +from common import UuidCache, now from entities.attribute import Attribute, AttributeType from entities.common import ( Align, @@ -78,18 +77,9 @@ COURTYARD_EXCESS = 0.2 -# Initialize UUID cache -uuid_cache_file = 'uuid_cache_molex_picoblade.csv' -uuid_cache = init_cache(uuid_cache_file) +uuid_cache = UuidCache('uuid_cache_molex_picoblade.csv') -uuid_cache_connectors = init_cache('uuid_cache_connectors.csv') - - -def uuid(category: str, full_name: str, identifier: str) -> str: - key = '{}-{}-{}'.format(category, full_name, identifier).lower().replace(' ', '~') - if key not in uuid_cache: - uuid_cache[key] = str(uuid4()) - return uuid_cache[key] +uuid_cache_connectors = UuidCache('uuid_cache_connectors.csv', stale_check=False) def generate_pkg( @@ -106,7 +96,7 @@ def generate_pkg( generate_3d_models: bool, ) -> None: def _uuid(identifier: str) -> str: - return uuid('pkg', uuid_key, identifier) + return uuid_cache.get('pkg', uuid_key, identifier) uuid_pkg = _uuid('pkg') @@ -563,16 +553,16 @@ def generate_dev( parts: List[Part], ) -> None: def _uuid(identifier: str) -> str: - return uuid('dev', uuid_key, identifier) + return uuid_cache.get('dev', uuid_key, identifier) uuid_dev = _uuid('dev') print(f'Generating {name}: {uuid_dev}') connector_uuid_stub = f'cmp-pinheader-1x{circuits}' - component_uuid = uuid_cache_connectors[f'{connector_uuid_stub}-cmp'] + component_uuid = uuid_cache_connectors.get(f'{connector_uuid_stub}-cmp') signal_uuids = [ - uuid_cache_connectors[f'{connector_uuid_stub}-signal-{i}'] for i in range(circuits) + uuid_cache_connectors.get(f'{connector_uuid_stub}-signal-{i}') for i in range(circuits) ] device = Device( @@ -587,14 +577,14 @@ def _uuid(identifier: str) -> str: generated_by=GeneratedBy(''), categories=[Category(c) for c in categories], component_uuid=ComponentUUID(component_uuid), - package_uuid=PackageUUID(uuid('pkg', uuid_key, 'pkg')), + package_uuid=PackageUUID(uuid_cache.get('pkg', uuid_key, 'pkg')), ) for i in range(circuits): - pad_uuid = uuid_cache[f'pkg-{uuid_key}-pad-{i + 1:02}'] + pad_uuid = uuid_cache.get(f'pkg-{uuid_key}-pad-{i + 1:02}') device.add_pad(ComponentPad(pad_uuid, SignalUUID(signal_uuids[i]))) for i in range(2): - pad_uuid = uuid_cache[f'pkg-{uuid_key}-pad-tab{i + 1}'] + pad_uuid = uuid_cache.get(f'pkg-{uuid_key}-pad-tab{i + 1}') device.add_pad(ComponentPad(pad_uuid, SignalUUID('none'))) device.add_resource( @@ -611,7 +601,7 @@ def _uuid(identifier: str) -> str: device.serialize(path.join('out', library, 'dev')) -if __name__ == '__main__': +def main() -> None: if '--help' in sys.argv or '-h' in sys.argv: print(f'Usage: {sys.argv[0]} [--3d]') print() @@ -675,4 +665,7 @@ def _uuid(identifier: str) -> str: parts=parts, ) - save_cache(uuid_cache_file, uuid_cache) + +if __name__ == '__main__': + with uuid_cache: + main() diff --git a/generate_mosfet_dual.py b/generate_mosfet_dual.py index 8d01021..4133b2a 100644 --- a/generate_mosfet_dual.py +++ b/generate_mosfet_dual.py @@ -3,35 +3,14 @@ """ from os import makedirs, path -from uuid import uuid4 from typing import Any, Dict, Iterable, List, Optional -from common import init_cache, now, save_cache +from common import UuidCache, now generator = 'librepcb-parts-generator (generate_mosfet_dual.py)' -# Initialize UUID cache -uuid_cache_file = 'uuid_cache_mosfet_dual.csv' -uuid_cache = init_cache(uuid_cache_file) - - -def uuid(category: str, full_name: str, identifier: str) -> str: - """ - Return a uuid for the specified pin. - - Params: - category: - For example 'cmp' or 'pkg'. - full_name: - For example "RESC3216X65". - identifier: - For example 'pad-1' or 'pin-13'. - """ - key = '{}-{}-{}'.format(category, full_name, identifier).lower().replace(' ', '~') - if key not in uuid_cache: - uuid_cache[key] = str(uuid4()) - return uuid_cache[key] +uuid_cache = UuidCache('uuid_cache_mosfet_dual.csv') class PackageConfig: @@ -125,7 +104,7 @@ def generate_dev( package_config = PACKAGES[fet_config.package] # UUIDs - uuid_dev = uuid('dev', full_name, 'dev') + uuid_dev = uuid_cache.get('dev', full_name, 'dev') uuid_pkg = package_config.uuid_pkg uuid_pads = package_config.uuid_pads uuid_signals = [SIGNALS[s] for s in fet_config.signals] @@ -173,7 +152,7 @@ def generate_dev( f.write('\n') -if __name__ == '__main__': +def main() -> None: # Diodes Incorporated # fmt: off generate_dev( @@ -260,4 +239,8 @@ def generate_dev( ], ) # fmt: on - save_cache(uuid_cache_file, uuid_cache) + + +if __name__ == '__main__': + with uuid_cache: + main() diff --git a/generate_mounting_holes.py b/generate_mounting_holes.py index b39fa04..6bf01f5 100644 --- a/generate_mounting_holes.py +++ b/generate_mounting_holes.py @@ -8,11 +8,10 @@ """ from os import path -from uuid import uuid4 from typing import Optional -from common import init_cache, now, save_cache +from common import UuidCache, now from entities.common import ( Angle, Author, @@ -68,16 +67,7 @@ courtyard_excess = 0.5 -# Initialize UUID cache -uuid_cache_file = 'uuid_cache_mounting_holes.csv' -uuid_cache = init_cache(uuid_cache_file) - - -def uuid(category: str, full_name: str, identifier: str) -> str: - key = '{}-{}-{}'.format(category, full_name, identifier).lower().replace(' ', '~') - if key not in uuid_cache: - uuid_cache[key] = str(uuid4()) - return uuid_cache[key] +uuid_cache = UuidCache('uuid_cache_mounting_holes.csv') def generate_pkg( @@ -100,7 +90,7 @@ def generate_pkg( keywords = f'mounting,hole,pad,drill,screw,{name},{hole_diameter}mm,{pad_diameter}mm' def _uuid(identifier: str) -> str: - return uuid('pkg', name.lower(), identifier) + return uuid_cache.get('pkg', name.lower(), identifier) uuid_pkg = _uuid('pkg') @@ -299,7 +289,7 @@ def generate_dev( keywords = f'mounting,hole,pad,drill,screw,{name},{hole_diameter}mm,{pad_diameter}mm' def _uuid(identifier: str) -> str: - return uuid('dev', name.lower(), identifier) + return uuid_cache.get('dev', name.lower(), identifier) uuid_dev = _uuid('dev') @@ -320,12 +310,13 @@ def _uuid(identifier: str) -> str: Category('8ca4f9fb-3dd3-4c1e-a097-6601b437bbc6'), ], component_uuid=ComponentUUID('5c0f6cd9-dced-46ae-8098-6cccaa8726ec'), - package_uuid=PackageUUID(uuid('pkg', name.lower(), 'pkg')), + package_uuid=PackageUUID(uuid_cache.get('pkg', name.lower(), 'pkg')), ) device.add_pad( ComponentPad( - uuid('pkg', name.lower(), 'pad'), SignalUUID('c8721bab-6c90-43f6-8135-c32fce7aecc0') + uuid_cache.get('pkg', name.lower(), 'pad'), + SignalUUID('c8721bab-6c90-43f6-8135-c32fce7aecc0'), ) ) device.add_approval('(approved no_parts)') @@ -333,7 +324,7 @@ def _uuid(identifier: str) -> str: device.serialize(path.join('out', library, 'dev')) -if __name__ == '__main__': +def main() -> None: # Maximum head diameters of standard screws: # # | Screw | ISO4762 | ISO7380 | ISO14580 | DIN965 | @@ -374,4 +365,7 @@ def _uuid(identifier: str) -> str: pad_diameter=pad_diameter, ) - save_cache(uuid_cache_file, uuid_cache) + +if __name__ == '__main__': + with uuid_cache: + main() diff --git a/generate_qfp.py b/generate_qfp.py index 1d6df44..5d55b43 100644 --- a/generate_qfp.py +++ b/generate_qfp.py @@ -14,12 +14,11 @@ from copy import deepcopy from itertools import chain from os import path -from uuid import uuid4 from typing import Dict, Iterable, List, Optional, cast +from common import UuidCache, now, sign from common import format_ipc_dimension as fd -from common import init_cache, now, save_cache, sign from entities.common import ( Align, Angle, @@ -87,9 +86,7 @@ courtyard_around_pads = 0.1 # 100 µm -# Initialize UUID cache -uuid_cache_file = 'uuid_cache_qfp.csv' -uuid_cache = init_cache(uuid_cache_file) +uuid_cache = UuidCache('uuid_cache_qfp.csv') # Based on Footprint Expert Guidelines, Chapter 7.0 (Nominal Calculation) @@ -336,24 +333,6 @@ def get_configs(self) -> List[QfpConfig]: # fmt: on -def uuid(category: str, full_name: str, identifier: str) -> str: - """ - Return a uuid for the specified pin. - - Params: - category: - For example 'cmp' or 'pkg'. - full_name: - For example "SOIC127P762X120-16". - identifier: - For example 'pad-1' or 'pin-13'. - """ - key = '{}-{}-{}'.format(category, full_name, identifier).lower().replace(' ', '~') - if key not in uuid_cache: - uuid_cache[key] = str(uuid4()) - return uuid_cache[key] - - class Pad: def __init__(self, x: float, y: float, orientation: str): self.x = x @@ -440,7 +419,7 @@ def generate_pkg( full_description = config.description() def _uuid(identifier: str) -> str: - return uuid(category, full_name, identifier) + return uuid_cache.get(category, full_name, identifier) uuid_pkg = _uuid('pkg') uuid_pads = [_uuid('pad-{}'.format(p)) for p in range(1, config.lead_count + 1)] @@ -802,7 +781,7 @@ def _create_outline_vertices( add_footprint_variant('density~c', 'Density Level C (min protrusion)', 'C') # Generate 3D models - uuid_3d = uuid('pkg', full_name, '3d') + uuid_3d = uuid_cache.get('pkg', full_name, '3d') if generate_3d_models: generate_3d(library, full_name, uuid_pkg, uuid_3d, config) package.add_3d_model(Package3DModel(uuid_3d, Name(full_name))) @@ -906,7 +885,7 @@ def generate_3d( assembly.save(out_path, fused=False) -if __name__ == '__main__': +def main() -> None: if '--help' in sys.argv or '-h' in sys.argv: print(f'Usage: {sys.argv[0]} [--3d]') print() @@ -930,4 +909,8 @@ def generate_3d( version='0.5', create_date='2019-02-07T21:03:03Z', ) - save_cache(uuid_cache_file, uuid_cache) + + +if __name__ == '__main__': + with uuid_cache: + main() diff --git a/generate_screw_terminals.py b/generate_screw_terminals.py index fc41659..ebf633d 100644 --- a/generate_screw_terminals.py +++ b/generate_screw_terminals.py @@ -5,11 +5,10 @@ import math import sys from os import path -from uuid import uuid4 from typing import Any, Callable, List, Optional -from common import init_cache, now, save_cache +from common import UuidCache, now from entities.attribute import Attribute, AttributeType from entities.common import ( Align, @@ -74,18 +73,9 @@ courtyard_excess = 0.4 -# Initialize UUID cache -uuid_cache_file = 'uuid_cache_screw_terminals.csv' -uuid_cache = init_cache(uuid_cache_file) +uuid_cache = UuidCache('uuid_cache_screw_terminals.csv') -uuid_cache_connectors = init_cache('uuid_cache_connectors.csv') - - -def uuid(category: str, full_name: str, identifier: str) -> str: - key = '{}-{}-{}'.format(category, full_name, identifier).lower().replace(' ', '~') - if key not in uuid_cache: - uuid_cache[key] = str(uuid4()) - return uuid_cache[key] +uuid_cache_connectors = UuidCache('uuid_cache_connectors.csv', stale_check=False) def create_screw_diagonal(y: float, diameter: float, dir: int) -> List[Vertex]: @@ -165,7 +155,7 @@ def __init__(self, name: str, mpn: str, circuits: int, datasheet: Optional[str] def uuid_key(self, family: Family) -> str: return ( - '{}-{}'.format(family.pkg_name_prefix, model.name) + '{}-{}'.format(family.pkg_name_prefix, self.name) .lower() .replace(' ', '') .replace(',', 'p') @@ -215,7 +205,7 @@ def generate_pkg( full_name = family.pkg_name_prefix + '_' + model.name.replace(' ', '_') def _uuid(identifier: str) -> str: - return uuid('pkg', model.uuid_key(family), identifier) + return uuid_cache.get('pkg', model.uuid_key(family), identifier) uuid_pkg = _uuid('pkg') @@ -627,16 +617,17 @@ def generate_dev( full_name = f'{family.dev_name_prefix} {model.name}' def _uuid(identifier: str) -> str: - return uuid('dev', model.uuid_key(family), identifier) + return uuid_cache.get('dev', model.uuid_key(family), identifier) uuid_dev = _uuid('dev') print('Generating {}: {}'.format(full_name, uuid_dev)) connector_uuid_stub = f'cmp-screwterminal-1x{model.circuits}' - component_uuid = uuid_cache_connectors[f'{connector_uuid_stub}-cmp'] + component_uuid = uuid_cache_connectors.get(f'{connector_uuid_stub}-cmp') signal_uuids = [ - uuid_cache_connectors[f'{connector_uuid_stub}-signal-{i}'] for i in range(model.circuits) + uuid_cache_connectors.get(f'{connector_uuid_stub}-signal-{i}') + for i in range(model.circuits) ] device = Device( @@ -651,11 +642,11 @@ def _uuid(identifier: str) -> str: generated_by=GeneratedBy(''), categories=[Category('f9db4ef5-2220-462a-adff-deac8402ecf0')], component_uuid=ComponentUUID(component_uuid), - package_uuid=PackageUUID(uuid('pkg', model.uuid_key(family), 'pkg')), + package_uuid=PackageUUID(uuid_cache.get('pkg', model.uuid_key(family), 'pkg')), ) for i in range(model.circuits): - pad_uuid = uuid('pkg', model.uuid_key(family), 'pad-{}'.format(i + 1)) + pad_uuid = uuid_cache.get('pkg', model.uuid_key(family), 'pad-{}'.format(i + 1)) device.add_pad(ComponentPad(pad_uuid, SignalUUID(signal_uuids[i]))) device.add_part( @@ -684,7 +675,7 @@ def _uuid(identifier: str) -> str: device.serialize(path.join('out', library, 'dev')) -if __name__ == '__main__': +def main() -> None: if '--help' in sys.argv or '-h' in sys.argv: print(f'Usage: {sys.argv[0]} [--3d]') print() @@ -846,4 +837,7 @@ def _uuid(identifier: str) -> str: model=model, ) - save_cache(uuid_cache_file, uuid_cache) + +if __name__ == '__main__': + with uuid_cache: + main() diff --git a/generate_so.py b/generate_so.py index 4c7557a..97dcf79 100644 --- a/generate_so.py +++ b/generate_so.py @@ -11,12 +11,11 @@ import sys from collections import namedtuple from os import path -from uuid import uuid4 from typing import Dict, Iterable, List, Optional, cast +from common import UuidCache, now from common import format_ipc_dimension as fd -from common import init_cache, now, save_cache from entities.common import ( Align, Angle, @@ -124,27 +123,7 @@ ] -# Initialize UUID cache -uuid_cache_file = 'uuid_cache_so.csv' -uuid_cache = init_cache(uuid_cache_file) - - -def uuid(category: str, full_name: str, identifier: str) -> str: - """ - Return a uuid for the specified pin. - - Params: - category: - For example 'cmp' or 'pkg'. - full_name: - For example "SOIC127P762X120-16". - identifier: - For example 'pad-1' or 'pin-13'. - """ - key = '{}-{}-{}'.format(category, full_name, identifier).lower().replace(' ', '~') - if key not in uuid_cache: - uuid_cache[key] = str(uuid4()) - return uuid_cache[key] +uuid_cache = UuidCache('uuid_cache_so.csv', stale_check=False) def excess_by_density(pitch: float, level: str) -> Excess: @@ -251,7 +230,7 @@ def generate_pkg( ) + '\n\nGenerated with {}'.format(generator) def _uuid(identifier: str) -> str: - return uuid(category, full_name, identifier) + return uuid_cache.get(category, full_name, identifier) uuid_pkg = _uuid('pkg') uuid_pads = [_uuid('pad-{}'.format(p)) for p in range(1, pin_count + 1)] @@ -611,7 +590,7 @@ def add_footprint_variant( add_footprint_variant('density~c', 'Density Level C (min protrusion)', 'C') # Generate 3D models - uuid_3d = uuid('pkg', full_name, '3d') + uuid_3d = uuid_cache.get('pkg', full_name, '3d') if generate_3d_models: generate_3d( library, full_name, uuid_pkg, uuid_3d, config, lead_width, lead_contact_length @@ -702,7 +681,7 @@ def generate_3d( assembly.save(out_path, fused=False) -if __name__ == '__main__': +def main() -> None: if '--help' in sys.argv or '-h' in sys.argv: print(f'Usage: {sys.argv[0]} [--3d]') print() @@ -1119,4 +1098,8 @@ def generate_3d( version='0.3', create_date='2020-12-26T16:14:30Z', ) - save_cache(uuid_cache_file, uuid_cache) + + +if __name__ == '__main__': + with uuid_cache: + main() diff --git a/generate_sod.py b/generate_sod.py index bdf2bd5..7763133 100644 --- a/generate_sod.py +++ b/generate_sod.py @@ -4,11 +4,10 @@ import sys from os import path -from uuid import uuid4 from typing import Dict, Iterable, Optional -from common import init_cache, now, save_cache +from common import UuidCache, now from entities.common import ( Align, Angle, @@ -72,29 +71,7 @@ courtyard_excess = 0.25 -# Initialize UUID cache -uuid_cache_file = 'uuid_cache_sod.csv' -uuid_cache = init_cache(uuid_cache_file) - - -def uuid(category: str, full_name: str, identifier: str, create: bool = True) -> str: - """ - Return a uuid for the specified pin. - - Params: - category: - For example 'cmp' or 'pkg'. - full_name: - For example "RESC3216X65". - identifier: - For example 'pad-1' or 'pin-13'. - """ - key = '{}-{}-{}'.format(category, full_name, identifier).lower().replace(' ', '~') - if key not in uuid_cache: - if not create: - raise ValueError('Unknown UUID: {}'.format(key)) - uuid_cache[key] = str(uuid4()) - return uuid_cache[key] +uuid_cache = UuidCache('uuid_cache_sod.csv') class FootprintConfig: @@ -189,7 +166,7 @@ def generate_pkg( ) def _uuid(identifier: str) -> str: - return uuid(category, full_name, identifier) + return uuid_cache.get(category, full_name, identifier) # UUIDs uuid_pkg = _uuid('pkg') @@ -425,7 +402,7 @@ def add_footprint_variant(fpt_config: FootprintConfig) -> None: add_footprint_variant(fpt) # Generate 3D model - uuid_3d = uuid('pkg', full_name, '3d') + uuid_3d = uuid_cache.get('pkg', full_name, '3d') if generate_3d_models: generate_3d(library, full_name, uuid_pkg, uuid_3d, config) package.add_3d_model(Package3DModel(uuid_3d, Name(full_name))) @@ -503,7 +480,7 @@ def generate_3d( assembly.save(out_path, fused=True) -if __name__ == '__main__': +def main() -> None: if '--help' in sys.argv or '-h' in sys.argv: print(f'Usage: {sys.argv[0]} [--3d]') print() @@ -586,4 +563,8 @@ def generate_3d( version='0.2', create_date='2018-12-02T22:17:40Z', ) - save_cache(uuid_cache_file, uuid_cache) + + +if __name__ == '__main__': + with uuid_cache: + main() diff --git a/generate_stm_mcu.py b/generate_stm_mcu.py index a5c1999..23f4823 100644 --- a/generate_stm_mcu.py +++ b/generate_stm_mcu.py @@ -29,12 +29,11 @@ import re from collections import defaultdict from os import listdir, path -from uuid import uuid4 from typing import Any, DefaultDict, Dict, Iterable, Iterator, List, Optional, Set, Tuple import common -from common import human_sort_key, init_cache, save_cache +from common import UuidCache, human_sort_key from entities.common import ( Align, Angle, @@ -97,27 +96,7 @@ cmpcat = [Category('22151601-c2d9-419a-87bc-266f9c7c3459')] outdir = path.join('out', 'STMicroelectronics.lplib') -# Initialize UUID cache -uuid_cache_file = 'uuid_cache_stm_mcu.csv' -uuid_cache = init_cache(uuid_cache_file) - - -def uuid(category: str, full_name: str, identifier: str) -> str: - """ - Return a uuid for the specified item. - - Params: - category: - For example 'cmp' or 'sym'. - full_name: - For example "STM32WB55CEUx". - identifier: - For example 'sym' or 'pin-pb9'. - """ - key = '{}-{}-{}'.format(category, full_name, identifier).lower().replace(' ', '~') - if key not in uuid_cache: - uuid_cache[key] = str(uuid4()) - return uuid_cache[key] +uuid_cache = UuidCache('uuid_cache_stm_mcu.csv') class Pin: @@ -636,7 +615,7 @@ def generate_sym(mcus: List[MCU], symbol_map: Dict[str, str], debug: bool = Fals if debug: print(pin_mapping) - uuid_sym = uuid('sym', mcu.symbol_identifier, 'sym') + uuid_sym = uuid_cache.get('sym', mcu.symbol_identifier, 'sym') symbol = Symbol( uuid_sym, Name(mcu.symbol_name), @@ -654,7 +633,7 @@ def generate_sym(mcus: List[MCU], symbol_map: Dict[str, str], debug: bool = Fals for pin_name, position, rotation in placement.pins(width, grid): symbol.add_pin( SymbolPin( - uuid('sym', mcu.symbol_identifier, 'pin-{}'.format(pin_name)), + uuid_cache.get('sym', mcu.symbol_identifier, 'pin-{}'.format(pin_name)), Name(pin_name), position, rotation, @@ -666,7 +645,7 @@ def generate_sym(mcus: List[MCU], symbol_map: Dict[str, str], debug: bool = Fals ) ) polygon = Polygon( - uuid('sym', mcu.symbol_identifier, 'polygon'), + uuid_cache.get('sym', mcu.symbol_identifier, 'polygon'), Layer('sym_outlines'), Width(line_width), Fill(False), @@ -682,7 +661,7 @@ def generate_sym(mcus: List[MCU], symbol_map: Dict[str, str], debug: bool = Fals symbol.add_polygon(polygon) text_name = Text( - uuid('sym', mcu.symbol_identifier, 'text-name'), + uuid_cache.get('sym', mcu.symbol_identifier, 'text-name'), Layer('sym_names'), Value('{{NAME}}'), Align('left bottom'), @@ -691,7 +670,7 @@ def generate_sym(mcus: List[MCU], symbol_map: Dict[str, str], debug: bool = Fals Rotation(0.0), ) text_value = Text( - uuid('sym', mcu.symbol_identifier, 'text-value'), + uuid_cache.get('sym', mcu.symbol_identifier, 'text-value'), Layer('sym_values'), Value('{{VALUE}}'), Align('left top'), @@ -743,7 +722,7 @@ def generate_cmp( cmp_version = '0.1' component = Component( - uuid('cmp', mcu.component_identifier, 'cmp'), + uuid_cache.get('cmp', mcu.component_identifier, 'cmp'), Name(name), Description(mcu.component_description), mcu.keywords, @@ -765,7 +744,7 @@ def generate_cmp( Signal( # Use original signal name, so that changing the cleanup function # does not influence the identifier. - uuid('cmp', mcu.component_identifier, 'signal-{}'.format(signal)), + uuid_cache.get('cmp', mcu.component_identifier, 'signal-{}'.format(signal)), # Use cleaned up signal name for name Name(signal), Role.PASSIVE, @@ -778,8 +757,8 @@ def generate_cmp( # Add symbol variant gate = Gate( - uuid('cmp', mcu.component_identifier, 'variant-single-gate1'), - SymbolUUID(uuid('sym', mcu.symbol_identifier, 'sym')), + uuid_cache.get('cmp', mcu.component_identifier, 'variant-single-gate1'), + SymbolUUID(uuid_cache.get('sym', mcu.symbol_identifier, 'sym')), Position(0, 0), Rotation(0.0), Required(True), @@ -788,14 +767,18 @@ def generate_cmp( for generic, concrete in pin_mapping.items(): gate.add_pin_signal_map( PinSignalMap( - uuid('sym', mcu.symbol_identifier, 'pin-{}'.format(generic)), - SignalUUID(uuid('cmp', mcu.component_identifier, 'signal-{}'.format(concrete))), + uuid_cache.get('sym', mcu.symbol_identifier, 'pin-{}'.format(generic)), + SignalUUID( + uuid_cache.get( + 'cmp', mcu.component_identifier, 'signal-{}'.format(concrete) + ) + ), TextDesignator.SIGNAL_NAME, ) ) component.add_variant( Variant( - uuid('cmp', mcu.component_identifier, 'variant-single'), + uuid_cache.get('cmp', mcu.component_identifier, 'variant-single'), Norm.EMPTY, Name('single'), Description('Symbol with all MCU pins'), @@ -843,7 +826,7 @@ def generate_dev( pad_uuid_mapping = common.get_pad_uuids(base_lib_path, package_uuid_mapping[mcu.package]) device = Device( - uuid('dev', mcu.ref, 'dev'), + uuid_cache.get('dev', mcu.ref, 'dev'), Name(mcu.ref), Description(mcu.description), mcu.keywords, @@ -853,7 +836,7 @@ def generate_dev( Deprecated(False), GeneratedBy(''), cmpcat, - ComponentUUID(uuid('cmp', mcu.component_identifier, 'cmp')), + ComponentUUID(uuid_cache.get('cmp', mcu.component_identifier, 'cmp')), PackageUUID(package_uuid_mapping[mcu.package]), ) for pin in mcu.pins: @@ -861,7 +844,9 @@ def generate_dev( device.add_pad( ComponentPad( pad_uuid, - SignalUUID(uuid('cmp', mcu.component_identifier, 'signal-{}'.format(pin.name))), + SignalUUID( + uuid_cache.get('cmp', mcu.component_identifier, 'signal-{}'.format(pin.name)) + ), ) ) @@ -904,7 +889,7 @@ def generate(data: Dict[str, MCU], base_lib_path: str, debug: bool = False) -> N generate_dev(mcu, symbol_map, base_lib_path, debug) -if __name__ == '__main__': +def main() -> None: parser = argparse.ArgumentParser(description='Generate STM MCU library elements') parser.add_argument( '--data-dir', @@ -945,4 +930,8 @@ def generate(data: Dict[str, MCU], base_lib_path: str, debug: bool = False) -> N generate(data, args.base_lib, args.debug) print() - save_cache(uuid_cache_file, uuid_cache) + + +if __name__ == '__main__': + with uuid_cache: + main() diff --git a/generate_tactile_switches.py b/generate_tactile_switches.py index 8a549e0..ed14cde 100644 --- a/generate_tactile_switches.py +++ b/generate_tactile_switches.py @@ -4,11 +4,10 @@ import sys from os import path -from uuid import uuid4 from typing import List, Optional, Tuple, Union -from common import init_cache, now, save_cache +from common import UuidCache, now from entities.attribute import Attribute, AttributeType from entities.common import ( Align, @@ -73,16 +72,7 @@ courtyard_excess = 0.4 -# Initialize UUID cache -uuid_cache_file = 'uuid_cache_tactile_switches.csv' -uuid_cache = init_cache(uuid_cache_file) - - -def uuid(category: str, full_name: str, identifier: str) -> str: - key = '{}-{}-{}'.format(category, full_name, identifier).lower().replace(' ', '~') - if key not in uuid_cache: - uuid_cache[key] = str(uuid4()) - return uuid_cache[key] +uuid_cache = UuidCache('uuid_cache_tactile_switches.csv') class ThtLeadConfig: @@ -188,7 +178,7 @@ def __init__( def uuid_key(self, family: Family) -> str: return ( - '{}-{}'.format(family.pkg_name_prefix, model.name) + '{}-{}'.format(family.pkg_name_prefix, self.name) .lower() .replace(' ', '') .replace(',', 'p') @@ -232,7 +222,7 @@ def generate_pkg( full_name = family.pkg_name_prefix + '_' + model.name.replace(' ', '_') def _uuid(identifier: str) -> str: - return uuid('pkg', model.uuid_key(family), identifier) + return uuid_cache.get('pkg', model.uuid_key(family), identifier) uuid_pkg = _uuid('pkg') @@ -705,7 +695,7 @@ def generate_dev( full_name = f'{family.dev_name_prefix} {model.name}' def _uuid(identifier: str) -> str: - return uuid('dev', model.uuid_key(family), identifier) + return uuid_cache.get('dev', model.uuid_key(family), identifier) uuid_dev = _uuid('dev') @@ -723,7 +713,7 @@ def _uuid(identifier: str) -> str: generated_by=GeneratedBy(''), categories=[Category('e29f0cb3-ef6d-4203-b854-d75150cbae0b')], component_uuid=ComponentUUID('6eedad0b-5b41-4233-9b7b-8be1ee8527e0'), - package_uuid=PackageUUID(uuid('pkg', model.uuid_key(family), 'pkg')), + package_uuid=PackageUUID(uuid_cache.get('pkg', model.uuid_key(family), 'pkg')), ) signal_uuids = [ @@ -732,7 +722,7 @@ def _uuid(identifier: str) -> str: ] for i in range(4): - pad_uuid = uuid('pkg', model.uuid_key(family), 'pad-{}'.format(i + 1)) + pad_uuid = uuid_cache.get('pkg', model.uuid_key(family), 'pad-{}'.format(i + 1)) device.add_pad(ComponentPad(pad_uuid, SignalUUID(signal_uuids[i // 2]))) for part in model.parts: @@ -751,7 +741,7 @@ def _uuid(identifier: str) -> str: device.serialize(path.join('out', library, 'dev')) -if __name__ == '__main__': +def main() -> None: if '--help' in sys.argv or '-h' in sys.argv: print(f'Usage: {sys.argv[0]} [--3d]') print() @@ -1529,4 +1519,7 @@ def _uuid(identifier: str) -> str: model=model, ) - save_cache(uuid_cache_file, uuid_cache) + +if __name__ == '__main__': + with uuid_cache: + main() diff --git a/pyproject.toml b/pyproject.toml index 5c08828..a5a31f7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,6 +8,9 @@ authors = [ requires-python = ">=3.10" dependencies = [ "cadquery == 2.6.1", + # casadi 3.8.0 ships a casadi.pyi with duplicate parameter names, which breaks mypy. + # Fix planned for 3.8.1: https://github.com/casadi/casadi/issues/4390 + "casadi != 3.8.0", ] version = "0.1.0"