Skip to content

Commit 2fb3e89

Browse files
authored
Merge pull request #31 from Josverl/add_custom
Allow add of custom boards Add VID:PID to JSON output and enhance documentation
2 parents d2c84ea + 8bffc09 commit 2fb3e89

62 files changed

Lines changed: 7376 additions & 1241 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,7 @@ PIP_DISABLE_PIP_VERSION_CHECK=1
1515

1616
# stop neggin during debug
1717
JUPYTER_PLATFORM_DIRS=1
18-
PYDEVD_DISABLE_FILE_VALIDATION=1
18+
PYDEVD_DISABLE_FILE_VALIDATION=1
19+
20+
21+
MPFLASH_FIRMWARE=./scratch

.github/copilot-instructions.md

Lines changed: 195 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,28 @@
1-
# writing code
2-
3-
- Python
4-
- Use type annotations in code
5-
- add comments , but not too much
6-
- add docstrings to modules and methods. Docstrings should be max 5-9 lines
7-
- Use f-strings for string formatting
8-
- Use snake_case for variable and function names
9-
- Use CamelCase for class names
1+
# GitHub Copilot Instructions for MPFlash
2+
3+
This document provides guidance for GitHub Copilot to maintain consistency with MPFlash's architecture and coding standards.
4+
5+
## Project Overview
6+
7+
MPFlash is a command-line tool and Python library for managing MicroPython firmware across multiple hardware platforms. The project follows a layered architecture with clear separation of concerns.
8+
9+
## AI Assistant rukes
10+
- When running in shell , always make sure the activate the virtual environment after starting the shell
11+
- when possible use MCP servers
12+
13+
## Code Style and Standards
14+
15+
### Python Conventions
16+
- Use Python type annotations throughout the code
17+
- Follow snake_case for functions and variables
18+
- Follow CamelCase for class names
1019
- Use 4 spaces for indentation
1120
- Use double quotes for strings
21+
- Prefer f-strings for string formatting
22+
- Maximum line length: 88 characters (Black formatter standard)
23+
- Add comments, but not too much
24+
- Add docstrings to modules and methods (5-9 lines maximum)
25+
- Use double quotes for strings
1226

1327
# Speed and performance
1428

@@ -24,12 +38,181 @@
2438
-
2539

2640
# Writing tests
27-
41+
- when asked to create an MVP - keep the number of tests to a minimum
2842
- Use pytest for testing
2943
- Use pytest fixtures for setup and teardown
3044
- Use assert statements for testing
31-
- all tests shouod be located in a tests/ directory
45+
- all tests shouod be located in or under the `tests` directory
3246
- Use descriptive names for test functions
3347
- Use pytest.mark.parametrize for parameterized tests
3448
- Use pytest.raises for testing exceptions
35-
- for database testing make use of the test database int tests/data
49+
- for database related tests testsL
50+
- make use of the test database int tests/data
51+
- add fixtures for database setup and teardown
52+
### Documentation
53+
- Do not include type hints in docstrings
54+
- Keep comments minimal but descriptive
55+
56+
### Example Function Style
57+
```python
58+
def flash_firmware(
59+
port: str,
60+
firmware_path: Path,
61+
timeout: float = 30.0
62+
) -> bool:
63+
"""Flash MicroPython firmware to a connected board.
64+
65+
Args:
66+
port: Serial port identifier (e.g., 'COM3' or '/dev/ttyUSB0')
67+
firmware_path: Path to the firmware file
68+
timeout: Maximum time to wait for flashing (seconds)
69+
70+
Returns:
71+
True if flashing succeeded, False otherwise
72+
73+
Raises:
74+
FlashError: If flashing operation fails
75+
"""
76+
# Implementation
77+
```
78+
79+
## Project Structure Patterns
80+
81+
### CLI Commands
82+
- Place in `mpflash/cli_*.py`
83+
- Use Click decorators
84+
- Include help text and type annotations
85+
- Handle errors gracefully
86+
87+
### Core Components
88+
- Follow interface-based design
89+
- Use abstract base classes for common patterns
90+
- Implement strategy pattern for varying behaviors
91+
92+
### Database Operations
93+
- Use SQLAlchemy ORM
94+
- Follow repository pattern
95+
- Include proper error handling
96+
- Use migrations for schema changes
97+
98+
## Common Patterns
99+
100+
### Hardware Abstraction
101+
```python
102+
class FlashBase(ABC):
103+
"""Base class for flash implementations."""
104+
105+
@abstractmethod
106+
def flash_firmware(self) -> bool:
107+
"""Flash firmware to device."""
108+
pass
109+
```
110+
111+
### Error Handling
112+
```python
113+
class MPFlashError(Exception):
114+
"""Base exception for MPFlash operations."""
115+
pass
116+
117+
def safe_operation(func: Callable) -> Callable:
118+
"""Decorator for safe operations with proper error handling."""
119+
@wraps(func)
120+
def wrapper(*args, **kwargs):
121+
try:
122+
return func(*args, **kwargs)
123+
except MPFlashError as e:
124+
log.error(f"Operation failed: {e}")
125+
return None
126+
return wrapper
127+
```
128+
129+
### Configuration Management
130+
```python
131+
@dataclass
132+
class Config:
133+
"""Configuration dataclass with type hints."""
134+
firmware_dir: Path
135+
log_level: str = "INFO"
136+
timeout: float = 30.0
137+
```
138+
139+
## Testing Conventions
140+
141+
### Test Structure
142+
- Place tests in `tests/` directory
143+
- Match test file names with implementation files
144+
- Use pytest fixtures for setup
145+
- Include unit, integration, and end-to-end tests
146+
147+
### Example Test Pattern
148+
```python
149+
def test_flash_firmware(mock_board, temp_firmware):
150+
"""Test firmware flashing with mocked board."""
151+
result = flash_firmware(
152+
port=mock_board.port,
153+
firmware_path=temp_firmware
154+
)
155+
assert result is True
156+
```
157+
158+
## Performance Considerations
159+
160+
### Lazy Loading
161+
```python
162+
class LazyLoader:
163+
"""Lazy loading pattern for expensive imports."""
164+
def __init__(self):
165+
self._module = None
166+
167+
@property
168+
def module(self):
169+
if self._module is None:
170+
import expensive_module
171+
self._module = expensive_module
172+
return self._module
173+
```
174+
175+
### Caching
176+
```python
177+
@lru_cache(maxsize=100)
178+
def get_board_info(board_id: str) -> dict:
179+
"""Cached board information retrieval."""
180+
# Implementation
181+
```
182+
183+
## Security Patterns
184+
185+
### Input Validation
186+
```python
187+
def validate_input(value: str, pattern: str) -> bool:
188+
"""Validate input against security pattern."""
189+
import re
190+
return bool(re.match(pattern, value))
191+
```
192+
193+
### Safe File Operations
194+
```python
195+
def safe_file_operation(path: Path) -> None:
196+
"""Safe file operation pattern."""
197+
if not path.suffix in {'.bin', '.uf2', '.hex'}:
198+
raise SecurityError("Invalid file type")
199+
# Implementation
200+
```
201+
202+
## Database Update Process
203+
204+
When working with the board database:
205+
- Use `gather_boards.py` for updating board definitions
206+
- Package updates in `micropython_boards.zip`
207+
- Follow the repository pattern for database operations
208+
- Maintain proper versioning and migrations
209+
210+
## Bootloader Operations
211+
212+
When implementing bootloader-related code:
213+
- Use the BootloaderManager class
214+
- Implement proper error handling
215+
- Follow the strategy pattern for different bootloader types
216+
- Include timeout mechanisms
217+
218+
Remember to maintain consistency with these patterns when suggesting code completions and implementations.

.vscode/launch.json

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,20 @@
1313
"cwd": "${workspaceFolder}",
1414
"args": [
1515
"-VV",
16+
// "add",
17+
// "--path",
18+
// "\\\\wsl.localhost\\Ubuntu\\home\\jos\\micropython\\ports\\samd\\build-SEEED_WIO_TERMINAL\\firmware.uf2",
19+
// "--force",
1620
"flash",
1721
"--board",
18-
"ESP32_GENERIC-SPIRAM",
19-
"--serial",
20-
"COM15",
21-
// "--version",
22-
// "preview",
22+
"RPI_PICO2_W@settrace_tests",
23+
"--custom",
24+
"--version",
25+
"preview",
26+
// "--variant",
27+
// "--variant",
28+
// "SPIRAM",
29+
// "--erase",
2330
// "--variant",
2431
// "DP",
2532
// "FLASH_16M",

.vscode/settings.json

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,25 @@
2323
"terminal.integrated.persistentSessionReviveProcess": "never",
2424
"workbench.colorCustomizations": {
2525
"activityBar.activeBorder": "#0bb45d",
26-
"activityBar.activeBackground": "#e30d7a",
27-
"activityBar.background": "#e30d7a",
26+
"activityBar.activeBackground": "#e30da5",
27+
"activityBar.background": "#e30da5",
2828
"activityBar.foreground": "#e7e7e7",
2929
"activityBar.inactiveForeground": "#e7e7e799",
30-
"activityBarBadge.background": "#71d30c",
30+
"activityBarBadge.background": "#99d30c",
3131
"activityBarBadge.foreground": "#15202b",
3232
"commandCenter.border": "#e7e7e799",
33-
"editorGroup.border": "#e30d7a",
34-
"panel.border": "#e30d7a",
35-
"sash.hoverBorder": "#e30d7a",
36-
"statusBar.background": "#b30a60",
33+
"editorGroup.border": "#e30da5",
34+
"panel.border": "#e30da5",
35+
"sash.hoverBorder": "#e30da5",
36+
"statusBar.background": "#b30a82",
3737
"statusBar.foreground": "#e7e7e7",
38-
"statusBarItem.hoverBackground": "#e30d7a",
39-
"statusBarItem.remoteBackground": "#b30a60",
38+
"statusBarItem.hoverBackground": "#e30da5",
39+
"statusBarItem.remoteBackground": "#b30a82",
4040
"statusBarItem.remoteForeground": "#e7e7e7",
41-
"tab.activeBorder": "#e30d7a",
42-
"titleBar.activeBackground": "#b30a60",
41+
"tab.activeBorder": "#e30da5",
42+
"titleBar.activeBackground": "#b30a82",
4343
"titleBar.activeForeground": "#e7e7e7",
44-
"titleBar.inactiveBackground": "#b30a6099",
44+
"titleBar.inactiveBackground": "#b30a8299",
4545
"titleBar.inactiveForeground": "#e7e7e799"
4646
},
4747
"python.terminal.activateEnvInCurrentTerminal": true,

0 commit comments

Comments
 (0)