🎉 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>
205 lines
4.5 KiB
Python
205 lines
4.5 KiB
Python
"""
|
|
Abstract base class for KiCAD API backends
|
|
|
|
Defines the interface that all KiCAD backends must implement.
|
|
"""
|
|
from abc import ABC, abstractmethod
|
|
from pathlib import Path
|
|
from typing import Optional, Dict, Any, List
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class KiCADBackend(ABC):
|
|
"""Abstract base class for KiCAD API backends"""
|
|
|
|
@abstractmethod
|
|
def connect(self) -> bool:
|
|
"""
|
|
Connect to KiCAD
|
|
|
|
Returns:
|
|
True if connection successful, False otherwise
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def disconnect(self) -> None:
|
|
"""Disconnect from KiCAD and clean up resources"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def is_connected(self) -> bool:
|
|
"""
|
|
Check if currently connected to KiCAD
|
|
|
|
Returns:
|
|
True if connected, False otherwise
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def get_version(self) -> str:
|
|
"""
|
|
Get KiCAD version
|
|
|
|
Returns:
|
|
Version string (e.g., "9.0.0")
|
|
"""
|
|
pass
|
|
|
|
# Project Operations
|
|
@abstractmethod
|
|
def create_project(self, path: Path, name: str) -> Dict[str, Any]:
|
|
"""
|
|
Create a new KiCAD project
|
|
|
|
Args:
|
|
path: Directory path for the project
|
|
name: Project name
|
|
|
|
Returns:
|
|
Dictionary with project info
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def open_project(self, path: Path) -> Dict[str, Any]:
|
|
"""
|
|
Open an existing KiCAD project
|
|
|
|
Args:
|
|
path: Path to .kicad_pro file
|
|
|
|
Returns:
|
|
Dictionary with project info
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def save_project(self, path: Optional[Path] = None) -> Dict[str, Any]:
|
|
"""
|
|
Save the current project
|
|
|
|
Args:
|
|
path: Optional new path to save to
|
|
|
|
Returns:
|
|
Dictionary with save status
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def close_project(self) -> None:
|
|
"""Close the current project"""
|
|
pass
|
|
|
|
# Board Operations
|
|
@abstractmethod
|
|
def get_board(self) -> 'BoardAPI':
|
|
"""
|
|
Get board API for current project
|
|
|
|
Returns:
|
|
BoardAPI instance
|
|
"""
|
|
pass
|
|
|
|
|
|
class BoardAPI(ABC):
|
|
"""Abstract interface for board operations"""
|
|
|
|
@abstractmethod
|
|
def set_size(self, width: float, height: float, unit: str = "mm") -> bool:
|
|
"""
|
|
Set board size
|
|
|
|
Args:
|
|
width: Board width
|
|
height: Board height
|
|
unit: Unit of measurement ("mm" or "in")
|
|
|
|
Returns:
|
|
True if successful
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def get_size(self) -> Dict[str, float]:
|
|
"""
|
|
Get current board size
|
|
|
|
Returns:
|
|
Dictionary with width, height, unit
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def add_layer(self, layer_name: str, layer_type: str) -> bool:
|
|
"""
|
|
Add a layer to the board
|
|
|
|
Args:
|
|
layer_name: Name of the layer
|
|
layer_type: Type ("copper", "technical", "user")
|
|
|
|
Returns:
|
|
True if successful
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def list_components(self) -> List[Dict[str, Any]]:
|
|
"""
|
|
List all components on the board
|
|
|
|
Returns:
|
|
List of component dictionaries
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def place_component(
|
|
self,
|
|
reference: str,
|
|
footprint: str,
|
|
x: float,
|
|
y: float,
|
|
rotation: float = 0,
|
|
layer: str = "F.Cu"
|
|
) -> bool:
|
|
"""
|
|
Place a component on the board
|
|
|
|
Args:
|
|
reference: Component reference (e.g., "R1")
|
|
footprint: Footprint library path
|
|
x: X position (mm)
|
|
y: Y position (mm)
|
|
rotation: Rotation angle (degrees)
|
|
layer: Layer name
|
|
|
|
Returns:
|
|
True if successful
|
|
"""
|
|
pass
|
|
|
|
# Add more abstract methods for routing, DRC, export, etc.
|
|
# These will be filled in during migration
|
|
|
|
|
|
class BackendError(Exception):
|
|
"""Base exception for backend errors"""
|
|
pass
|
|
|
|
|
|
class ConnectionError(BackendError):
|
|
"""Raised when connection to KiCAD fails"""
|
|
pass
|
|
|
|
|
|
class APINotAvailableError(BackendError):
|
|
"""Raised when required API is not available"""
|
|
pass
|