chore: normalize schematic.py and apply black to create_schematic signature
Bundles two changes for python/commands/schematic.py:
1. CRLF → LF line-ending normalization (matches the bulk renormalize
from the previous commit — was held back here because black would
also need to re-reformat it).
2. Black reflow of create_schematic()'s parameter list, which exceeded
the line length. Pre-existing drift, no logic change.
`git show --ignore-all-space HEAD` shows just the 2-line signature diff.
This commit is contained in:
@@ -1,132 +1,134 @@
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import uuid
|
||||
from typing import Any, Optional
|
||||
|
||||
from skip import Schematic
|
||||
|
||||
logger = logging.getLogger("kicad_interface")
|
||||
|
||||
|
||||
class SchematicManager:
|
||||
"""Core schematic operations using kicad-skip"""
|
||||
|
||||
@staticmethod
|
||||
def create_schematic(name: str, metadata: Optional[Any] = None, *, path: Optional[str] = None) -> Any:
|
||||
"""Create a new empty schematic from template"""
|
||||
try:
|
||||
# Determine template path (use template_with_symbols for component cloning support)
|
||||
template_path = os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"..",
|
||||
"templates",
|
||||
"template_with_symbols.kicad_sch",
|
||||
)
|
||||
|
||||
# Determine output path
|
||||
base_name = name if name.endswith(".kicad_sch") else f"{name}.kicad_sch"
|
||||
output_path = os.path.join(path, base_name) if path else base_name
|
||||
|
||||
if os.path.exists(template_path):
|
||||
# Copy template to target location
|
||||
shutil.copy(template_path, output_path)
|
||||
|
||||
# Regenerate UUID to ensure uniqueness for each created schematic
|
||||
import re
|
||||
|
||||
with open(output_path, "r", encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
new_uuid = str(uuid.uuid4())
|
||||
content = re.sub(
|
||||
r"\(uuid [0-9a-fA-F-]+\)",
|
||||
f"(uuid {new_uuid})",
|
||||
content,
|
||||
count=1, # Only replace first (schematic) UUID
|
||||
)
|
||||
with open(output_path, "w", encoding="utf-8", newline="\n") as f:
|
||||
f.write(content)
|
||||
|
||||
logger.info(f"Created schematic from template: {output_path}")
|
||||
else:
|
||||
# Fallback: create minimal schematic
|
||||
logger.warning(f"Template not found at {template_path}, creating minimal schematic")
|
||||
# Generate unique UUID for this schematic
|
||||
schematic_uuid = str(uuid.uuid4())
|
||||
# Write with explicit UTF-8 encoding and Unix line endings for cross-platform compatibility
|
||||
with open(output_path, "w", encoding="utf-8", newline="\n") as f:
|
||||
f.write('(kicad_sch (version 20250114) (generator "KiCAD-MCP-Server")\n\n')
|
||||
f.write(f" (uuid {schematic_uuid})\n\n")
|
||||
f.write(' (paper "A4")\n\n')
|
||||
f.write(" (lib_symbols\n )\n\n")
|
||||
f.write(' (sheet_instances\n (path "/" (page "1"))\n )\n')
|
||||
f.write(")\n")
|
||||
|
||||
# Load the schematic
|
||||
sch = Schematic(output_path)
|
||||
logger.info(f"Loaded new schematic: {output_path}")
|
||||
return sch
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error creating schematic: {e}")
|
||||
raise
|
||||
|
||||
@staticmethod
|
||||
def load_schematic(file_path: str) -> Optional[Any]:
|
||||
"""Load an existing schematic"""
|
||||
if not os.path.exists(file_path):
|
||||
logger.error(f"Schematic file not found at {file_path}")
|
||||
return None
|
||||
try:
|
||||
sch = Schematic(file_path)
|
||||
logger.info(f"Loaded schematic from: {file_path}")
|
||||
return sch
|
||||
except Exception as e:
|
||||
logger.error(f"Error loading schematic from {file_path}: {e}")
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def save_schematic(schematic: Any, file_path: str) -> bool:
|
||||
"""Save a schematic to file"""
|
||||
try:
|
||||
# kicad-skip uses write method, not save
|
||||
schematic.write(file_path)
|
||||
logger.info(f"Saved schematic to: {file_path}")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Error saving schematic to {file_path}: {e}")
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def get_schematic_metadata(schematic: Any) -> dict[str, Any]:
|
||||
"""Extract metadata from schematic"""
|
||||
# kicad-skip doesn't expose a direct metadata object on Schematic.
|
||||
# We can return basic info like version and generator.
|
||||
metadata = {
|
||||
"version": schematic.version,
|
||||
"generator": schematic.generator,
|
||||
# Add other relevant properties if needed
|
||||
}
|
||||
logger.debug("Extracted schematic metadata")
|
||||
return metadata
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Example Usage (for testing)
|
||||
# Create a new schematic
|
||||
new_sch = SchematicManager.create_schematic("MyTestSchematic")
|
||||
|
||||
# Save the schematic
|
||||
test_file = "test_schematic.kicad_sch"
|
||||
SchematicManager.save_schematic(new_sch, test_file)
|
||||
|
||||
# Load the schematic
|
||||
loaded_sch = SchematicManager.load_schematic(test_file)
|
||||
if loaded_sch:
|
||||
metadata = SchematicManager.get_schematic_metadata(loaded_sch)
|
||||
print(f"Loaded schematic metadata: {metadata}")
|
||||
|
||||
# Clean up test file
|
||||
if os.path.exists(test_file):
|
||||
os.remove(test_file)
|
||||
print(f"Cleaned up {test_file}")
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import uuid
|
||||
from typing import Any, Optional
|
||||
|
||||
from skip import Schematic
|
||||
|
||||
logger = logging.getLogger("kicad_interface")
|
||||
|
||||
|
||||
class SchematicManager:
|
||||
"""Core schematic operations using kicad-skip"""
|
||||
|
||||
@staticmethod
|
||||
def create_schematic(
|
||||
name: str, metadata: Optional[Any] = None, *, path: Optional[str] = None
|
||||
) -> Any:
|
||||
"""Create a new empty schematic from template"""
|
||||
try:
|
||||
# Determine template path (use template_with_symbols for component cloning support)
|
||||
template_path = os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"..",
|
||||
"templates",
|
||||
"template_with_symbols.kicad_sch",
|
||||
)
|
||||
|
||||
# Determine output path
|
||||
base_name = name if name.endswith(".kicad_sch") else f"{name}.kicad_sch"
|
||||
output_path = os.path.join(path, base_name) if path else base_name
|
||||
|
||||
if os.path.exists(template_path):
|
||||
# Copy template to target location
|
||||
shutil.copy(template_path, output_path)
|
||||
|
||||
# Regenerate UUID to ensure uniqueness for each created schematic
|
||||
import re
|
||||
|
||||
with open(output_path, "r", encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
new_uuid = str(uuid.uuid4())
|
||||
content = re.sub(
|
||||
r"\(uuid [0-9a-fA-F-]+\)",
|
||||
f"(uuid {new_uuid})",
|
||||
content,
|
||||
count=1, # Only replace first (schematic) UUID
|
||||
)
|
||||
with open(output_path, "w", encoding="utf-8", newline="\n") as f:
|
||||
f.write(content)
|
||||
|
||||
logger.info(f"Created schematic from template: {output_path}")
|
||||
else:
|
||||
# Fallback: create minimal schematic
|
||||
logger.warning(f"Template not found at {template_path}, creating minimal schematic")
|
||||
# Generate unique UUID for this schematic
|
||||
schematic_uuid = str(uuid.uuid4())
|
||||
# Write with explicit UTF-8 encoding and Unix line endings for cross-platform compatibility
|
||||
with open(output_path, "w", encoding="utf-8", newline="\n") as f:
|
||||
f.write('(kicad_sch (version 20250114) (generator "KiCAD-MCP-Server")\n\n')
|
||||
f.write(f" (uuid {schematic_uuid})\n\n")
|
||||
f.write(' (paper "A4")\n\n')
|
||||
f.write(" (lib_symbols\n )\n\n")
|
||||
f.write(' (sheet_instances\n (path "/" (page "1"))\n )\n')
|
||||
f.write(")\n")
|
||||
|
||||
# Load the schematic
|
||||
sch = Schematic(output_path)
|
||||
logger.info(f"Loaded new schematic: {output_path}")
|
||||
return sch
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error creating schematic: {e}")
|
||||
raise
|
||||
|
||||
@staticmethod
|
||||
def load_schematic(file_path: str) -> Optional[Any]:
|
||||
"""Load an existing schematic"""
|
||||
if not os.path.exists(file_path):
|
||||
logger.error(f"Schematic file not found at {file_path}")
|
||||
return None
|
||||
try:
|
||||
sch = Schematic(file_path)
|
||||
logger.info(f"Loaded schematic from: {file_path}")
|
||||
return sch
|
||||
except Exception as e:
|
||||
logger.error(f"Error loading schematic from {file_path}: {e}")
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def save_schematic(schematic: Any, file_path: str) -> bool:
|
||||
"""Save a schematic to file"""
|
||||
try:
|
||||
# kicad-skip uses write method, not save
|
||||
schematic.write(file_path)
|
||||
logger.info(f"Saved schematic to: {file_path}")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Error saving schematic to {file_path}: {e}")
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def get_schematic_metadata(schematic: Any) -> dict[str, Any]:
|
||||
"""Extract metadata from schematic"""
|
||||
# kicad-skip doesn't expose a direct metadata object on Schematic.
|
||||
# We can return basic info like version and generator.
|
||||
metadata = {
|
||||
"version": schematic.version,
|
||||
"generator": schematic.generator,
|
||||
# Add other relevant properties if needed
|
||||
}
|
||||
logger.debug("Extracted schematic metadata")
|
||||
return metadata
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Example Usage (for testing)
|
||||
# Create a new schematic
|
||||
new_sch = SchematicManager.create_schematic("MyTestSchematic")
|
||||
|
||||
# Save the schematic
|
||||
test_file = "test_schematic.kicad_sch"
|
||||
SchematicManager.save_schematic(new_sch, test_file)
|
||||
|
||||
# Load the schematic
|
||||
loaded_sch = SchematicManager.load_schematic(test_file)
|
||||
if loaded_sch:
|
||||
metadata = SchematicManager.get_schematic_metadata(loaded_sch)
|
||||
print(f"Loaded schematic metadata: {metadata}")
|
||||
|
||||
# Clean up test file
|
||||
if os.path.exists(test_file):
|
||||
os.remove(test_file)
|
||||
print(f"Cleaned up {test_file}")
|
||||
|
||||
Reference in New Issue
Block a user