495 lines
10 KiB
Markdown
495 lines
10 KiB
Markdown
# Contributing to WebDrop Bridge
|
|
|
|
Thank you for your interest in contributing! This document provides guidelines and instructions for contributing to the WebDrop Bridge project.
|
|
|
|
## Code of Conduct
|
|
|
|
Please be respectful and constructive in all interactions. We're building a welcoming community for developers of all experience levels.
|
|
|
|
## Getting Started
|
|
|
|
### Prerequisites
|
|
- Python 3.10+
|
|
- Git
|
|
- Familiarity with Qt/PySide6 or willingness to learn
|
|
|
|
### Setup Development Environment
|
|
|
|
```bash
|
|
# Fork and clone the repository
|
|
git clone https://github.com/yourusername/webdrop-bridge.git
|
|
cd webdrop-bridge
|
|
|
|
# Create virtual environment
|
|
python -m venv venv
|
|
source venv/bin/activate # macOS/Linux
|
|
# venv\Scripts\activate # Windows
|
|
|
|
# Install development dependencies
|
|
pip install -r requirements-dev.txt
|
|
|
|
# Install pre-commit hooks (optional)
|
|
pip install pre-commit
|
|
pre-commit install
|
|
```
|
|
|
|
## Development Workflow
|
|
|
|
### 1. Create a Feature Branch
|
|
|
|
```bash
|
|
git checkout -b feature/your-feature-name
|
|
```
|
|
|
|
Use descriptive names:
|
|
- `feature/drag-performance-optimization`
|
|
- `bugfix/path-validation-windows`
|
|
- `docs/add-architecture-guide`
|
|
|
|
### 2. Write Tests First (TDD)
|
|
|
|
```bash
|
|
# Create test file
|
|
touch tests/unit/test_my_feature.py
|
|
|
|
# Write failing tests
|
|
pytest tests/unit/test_my_feature.py
|
|
|
|
# Implement feature
|
|
# Re-run tests until passing
|
|
```
|
|
|
|
### 3. Implement Your Feature
|
|
|
|
```bash
|
|
# Follow the project structure
|
|
src/webdrop_bridge/
|
|
├── core/ # Core logic
|
|
├── ui/ # UI components
|
|
└── utils/ # Utilities
|
|
```
|
|
|
|
### 4. Code Quality Checks
|
|
|
|
```bash
|
|
# Format code
|
|
tox -e format
|
|
|
|
# Run linting
|
|
tox -e lint
|
|
|
|
# Type checking
|
|
tox -e type
|
|
|
|
# Full test suite
|
|
pytest --cov
|
|
|
|
# All checks
|
|
tox
|
|
```
|
|
|
|
### 5. Write Documentation
|
|
|
|
- Add docstrings to all functions/classes
|
|
- Update README.md if adding features
|
|
- Add examples for new APIs
|
|
|
|
### 6. Commit and Push
|
|
|
|
```bash
|
|
# Commit with meaningful message
|
|
git commit -m "feat: add feature description
|
|
|
|
- Detailed explanation of changes
|
|
- Bullet points for key changes
|
|
- References to related issues"
|
|
|
|
# Push to your fork
|
|
git push origin feature/your-feature-name
|
|
```
|
|
|
|
### 7. Submit Pull Request
|
|
|
|
- Use clear, descriptive title
|
|
- Reference related issues (#123)
|
|
- Describe changes and testing approach
|
|
- Include screenshots/videos if UI-related
|
|
|
|
## Code Style
|
|
|
|
### Python Style Guide
|
|
|
|
Follow PEP 8, enforced by Black and Ruff:
|
|
|
|
```python
|
|
# Good
|
|
def validate_path(path: Path, allowed_roots: List[Path]) -> bool:
|
|
"""Validate path against allowed roots."""
|
|
resolved = path.resolve()
|
|
return any(is_relative_to(resolved, root) for root in allowed_roots)
|
|
|
|
|
|
# Bad
|
|
def validate_path(path,allowed_roots):
|
|
resolved=path.resolve()
|
|
return any(is_relative_to(resolved,root)for root in allowed_roots)
|
|
```
|
|
|
|
### Type Hints
|
|
|
|
Always use type hints:
|
|
|
|
```python
|
|
from typing import Optional, List
|
|
from pathlib import Path
|
|
|
|
def process_files(files: List[Path], validate: bool = True) -> Optional[int]:
|
|
"""Process a list of files."""
|
|
pass
|
|
```
|
|
|
|
### Docstrings
|
|
|
|
Use Google-style docstrings:
|
|
|
|
```python
|
|
def validate_path(path: Path, allowed_roots: List[Path]) -> bool:
|
|
"""Validate that path is within allowed roots.
|
|
|
|
Args:
|
|
path: File path to validate
|
|
allowed_roots: List of allowed root directories
|
|
|
|
Returns:
|
|
True if path is valid, False otherwise
|
|
|
|
Raises:
|
|
ValueError: If path cannot be resolved
|
|
"""
|
|
```
|
|
|
|
## Testing Guidelines
|
|
|
|
### Unit Tests
|
|
|
|
Test individual functions/classes in isolation:
|
|
|
|
```python
|
|
# tests/unit/test_validator.py
|
|
import pytest
|
|
from webdrop_bridge.core.validator import PathValidator
|
|
from pathlib import Path
|
|
|
|
@pytest.fixture
|
|
def validator():
|
|
allowed_roots = [Path("C:/Users/Public")]
|
|
return PathValidator(allowed_roots)
|
|
|
|
def test_valid_path(validator):
|
|
"""Test that valid paths are accepted."""
|
|
path = Path("C:/Users/Public/Documents/file.txt")
|
|
assert validator.is_allowed(path)
|
|
|
|
def test_invalid_path(validator):
|
|
"""Test that invalid paths are rejected."""
|
|
path = Path("C:/Windows/System32/file.txt")
|
|
assert not validator.is_allowed(path)
|
|
```
|
|
|
|
### Integration Tests
|
|
|
|
Test components working together:
|
|
|
|
```python
|
|
# tests/integration/test_drag_workflow.py
|
|
def test_complete_drag_workflow(temp_test_dir):
|
|
"""Test complete drag-and-drop workflow."""
|
|
# Setup
|
|
test_file = temp_test_dir / "test.txt"
|
|
test_file.write_text("content")
|
|
|
|
# Execute
|
|
validator = PathValidator([temp_test_dir])
|
|
result = validator.is_valid_file(test_file)
|
|
|
|
# Verify
|
|
assert result is True
|
|
```
|
|
|
|
### Test Coverage
|
|
|
|
- Aim for 80%+ code coverage
|
|
- All public APIs must have tests
|
|
- Test both happy path and error cases
|
|
|
|
```bash
|
|
# Check coverage
|
|
pytest --cov=src/webdrop_bridge --cov-report=html
|
|
|
|
# View detailed report
|
|
open htmlcov/index.html # macOS
|
|
start htmlcov\index.html # Windows
|
|
```
|
|
|
|
## Platform-Specific Development
|
|
|
|
### Windows
|
|
|
|
```bash
|
|
# For Windows-specific tests
|
|
pytest -m windows
|
|
|
|
# Build Windows installer
|
|
python build/scripts/build_windows.py
|
|
```
|
|
|
|
### macOS
|
|
|
|
```bash
|
|
# For macOS-specific tests
|
|
pytest -m macos
|
|
|
|
# Build macOS DMG
|
|
bash build/scripts/build_macos.sh
|
|
```
|
|
|
|
## Common Issues
|
|
|
|
### Import Errors
|
|
|
|
Ensure project is in PYTHONPATH:
|
|
|
|
```bash
|
|
export PYTHONPATH="${PYTHONPATH}:$(pwd)/src" # macOS/Linux
|
|
set PYTHONPATH=%PYTHONPATH%;%cd%\src # Windows
|
|
```
|
|
|
|
Or install in development mode:
|
|
|
|
```bash
|
|
pip install -e .
|
|
```
|
|
|
|
### PySide6 Installation Issues
|
|
|
|
```bash
|
|
# Force reinstall
|
|
pip install --force-reinstall --no-cache-dir PySide6
|
|
|
|
# On macOS with Apple Silicon
|
|
pip install PySide6 --target $PYTHON_ENV
|
|
```
|
|
|
|
### Test Failures in CI but Not Locally
|
|
|
|
- Check Python version: `python --version`
|
|
- Verify all dependencies: `pip list`
|
|
- Clear cache: `rm -rf .pytest_cache build/`
|
|
- Try clean venv: `rm -rf venv && python -m venv venv`
|
|
|
|
## Documentation
|
|
|
|
### API Documentation
|
|
|
|
Docstrings are automatically converted to HTML:
|
|
|
|
```bash
|
|
tox -e docs
|
|
|
|
# View documentation
|
|
open docs/_build/html/index.html # macOS
|
|
start docs\_build\html\index.html # Windows
|
|
```
|
|
|
|
### Writing Documentation
|
|
|
|
- Use Markdown for guides
|
|
- Include code examples
|
|
- Add screenshots for UI features
|
|
- Keep language clear and concise
|
|
|
|
## Writing Integration Tests
|
|
|
|
Integration tests should cover workflows across multiple components. See [tests/integration/test_update_flow.py](tests/integration/test_update_flow.py) for an example covering the update system.
|
|
|
|
## Release Process
|
|
|
|
### Versioning & Release Process
|
|
|
|
### Version Management
|
|
|
|
WebDrop Bridge uses **semantic versioning** (MAJOR.MINOR.PATCH). The version is centralized in one location:
|
|
|
|
**Single Source of Truth**: `src/webdrop_bridge/__init__.py`
|
|
|
|
```python
|
|
__version__ = "1.0.0"
|
|
```
|
|
|
|
**Shared Version Utility**: `build/scripts/version_utils.py`
|
|
|
|
All build scripts and version management tools use a shared utility to read the version from `__init__.py`, ensuring consistency across:
|
|
- `pyproject.toml` - Reads dynamically at build time
|
|
- `config.py` - Reads dynamically at startup
|
|
- `.env.example` - Updated by sync script (optional)
|
|
- `CHANGELOG.md` - Updated by sync script
|
|
|
|
### Releasing a New Version
|
|
|
|
#### Step 1: Update the Version (Only Place to Edit)
|
|
|
|
Edit `src/webdrop_bridge/__init__.py` and change `__version__`:
|
|
|
|
```python
|
|
__version__ = "1.2.0" # Change this to your new version
|
|
```
|
|
|
|
#### Step 2: Sync Version to Changelog
|
|
|
|
Run the sync script to update the changelog:
|
|
|
|
```bash
|
|
python scripts/sync_version.py
|
|
```
|
|
|
|
Or let the build script do it automatically:
|
|
|
|
```bash
|
|
# Windows
|
|
python build/scripts/build_windows.py
|
|
|
|
# macOS
|
|
bash build/scripts/build_macos.sh
|
|
```
|
|
|
|
Both the build script and sync script use the shared `build/scripts/version_utils.py` utility.
|
|
|
|
#### Step 3: Update CHANGELOG.md Manually (Content Only)
|
|
|
|
The sync script adds the version header with the date. Now add your changes under each section:
|
|
|
|
```markdown
|
|
## [1.2.0] - 2026-01-15
|
|
|
|
### Added
|
|
- New feature description
|
|
|
|
### Changed
|
|
- Breaking change description
|
|
|
|
### Fixed
|
|
- Bug fix description
|
|
```
|
|
|
|
#### Step 4: Commit and Tag
|
|
|
|
```bash
|
|
git add -A
|
|
git commit -m "chore: release v1.2.0
|
|
|
|
- Feature 1 details
|
|
- Feature 2 details"
|
|
|
|
git tag -a v1.2.0 -m "Release version 1.2.0"
|
|
git push origin main --tags
|
|
```
|
|
|
|
### Manual Version Sync (If Needed)
|
|
|
|
If you need to sync versions without building:
|
|
|
|
```bash
|
|
python scripts/sync_version.py
|
|
```
|
|
|
|
To set a specific version:
|
|
|
|
```bash
|
|
python scripts/sync_version.py --version 1.2.0
|
|
```
|
|
|
|
### Querying Version in Code
|
|
|
|
Always import from the package:
|
|
|
|
```python
|
|
from webdrop_bridge import __version__
|
|
|
|
print(__version__) # "1.2.0"
|
|
```
|
|
|
|
### Environment Override (Development Only)
|
|
|
|
If needed for testing, you can override with `.env`:
|
|
|
|
```bash
|
|
# .env (development only)
|
|
APP_VERSION=1.2.0-dev
|
|
```
|
|
|
|
Config loads it via lazy import (to avoid circular dependencies):
|
|
```python
|
|
if not os.getenv("APP_VERSION"):
|
|
from webdrop_bridge import __version__
|
|
app_version = __version__
|
|
else:
|
|
app_version = os.getenv("APP_VERSION")
|
|
```
|
|
|
|
### Shared Version Utility
|
|
|
|
Both build scripts and the sync script use `build/scripts/version_utils.py` to read the version:
|
|
|
|
```python
|
|
from version_utils import get_current_version, get_project_root
|
|
|
|
version = get_current_version() # Reads from __init__.py
|
|
root = get_project_root() # Gets project root
|
|
```
|
|
|
|
This ensures:
|
|
- **No duplication** - Single implementation used everywhere
|
|
- **Consistency** - All tools read from the same source
|
|
- **Maintainability** - Update once, affects all tools
|
|
|
|
If you create new build scripts or tools, import from this utility instead of implementing version reading again.
|
|
|
|
---
|
|
|
|
## Summary of Version Management
|
|
|
|
| Task | How | Location |
|
|
|------|-----|----------|
|
|
| Define version | Edit `__version__` | `src/webdrop_bridge/__init__.py` |
|
|
| Read version in app | Lazy import `__init__.py` | `src/webdrop_bridge/config.py` |
|
|
| Read version in builds | Use shared utility | `build/scripts/version_utils.py` |
|
|
| Update changelog | Run sync script | `scripts/sync_version.py` |
|
|
| Release new version | Edit `__init__.py`, run sync, commit/tag | See "Releasing a New Version" above |
|
|
|
|
**Golden Rule**: Only edit `src/webdrop_bridge/__init__.py`. Everything else is automated or handled by scripts.
|
|
|
|
## Getting Help
|
|
|
|
- **Issues**: Report bugs or request features
|
|
- **Discussions**: Ask questions or discuss ideas
|
|
- **Documentation**: Check docs/ folder
|
|
- **Code Examples**: Look at tests/ folder
|
|
|
|
## Review Process
|
|
|
|
All pull requests require:
|
|
|
|
- ✅ Tests pass (100% on target platforms)
|
|
- ✅ Code review approved
|
|
- ✅ No lint/type warnings
|
|
- ✅ Documentation updated
|
|
- ✅ Coverage maintained or improved
|
|
|
|
## Recognition
|
|
|
|
Contributors are recognized in:
|
|
- CONTRIBUTORS.md
|
|
- GitHub releases
|
|
- Project website
|
|
|
|
Thank you for contributing to WebDrop Bridge! 🎉
|