Python script to check KiCad footprint libraries for duplicate UUIDs

This script will check each individual footprint file for duplicate UUIDs

#!/usr/bin/env python3
import os
import re
import argparse
from collections import defaultdict

def find_kicad_mod_files(root_dir):
    """Recursively find all .kicad_mod files in the given directory."""
    kicad_mod_files = []
    for dirpath, _, filenames in os.walk(root_dir):
        for filename in filenames:
            if filename.endswith('.kicad_mod'):
                kicad_mod_files.append(os.path.join(dirpath, filename))
    return kicad_mod_files

def extract_uuids(file_path):
    """Extract all UUIDs from a given .kicad_mod file."""
    uuid_pattern = re.compile(r'\(uuid "([0-9a-fA-F-]+)"\)')
    uuids = []
    with open(file_path, 'r') as file:
        for line in file:
            match = uuid_pattern.search(line)
            if match:
                uuids.append(match.group(1))
    return uuids

def check_duplicate_uuids(uuids):
    """Check for duplicate UUIDs in the list and return them."""
    uuid_count = defaultdict(int)
    for uuid in uuids:
        uuid_count[uuid] += 1
    duplicates = [uuid for uuid, count in uuid_count.items() if count > 1]
    return duplicates

def main(root_dir):
    kicad_mod_files = find_kicad_mod_files(root_dir)
    for file_path in kicad_mod_files:
        uuids = extract_uuids(file_path)
        duplicates = check_duplicate_uuids(uuids)
        if duplicates:
            print(f"Duplicate UUIDs found in {file_path}: {duplicates}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Check for duplicate UUIDs in .kicad_mod files.')
    parser.add_argument('root_dir', type=str, help='The root directory to search for .kicad_mod files.')
    args = parser.parse_args()
    
    main(args.root_dir)

Usage

python3 check-duplicate-uuids.py kicad-footprints

Example output

Duplicate UUIDs found in ./Connector_Audio.pretty/Jack_3.5mm_Lumberg_1503_07_Horizontal.kicad_mod: ['5d89b84d-1724-4295-a6de-f4c29a1b88c4', '97162d26-e840-41f4-adb4-b92b38c5a58d', '596db706-3656-4d79-8d35-c213f53513c2']
Duplicate UUIDs found in ./Module.pretty/Arduino_Nano_WithMountingHoles.kicad_mod: ['afb53f55-89fc-467f-b192-5ef16ddd17c7']
Duplicate UUIDs found in ./RF_GPS.pretty/ublox_SAM-M8Q.kicad_mod: ['f39553a8-4ba2-4021-a968-74b5a9402e10']
Duplicate UUIDs found in ./Connector_RJ.pretty/RJ12_Amphenol_54601-x06_Horizontal.kicad_mod: ['ca7c8ade-6e68-4498-be5c-636214cec9ba']
Duplicate UUIDs found in ./Connector_RJ.pretty/RJ45_Amphenol_RJMG1BD3B8K1ANR.kicad_mod: ['a7ea8871-0814-496d-bea8-76acf87a9f1d']
Duplicate UUIDs found in ./Rotary_Encoder.pretty/RotaryEncoder_Bourns_Horizontal_PEC12R-2x17F-Sxxxx.kicad_mod: ['fbe20761-a4dd-4717-a1ee-ee163a29403c']
Duplicate UUIDs found in ./Rotary_Encoder.pretty/RotaryEncoder_Bourns_Vertical_PEC12R-3x17F-Sxxxx.kicad_mod: ['2121f37f-d564-4d19-b967-c2e3a11ee91d', 'da838f91-01ea-4baa-80d5-cd2ec5938d95']
Duplicate UUIDs found in ./Rotary_Encoder.pretty/RotaryEncoder_Bourns_Horizontal_PEC12R-2x17F-Nxxxx.kicad_mod: ['fbe20761-a4dd-4717-a1ee-ee163a29403c']
Duplicate UUIDs found in ./OptoDevice.pretty/Everlight_ITR9608-F.kicad_mod: ['31cbb4e1-301b-41e3-84aa-8889ec650a31']
Duplicate UUIDs found in ./Relay_THT.pretty/Relay_SPDT_Finder_40.11.kicad_mod: ['63c01b9c-4254-44f3-88b5-efcdc8449585']
Duplicate UUIDs found in ./Relay_THT.pretty/Relay_DPDT_Finder_40.52.kicad_mod: ['2ad24060-daab-4eec-8ede-478de9642fcc']
Duplicate UUIDs found in ./Connector_BarrelJack.pretty/BarrelJack_Wuerth_694102107102_1.0x3.9mm.kicad_mod: ['c7b3235a-ca21-4d5b-9cb8-5cd1c9ffac20']
Duplicate UUIDs found in ./Connector_BarrelJack.pretty/BarrelJack_Wuerth_694103107102_1.35x3.9mm.kicad_mod: ['c7b3235a-ca21-4d5b-9cb8-5cd1c9ffac20']
Duplicate UUIDs found in ./Potentiometer_THT.pretty/Potentiometer_Bourns_PTV112-4_Dual_Vertical.kicad_mod: ['ce46aad6-930d-4f62-b34c-aa3cfe63aff6', 'fc4aa5ce-c916-41ac-a552-27fa764ea7a1']
Duplicate UUIDs found in ./Connector_TE-Connectivity.pretty/TE_2834006-2_1x02_P4.0mm_Horizontal.kicad_mod: ['cfdfed8e-5d84-4c6d-942c-ee1b9b80924b', '9de75ce7-a14d-4cdd-b274-c644b1382308']
Duplicate UUIDs found in ./Package_DFN_QFN.pretty/Texas_MOF0009A.kicad_mod: ['14f8887d-4cb1-49e2-9618-9bb2e36b411d']
Duplicate UUIDs found in ./Package_DFN_QFN.pretty/OnSemi_SIP-38-6EP-9x7mm_P0.65mm_EP1.2x1.2mm.kicad_mod: ['36c37ae9-764e-4604-8fd1-0bd8202db0fa']