feat: Week 1 complete - Linux support + IPC API prep

🎉 Major v2.0 rebuild kickoff - Week 1 accomplished!

## Highlights

### Cross-Platform Support 🌍
-  Linux primary platform (Ubuntu/Debian tested)
-  Windows fully supported
-  macOS experimental support
-  Platform-agnostic path handling (XDG spec)
-  Auto-detection of KiCAD installation

### Infrastructure 🏗️
-  GitHub Actions CI/CD pipeline
-  Pytest framework with 20+ tests
-  Pre-commit hooks (Black, MyPy, ESLint)
-  Automated Linux installation script
-  Enhanced npm scripts

### IPC API Migration Prep 🚀
-  Comprehensive migration plan (30 pages)
-  Backend abstraction layer (800+ lines)
-  Factory pattern with auto-detection
-  SWIG backward compatibility wrapper
-  IPC backend skeleton ready

### Documentation 📚
-  Updated README (Linux installation)
-  CONTRIBUTING.md guide
-  Linux compatibility audit
-  IPC API migration plan
-  Session summaries
-  Platform-specific config templates

## Files Changed

- 27 files created
- ~3,000 lines of code/docs
- 8 comprehensive documentation pages
- 20+ unit tests
- 5 abstraction layer modules

## Next Steps

- Week 2: IPC API migration (project.py → component.py → routing.py)
- Migrate from deprecated SWIG to official IPC API
- JLCPCB/Digikey integration prep

🤖 Generated with Claude Code
https://claude.com/claude-code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
KiCAD MCP Bot
2025-10-25 20:48:00 -04:00
commit e4c7119c51
81 changed files with 16003 additions and 0 deletions

View File

@@ -0,0 +1,86 @@
(kicad_pcb
(version 20241229)
(generator "pcbnew")
(generator_version "9.0")
(general
(thickness 1.6)
(legacy_teardrops no)
)
(paper "A4")
(title_block
(title "TestProject")
(date "2025-04-26")
)
(layers
(0 "F.Cu" signal)
(2 "B.Cu" signal)
(9 "F.Adhes" user "F.Adhesive")
(11 "B.Adhes" user "B.Adhesive")
(13 "F.Paste" user)
(15 "B.Paste" user)
(5 "F.SilkS" user "F.Silkscreen")
(7 "B.SilkS" user "B.Silkscreen")
(1 "F.Mask" user)
(3 "B.Mask" user)
(17 "Dwgs.User" user "User.Drawings")
(19 "Cmts.User" user "User.Comments")
(21 "Eco1.User" user "User.Eco1")
(23 "Eco2.User" user "User.Eco2")
(25 "Edge.Cuts" user)
(27 "Margin" user)
(31 "F.CrtYd" user "F.Courtyard")
(29 "B.CrtYd" user "B.Courtyard")
(35 "F.Fab" user)
(33 "B.Fab" user)
(39 "User.1" user)
(41 "User.2" user)
(43 "User.3" user)
(45 "User.4" user)
)
(setup
(pad_to_mask_clearance 0)
(allow_soldermask_bridges_in_footprints no)
(tenting front back)
(pcbplotparams
(layerselection 0x00000000_00000000_55555555_5755f5ff)
(plot_on_all_layers_selection 0x00000000_00000000_00000000_00000000)
(disableapertmacros no)
(usegerberextensions no)
(usegerberattributes yes)
(usegerberadvancedattributes yes)
(creategerberjobfile yes)
(dashed_line_dash_ratio 12.000000)
(dashed_line_gap_ratio 3.000000)
(svgprecision 4)
(plotframeref no)
(mode 1)
(useauxorigin no)
(hpglpennumber 1)
(hpglpenspeed 20)
(hpglpendiameter 15.000000)
(pdf_front_fp_property_popups yes)
(pdf_back_fp_property_popups yes)
(pdf_metadata yes)
(pdf_single_document no)
(dxfpolygonmode yes)
(dxfimperialunits yes)
(dxfusepcbnewfont yes)
(psnegative no)
(psa4output no)
(plot_black_and_white yes)
(sketchpadsonfab no)
(plotpadnumbers no)
(hidednponfab no)
(sketchdnponfab yes)
(crossoutdnponfab yes)
(subtractmaskfromsilk no)
(outputformat 1)
(mirror no)
(drillshape 1)
(scaleselection 1)
(outputdirectory "")
)
)
(net 0 "")
(embedded_fonts no)
)

View File

@@ -0,0 +1,5 @@
{
"board": {
"filename": "TestProject.kicad_pcb"
}
}

50
test/check_skip.py Normal file
View File

@@ -0,0 +1,50 @@
#!/usr/bin/env python3
"""
Simple script to check if the skip module is available
"""
import sys
import traceback
print("Python executable:", sys.executable)
print("Python version:", sys.version)
try:
print("Attempting to import skip module...")
import skip
print("Successfully imported skip module!")
print("Skip module version:", getattr(skip, "__version__", "Unknown"))
print("Skip module path:", skip.__file__)
# Check if Schematic class is available
print("\nChecking for Schematic class...")
if hasattr(skip, "Schematic"):
print("Schematic class is available!")
# Create a schematic object
print("Creating schematic object...")
sch = skip.Schematic()
print("Successfully created schematic object!")
# Check for methods and attributes we use
print("\nChecking schematic methods/attributes:")
print("- add_symbol method:", hasattr(sch, "add_symbol"))
print("- add_wire method:", hasattr(sch, "add_wire"))
print("- save method:", hasattr(sch, "save"))
print("- version attribute:", hasattr(sch, "version"))
else:
print("ERROR: Schematic class is NOT available in the skip module!")
# List all available classes/functions in the skip module
print("\nAvailable members in skip module:")
for name in dir(skip):
if not name.startswith("_"): # Skip private/internal items
print(f"- {name}")
except ImportError as e:
print(f"ERROR: Failed to import skip module: {e}")
traceback.print_exc()
except Exception as e:
print(f"ERROR: An unexpected error occurred: {e}")
traceback.print_exc()

121
test/example_skip_usage.py Normal file
View File

@@ -0,0 +1,121 @@
#!/usr/bin/env python3
"""
Example script to inspect and document kicad-skip library capabilities
"""
import sys
import inspect
import os
import traceback
def main():
"""Examine the kicad-skip library functionality"""
print("=== Examining kicad-skip library ===")
try:
# Import the module
print("Importing skip module...")
import skip
print(f"Skip module path: {skip.__file__}")
# Display module contents
print("\nSkip module contents:")
for item_name in dir(skip):
if not item_name.startswith('_'):
try:
item = getattr(skip, item_name)
if inspect.isclass(item):
print(f" Class: {item_name}")
# List methods of the class
for method_name in dir(item):
if not method_name.startswith('_'):
method = getattr(item, method_name)
if inspect.ismethod(method) or inspect.isfunction(method):
print(f" - Method: {method_name}")
elif inspect.isfunction(item):
print(f" Function: {item_name}")
else:
print(f" Other: {item_name} (type: {type(item).__name__})")
except Exception as e:
print(f" Error examining {item_name}: {e}")
# Test Schematic class specifically
print("\nExamining Schematic class:")
if hasattr(skip, 'Schematic'):
schematic_class = skip.Schematic
print(f"Schematic class: {schematic_class}")
# Check initialization parameters
try:
sig = inspect.signature(schematic_class.__init__)
print(f"Schematic.__init__ signature: {sig}")
# List required parameters
required_params = [
name for name, param in sig.parameters.items()
if param.default == inspect.Parameter.empty and name != 'self'
]
print(f"Required parameters: {required_params}")
# Display initialization docstring
print(f"__init__ docstring: {schematic_class.__init__.__doc__}")
except Exception as e:
print(f"Error examining Schematic.__init__: {e}")
# Create a simple test file
test_dir = os.path.dirname(__file__)
test_file = os.path.join(test_dir, 'test_example.kicad_sch')
with open(test_file, 'w') as f:
f.write("(kicad_sch (version 20230121) (generator \"Test Example\"))\n")
# Try loading the test file
print(f"\nLoading test file {test_file}")
try:
sch = skip.Schematic(test_file)
print("Successfully created Schematic object")
# Examine the object's attributes and methods
print("\nSchematic object attributes:")
for attr_name in dir(sch):
if not attr_name.startswith('_'):
try:
attr = getattr(sch, attr_name)
if callable(attr):
print(f" Method: {attr_name}")
else:
print(f" Attribute: {attr_name} = {attr}")
except Exception as e:
print(f" Error examining {attr_name}: {e}")
# Check for io-related methods
print("\nLooking for IO-related methods:")
for method_name in ['save', 'write', 'to_file', 'export', 'dump']:
print(f" Has '{method_name}' method: {hasattr(sch, method_name)}")
# Examine the representation of the object
print(f"\nStr representation: {str(sch)}")
print(f"Repr representation: {repr(sch)}")
# Clean up
os.remove(test_file)
except Exception as e:
print(f"Error testing Schematic: {e}")
traceback.print_exc()
# Clean up even on error
if os.path.exists(test_file):
os.remove(test_file)
else:
print("Schematic class not found in skip module")
except ImportError as e:
print(f"Failed to import skip module: {e}")
except Exception as e:
print(f"An unexpected error occurred: {e}")
traceback.print_exc()
print("\n=== Examination completed ===")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,93 @@
#!/usr/bin/env python3
"""
Manual test script for the schematic functionality
"""
import sys
import os
# Add the parent directory to the module search path
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
# Import our schematic modules
from python.commands.schematic import SchematicManager
from python.commands.component_schematic import ComponentManager
from python.commands.connection_schematic import ConnectionManager
def main():
"""Run a basic test of schematic functionality"""
print("=== Starting manual schematic test ===")
# Set up test output directory
test_dir = os.path.join(os.path.dirname(__file__), 'schematic_test_output')
if not os.path.exists(test_dir):
os.makedirs(test_dir)
# 1. Create a new schematic
schematic_name = "TestCircuitManual"
schematic_path = os.path.join(test_dir, f"{schematic_name}.kicad_sch")
print(f"Creating schematic: {schematic_name}")
schematic = SchematicManager.create_schematic(schematic_name)
# 2. Add components to the schematic
print("Adding components to schematic...")
# Add resistor R1
r1_def = {
"type": "R",
"reference": "R1",
"value": "10k",
"library": "Device",
"x": 100,
"y": 100
}
r1 = ComponentManager.add_component(schematic, r1_def)
# Add resistor R2
r2_def = {
"type": "R",
"reference": "R2",
"value": "4.7k",
"library": "Device",
"x": 100,
"y": 200
}
r2 = ComponentManager.add_component(schematic, r2_def)
# Add capacitor C1
c1_def = {
"type": "C",
"reference": "C1",
"value": "0.1uF",
"library": "Device",
"x": 200,
"y": 150
}
c1 = ComponentManager.add_component(schematic, c1_def)
# 3. Add wires to connect components
print("Adding wires to connect components...")
# Connect R1 to R2
wire1 = ConnectionManager.add_wire(schematic, [150, 100], [150, 200])
# Connect R2 to C1
wire2 = ConnectionManager.add_wire(schematic, [150, 200], [200, 200])
# Connect C1 to R1
wire3 = ConnectionManager.add_wire(schematic, [200, 100], [150, 100])
# 4. Save the schematic
print(f"Saving schematic to: {schematic_path}")
success = SchematicManager.save_schematic(schematic, schematic_path)
if success:
print(f"Successfully saved schematic to: {schematic_path}")
else:
print("Failed to save schematic")
print("=== Manual schematic test completed ===")
if __name__ == "__main__":
main()

87
test/skip_test.py Normal file
View File

@@ -0,0 +1,87 @@
#!/usr/bin/env python3
"""
Simple test script for the kicad-skip library functionality
This test doesn't depend on KiCAD's Python modules like pcbnew.
"""
import sys
import os
import traceback
def main():
"""Test basic kicad-skip functionality"""
print("=== Testing kicad-skip schematic functionality ===")
# Set up test output directory
test_dir = os.path.join(os.path.dirname(__file__), 'schematic_test_output')
if not os.path.exists(test_dir):
os.makedirs(test_dir)
print("Test directory:", test_dir)
try:
# Import skip module
print("Importing skip module...")
from skip import Schematic
print("Successfully imported skip module")
# Create a new schematic
print("Creating new schematic...")
sch = Schematic()
sch.version = "20230121"
sch.generator = "KiCAD-MCP-Server-Test"
print("Created schematic object with version:", sch.version)
# Add resistor component
print("Adding resistor component...")
resistor = sch.add_symbol(
lib="Device",
name="R",
reference="R1",
at=[100, 100],
unit=1
)
resistor.property.Value.value = "10k"
print("Added resistor:", resistor.reference, resistor.property.Value.value)
# Add capacitor component
print("Adding capacitor component...")
capacitor = sch.add_symbol(
lib="Device",
name="C",
reference="C1",
at=[200, 100],
unit=1
)
capacitor.property.Value.value = "0.1uF"
print("Added capacitor:", capacitor.reference, capacitor.property.Value.value)
# Add wire connection
print("Adding wire connection...")
wire = sch.add_wire(start=[100, 150], end=[200, 150])
print("Added wire from", wire.start, "to", wire.end)
# Save the schematic
schematic_path = os.path.join(test_dir, "skip_test.kicad_sch")
print(f"Saving schematic to: {schematic_path}")
sch.save(schematic_path)
print(f"Schematic saved to: {schematic_path}")
# Verify the file exists
if os.path.exists(schematic_path):
print(f"SUCCESS: Schematic file created at: {schematic_path}")
print(f"File size: {os.path.getsize(schematic_path)} bytes")
else:
print(f"ERROR: Failed to create schematic file at: {schematic_path}")
except ImportError as e:
print(f"ERROR: Failed to import required modules: {e}")
traceback.print_exc()
except Exception as e:
print(f"ERROR: An unexpected error occurred: {e}")
traceback.print_exc()
print("=== Test completed ===")
if __name__ == "__main__":
main()

230
test/test_schematic.js Normal file
View File

@@ -0,0 +1,230 @@
import { spawn } from 'child_process';
import path from 'path';
import fs from 'fs';
import { fileURLToPath } from 'url';
// Get current file directory (ESM equivalent of __dirname)
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
/**
* Test script for the schematic generation functionality
*
* This script tests the KiCAD MCP server's schematic generation capabilities by:
* 1. Creating a new schematic
* 2. Adding components (resistors, capacitors)
* 3. Adding connections between them
* 4. Exporting the schematic to PDF
*/
// Directory for test outputs
const TEST_OUTPUT_DIR = path.join(__dirname, 'schematic_test_output');
if (!fs.existsSync(TEST_OUTPUT_DIR)) {
fs.mkdirSync(TEST_OUTPUT_DIR, { recursive: true });
}
// Function to send a command to the KiCAD MCP server
function sendCommand(serverProcess, command, params) {
return new Promise((resolve, reject) => {
// Create request object
const request = {
command,
params
};
// Convert to JSON and add newline
const requestStr = JSON.stringify(request) + '\n';
// Write to stdin of server process
console.log(`Sending request to server: ${requestStr}`);
serverProcess.stdin.write(requestStr);
// Set up response handler
let responseData = '';
const responseHandler = (data) => {
const chunk = data.toString();
console.log(`Received data: ${chunk}`);
responseData += chunk;
try {
// Try to parse as JSON
const response = JSON.parse(responseData);
// Got a complete response
console.log(`Parsed complete response: ${JSON.stringify(response)}`);
serverProcess.stdout.removeListener('data', responseHandler);
resolve(response);
} catch (e) {
// Not complete JSON yet, keep collecting
console.log(`JSON parsing failed, continuing to collect data: ${e.message}`);
}
};
// Set a timeout to prevent hanging indefinitely
const timeoutId = setTimeout(() => {
console.log("Command timeout after 10 seconds");
serverProcess.stdout.removeListener('data', responseHandler);
resolve({
success: false,
message: "Timeout waiting for response from server"
});
}, 10000); // 10 second timeout
// Listen for response
serverProcess.stdout.on('data', responseHandler);
// Handle errors
serverProcess.stderr.on('data', (data) => {
console.error(`Server stderr: ${data.toString()}`);
});
});
}
async function runTest() {
console.log('\n=== TESTING SCHEMATIC GENERATION ===\n');
// Start the KiCAD MCP server
console.log('Starting KiCAD MCP server...');
// Use shell: true to ensure proper command execution in Windows
const serverProcess = spawn('node', ['dist/kicad-server.js'], {
stdio: ['pipe', 'pipe', 'pipe'],
shell: true
});
// Log server startup messages
serverProcess.stderr.on('data', (data) => {
console.log(`Server startup: ${data.toString()}`);
});
// Give server time to start
console.log('Waiting for server to start...');
await new Promise(resolve => setTimeout(resolve, 5000));
console.log('Server should be ready now');
try {
// 1. Create a new schematic
const schematicName = 'TestCircuit';
const schematicPath = path.join(TEST_OUTPUT_DIR, `${schematicName}.kicad_sch`);
console.log(`Creating schematic: ${schematicName}...`);
const createResult = await sendCommand(serverProcess, 'create_schematic', {
projectName: schematicName,
path: TEST_OUTPUT_DIR,
metadata: {
description: 'Test circuit schematic',
author: 'KiCAD MCP Test'
}
});
console.log('Create schematic result:', createResult);
if (!createResult.success) {
throw new Error(`Failed to create schematic: ${createResult.message}`);
}
// 2. Add components: resistors, capacitor, and power/ground connections
console.log('Adding components to schematic...');
// Add resistor R1
const addR1Result = await sendCommand(serverProcess, 'add_schematic_component', {
schematicPath: schematicPath,
component: {
type: 'R',
reference: 'R1',
value: '10k',
library: 'Device',
x: 100,
y: 100
}
});
console.log('Add R1 result:', addR1Result);
// Add resistor R2
const addR2Result = await sendCommand(serverProcess, 'add_schematic_component', {
schematicPath: schematicPath,
component: {
type: 'R',
reference: 'R2',
value: '4.7k',
library: 'Device',
x: 100,
y: 200
}
});
console.log('Add R2 result:', addR2Result);
// Add capacitor C1
const addC1Result = await sendCommand(serverProcess, 'add_schematic_component', {
schematicPath: schematicPath,
component: {
type: 'C',
reference: 'C1',
value: '0.1uF',
library: 'Device',
x: 200,
y: 150
}
});
console.log('Add C1 result:', addC1Result);
// 3. Add wires to connect components
console.log('Adding wires to connect components...');
// Connect R1 to R2
const addWire1Result = await sendCommand(serverProcess, 'add_schematic_wire', {
schematicPath: schematicPath,
startPoint: [150, 100],
endPoint: [150, 200]
});
console.log('Add wire 1 result:', addWire1Result);
// Connect R2 to C1
const addWire2Result = await sendCommand(serverProcess, 'add_schematic_wire', {
schematicPath: schematicPath,
startPoint: [150, 200],
endPoint: [200, 200]
});
console.log('Add wire 2 result:', addWire2Result);
// Connect C1 to R1
const addWire3Result = await sendCommand(serverProcess, 'add_schematic_wire', {
schematicPath: schematicPath,
startPoint: [200, 100],
endPoint: [150, 100]
});
console.log('Add wire 3 result:', addWire3Result);
// 4. Export to PDF
console.log('Exporting schematic to PDF...');
const pdfPath = path.join(TEST_OUTPUT_DIR, `${schematicName}.pdf`);
const exportResult = await sendCommand(serverProcess, 'export_schematic_pdf', {
schematicPath: schematicPath,
outputPath: pdfPath
});
console.log('Export PDF result:', exportResult);
if (exportResult.success) {
console.log(`PDF successfully created at: ${pdfPath}`);
} else {
console.log(`Failed to create PDF: ${exportResult.message}`);
}
console.log('\n=== SCHEMATIC GENERATION TEST COMPLETED ===\n');
console.log(`Schematic file: ${schematicPath}`);
console.log(`PDF file: ${pdfPath}`);
} catch (error) {
console.error('Test error:', error);
} finally {
// Kill the server process
serverProcess.kill();
}
}
// Run the test
runTest().catch(console.error);

View File

@@ -0,0 +1,111 @@
#!/usr/bin/env python3
"""
Debug test script for the schematic manager implementation
"""
import sys
import os
import traceback
# Add the parent directory to the module search path
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
def main():
"""Test the SchematicManager functions with detailed debug output"""
print("=== DEBUGGING SchematicManager functionality ===")
# Set up test output directory
test_dir = os.path.join(os.path.dirname(__file__), 'schematic_test_output')
if not os.path.exists(test_dir):
os.makedirs(test_dir)
print("Test directory:", test_dir)
try:
# Import directly from skip for comparison
print("Importing skip module...")
from skip import Schematic
print("Successfully imported skip module")
# Create a template file directly
template_path = os.path.join(test_dir, "debug_template.kicad_sch")
print(f"Creating template file at: {template_path}")
with open(template_path, 'w') as f:
f.write("(kicad_sch (version 20230121) (generator \"KiCAD-MCP-Server-Debug\"))\n")
print(f"Template file created, size: {os.path.getsize(template_path)} bytes")
# Load the template with skip directly
print("Loading template with skip.Schematic...")
try:
sch = Schematic(template_path)
print("Successfully loaded template")
# Save directly
output_path = os.path.join(test_dir, "direct_save.kicad_sch")
print(f"Saving with skip.Schematic.save() to: {output_path}")
sch.save(output_path)
if os.path.exists(output_path):
print(f"Direct save successful, file size: {os.path.getsize(output_path)} bytes")
else:
print("Direct save failed, no file created")
except Exception as e:
print(f"Error using skip directly: {e}")
traceback.print_exc()
print("\n--- Now testing SchematicManager ---\n")
# Import our SchematicManager
print("Importing SchematicManager...")
from python.commands.schematic import SchematicManager
print("Successfully imported SchematicManager")
# Create a new schematic
print("\nCreating new schematic with SchematicManager...")
schematic_name = "TestDebugManager"
metadata = {
"description": "Debug test schematic",
"author": "Debug script"
}
try:
sch = SchematicManager.create_schematic(schematic_name, metadata)
print("Successfully created schematic object")
# Print schematic properties
print("Schematic properties:")
print(f" Version: {sch.version}")
print(f" Generator: {sch.generator}")
# Save the schematic
schematic_path = os.path.join(test_dir, f"{schematic_name}.kicad_sch")
print(f"\nSaving schematic to: {schematic_path}")
try:
success = SchematicManager.save_schematic(sch, schematic_path)
if success:
print(f"Successfully saved schematic to: {schematic_path}")
print(f"File size: {os.path.getsize(schematic_path)} bytes")
else:
print("SchematicManager.save_schematic returned False")
except Exception as e:
print(f"Error in save_schematic: {e}")
traceback.print_exc()
except Exception as e:
print(f"Error in create_schematic: {e}")
traceback.print_exc()
except ImportError as e:
print(f"ERROR: Failed to import required modules: {e}")
traceback.print_exc()
except Exception as e:
print(f"ERROR: An unexpected error occurred: {e}")
traceback.print_exc()
print("\n=== Debug test completed ===")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,82 @@
#!/usr/bin/env python3
"""
Test script for the schematic manager implementation using KiCAD python
"""
import sys
import os
import traceback
# Add the parent directory to the module search path
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
def main():
"""Test the SchematicManager functions"""
print("=== Testing SchematicManager functionality ===")
try:
# Set up test output directory
test_dir = os.path.join(os.path.dirname(__file__), 'schematic_test_output')
if not os.path.exists(test_dir):
os.makedirs(test_dir)
print("Test directory:", test_dir)
# Import our SchematicManager
print("Importing SchematicManager...")
from python.commands.schematic import SchematicManager
print("Successfully imported SchematicManager")
# Create a new schematic
print("\nCreating new schematic...")
schematic_name = "TestSchemManager"
metadata = {
"description": "Test schematic",
"author": "Test script"
}
sch = SchematicManager.create_schematic(schematic_name, metadata)
print("Successfully created schematic object")
# Save the schematic
schematic_path = os.path.join(test_dir, f"{schematic_name}.kicad_sch")
print(f"\nSaving schematic to: {schematic_path}")
success = SchematicManager.save_schematic(sch, schematic_path)
if success:
print(f"Successfully saved schematic to: {schematic_path}")
else:
print("Failed to save schematic")
return
# Load the schematic
print("\nLoading schematic from file...")
loaded_sch = SchematicManager.load_schematic(schematic_path)
if loaded_sch:
print("Successfully loaded schematic")
# Get metadata
print("\nGetting schematic metadata...")
metadata = SchematicManager.get_schematic_metadata(loaded_sch)
print(f"Metadata: {metadata}")
else:
print("Failed to load schematic")
# Verify the file exists
if os.path.exists(schematic_path):
print(f"\nSCHEMATIC TEST SUCCESSFUL: File created at: {schematic_path}")
print(f"File size: {os.path.getsize(schematic_path)} bytes")
else:
print(f"\nERROR: File not found at: {schematic_path}")
except ImportError as e:
print(f"ERROR: Failed to import required modules: {e}")
traceback.print_exc()
except Exception as e:
print(f"ERROR: An unexpected error occurred: {e}")
traceback.print_exc()
print("\n=== Test completed ===")
if __name__ == "__main__":
main()