Add Development
475
Development.md
Normal file
475
Development.md
Normal file
@@ -0,0 +1,475 @@
|
||||
# Development
|
||||
|
||||
### Development Environment Setup
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
- **Python**: 3.9, 3.10, or 3.11
|
||||
- **Git**: For version control
|
||||
- **Docker**: (Optional) For containerized testing
|
||||
- **IDE**: VS Code, PyCharm, or similar with Python support
|
||||
|
||||
#### Initial Setup
|
||||
|
||||
1. **Clone the repository:**
|
||||
```bash
|
||||
git clone https://git.serendipity.systems/k.eaven/pterodactyl-discord-bot.git
|
||||
cd pterodactyl-discord-bot
|
||||
```
|
||||
|
||||
2. **Create virtual environment:**
|
||||
```bash
|
||||
python -m venv venv
|
||||
source venv/bin/activate # On Windows: venv\Scripts\activate
|
||||
```
|
||||
|
||||
3. **Install dependencies:**
|
||||
```bash
|
||||
# Production dependencies
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Development and testing dependencies
|
||||
pip install -r requirements-test.txt
|
||||
```
|
||||
|
||||
4. **Set up pre-commit hooks (optional but recommended):**
|
||||
```bash
|
||||
pip install pre-commit
|
||||
pre-commit install
|
||||
```
|
||||
|
||||
5. **Create development configuration:**
|
||||
```bash
|
||||
cp config.ini.example config.ini
|
||||
# Edit config.ini with your development credentials
|
||||
```
|
||||
|
||||
### Project Structure
|
||||
|
||||
```
|
||||
pterodactyl-discord-bot/
|
||||
├── .gitea/
|
||||
│ └── workflows/
|
||||
│ ├── test.yml # Test-only CI workflow
|
||||
│ ├── ci-cd.yml # Complete CI/CD pipeline
|
||||
│ └── docker-build.yml # Docker build workflow
|
||||
├── embed/
|
||||
│ └── embed_locations.json # Persistent embed tracking
|
||||
├── logs/
|
||||
│ └── pterodisbot.log # Application logs
|
||||
├── tests/
|
||||
│ └── test_pterodisbot.py # Test suite
|
||||
├── pterodisbot.py # Main bot application
|
||||
├── server_metrics_graphs.py # Metrics and graphing module
|
||||
├── generate_config.py # Config generator from env vars
|
||||
├── requirements.txt # Production dependencies
|
||||
├── requirements-test.txt # Testing dependencies
|
||||
├── pytest.ini # Pytest configuration
|
||||
├── Makefile # Development shortcuts
|
||||
├── run_tests.sh # Test runner script
|
||||
├── Dockerfile # Container definition
|
||||
├── docker-compose.yml # Docker Compose configuration
|
||||
├── config.ini.example # Example configuration
|
||||
├── README.md # Application Features Documentation
|
||||
└── LICENSE # GPL-3.0 License
|
||||
```
|
||||
|
||||
### Development Workflow
|
||||
|
||||
#### 1. Feature Development
|
||||
|
||||
```bash
|
||||
# Create feature branch
|
||||
git checkout -b feature/your-feature-name
|
||||
|
||||
# Make changes and test frequently
|
||||
python pterodisbot.py # Manual testing
|
||||
make test # Automated testing
|
||||
|
||||
# Check code quality
|
||||
make lint
|
||||
make format
|
||||
|
||||
# Commit changes
|
||||
git add .
|
||||
git commit -m "feat: add your feature description"
|
||||
|
||||
# Push and create PR
|
||||
git push origin feature/your-feature-name
|
||||
```
|
||||
|
||||
#### 2. Bug Fixes
|
||||
|
||||
```bash
|
||||
# Create bugfix branch
|
||||
git checkout -b fix/bug-description
|
||||
|
||||
# Write test that reproduces bug
|
||||
# (in test_pterodisbot.py)
|
||||
|
||||
# Verify test fails
|
||||
pytest test_pterodisbot.py::TestClass::test_new_bug -v
|
||||
|
||||
# Fix the bug
|
||||
# (in pterodisbot.py or server_metrics_graphs.py)
|
||||
|
||||
# Verify test passes
|
||||
pytest test_pterodisbot.py::TestClass::test_new_bug -v
|
||||
|
||||
# Run full test suite
|
||||
make test
|
||||
|
||||
# Commit both test and fix
|
||||
git add .
|
||||
git commit -m "fix: resolve bug description"
|
||||
```
|
||||
|
||||
#### 3. Testing Changes
|
||||
|
||||
```bash
|
||||
# Run all tests
|
||||
make test
|
||||
|
||||
# Run specific test class
|
||||
pytest test_pterodisbot.py::TestConfigValidation -v
|
||||
|
||||
# Run with coverage
|
||||
make test-coverage
|
||||
|
||||
# Quick test (no coverage)
|
||||
make test-quick
|
||||
|
||||
# Watch mode (requires pytest-watch)
|
||||
make watch
|
||||
```
|
||||
|
||||
### Testing Infrastructure
|
||||
|
||||
#### Test Suite Organization
|
||||
|
||||
```python
|
||||
# test_pterodisbot.py structure
|
||||
├── Fixtures (reusable test setup)
|
||||
│ ├── mock_config
|
||||
│ ├── mock_pterodactyl_api
|
||||
│ ├── sample_server_data
|
||||
│ ├── sample_resources_data
|
||||
│ └── mock_discord_interaction
|
||||
│
|
||||
├── TestConfigValidation
|
||||
│ ├── test_valid_config
|
||||
│ ├── test_missing_sections
|
||||
│ ├── test_invalid_api_keys
|
||||
│ └── test_invalid_urls
|
||||
│
|
||||
├── TestPterodactylAPI
|
||||
│ ├── test_initialization
|
||||
│ ├── test_request_success
|
||||
│ ├── test_request_error
|
||||
│ ├── test_get_servers
|
||||
│ ├── test_get_server_resources
|
||||
│ └── test_send_power_action
|
||||
│
|
||||
├── TestServerMetricsGraphs
|
||||
│ ├── test_add_data_point
|
||||
│ ├── test_data_rotation
|
||||
│ ├── test_cpu_scale_calculation
|
||||
│ ├── test_generate_graphs
|
||||
│ └── test_get_data_summary
|
||||
│
|
||||
├── TestServerMetricsManager
|
||||
│ ├── test_server_creation
|
||||
│ ├── test_cleanup_old_servers
|
||||
│ └── test_get_summary
|
||||
│
|
||||
├── TestServerStatusView
|
||||
│ ├── test_authorization
|
||||
│ └── test_button_interactions
|
||||
│
|
||||
├── TestPterodactylBot
|
||||
│ ├── test_embed_tracking
|
||||
│ ├── test_load_save_locations
|
||||
│ └── test_state_management
|
||||
│
|
||||
└── TestIntegration
|
||||
├── test_complete_workflow
|
||||
└── test_metrics_collection
|
||||
```
|
||||
|
||||
#### Running Tests Locally
|
||||
|
||||
```bash
|
||||
# Using Makefile (recommended)
|
||||
make test # Full test suite with coverage
|
||||
make test-quick # Fast run without coverage
|
||||
make test-unit # Only unit tests
|
||||
make test-integration # Only integration tests
|
||||
make ci # Simulate full CI pipeline
|
||||
|
||||
# Using shell script
|
||||
./run_tests.sh # Interactive full test run
|
||||
./run_tests.sh --quick # Skip linting and security
|
||||
./run_tests.sh --coverage-only # Just coverage report
|
||||
|
||||
# Direct pytest
|
||||
pytest test_pterodisbot.py -v
|
||||
pytest test_pterodisbot.py::TestClass::test_method -v
|
||||
pytest -m "not slow" -v # Skip slow tests
|
||||
pytest --lf # Run last failed tests only
|
||||
```
|
||||
|
||||
#### Coverage Goals
|
||||
|
||||
- **Minimum**: 70% overall coverage
|
||||
- **Target**: 85% overall coverage
|
||||
- **Critical Modules**: 90%+ coverage
|
||||
- Configuration validation
|
||||
- Pterodactyl API client
|
||||
- Metrics tracking system
|
||||
|
||||
#### Viewing Coverage Reports
|
||||
|
||||
```bash
|
||||
# Generate HTML report
|
||||
make test-coverage
|
||||
|
||||
# Open in browser
|
||||
python -m http.server --directory htmlcov 8000
|
||||
# Navigate to http://localhost:8000
|
||||
|
||||
# Terminal report
|
||||
pytest --cov=pterodisbot --cov-report=term-missing
|
||||
```
|
||||
|
||||
### Code Quality Standards
|
||||
|
||||
#### Linting and Formatting
|
||||
|
||||
```bash
|
||||
# Check all quality standards
|
||||
make lint
|
||||
|
||||
# Auto-format code
|
||||
make format
|
||||
|
||||
# Individual tools
|
||||
flake8 pterodisbot.py --max-line-length=120
|
||||
pylint pterodisbot.py --max-line-length=120
|
||||
black --check --line-length=120 pterodisbot.py
|
||||
isort --check-only --profile black pterodisbot.py
|
||||
```
|
||||
|
||||
#### Style Guidelines
|
||||
|
||||
**PEP 8 Compliance:**
|
||||
- Maximum line length: 120 characters
|
||||
- 4 spaces for indentation
|
||||
- Snake_case for functions and variables
|
||||
- PascalCase for classes
|
||||
- UPPER_CASE for constants
|
||||
|
||||
**Type Hints:**
|
||||
```python
|
||||
def function_name(param1: str, param2: int) -> Optional[dict]:
|
||||
"""Function docstring."""
|
||||
return result
|
||||
```
|
||||
|
||||
**Docstrings:**
|
||||
```python
|
||||
def complex_function(arg1: str, arg2: int) -> dict:
|
||||
"""
|
||||
Brief description of function purpose.
|
||||
|
||||
Detailed explanation of what the function does,
|
||||
including any important behavior or side effects.
|
||||
|
||||
Args:
|
||||
arg1: Description of first argument
|
||||
arg2: Description of second argument
|
||||
|
||||
Returns:
|
||||
Description of return value
|
||||
|
||||
Raises:
|
||||
ValueError: When invalid input is provided
|
||||
APIError: When API request fails
|
||||
"""
|
||||
pass
|
||||
```
|
||||
|
||||
**Comments:**
|
||||
- Use comments to explain **why**, not **what**
|
||||
- Complex algorithms should have explanatory comments
|
||||
- TODO comments should include ticket references
|
||||
|
||||
### Security Best Practices
|
||||
|
||||
#### Running Security Scans
|
||||
|
||||
```bash
|
||||
# All security checks
|
||||
make security
|
||||
|
||||
# Individual tools
|
||||
bandit -r . -ll # Code security
|
||||
safety check # Dependency vulnerabilities
|
||||
pip-audit # Package auditing
|
||||
```
|
||||
|
||||
#### Security Checklist
|
||||
|
||||
- [ ] No hardcoded credentials in code
|
||||
- [ ] API keys stored in config.ini (gitignored)
|
||||
- [ ] All user input validated
|
||||
- [ ] SQL injection prevention (N/A - no database)
|
||||
- [ ] Rate limiting on API calls
|
||||
- [ ] Error messages don't leak sensitive info
|
||||
- [ ] Logs don't contain API keys or tokens
|
||||
|
||||
### Debugging Tips
|
||||
|
||||
#### Logging Levels
|
||||
|
||||
```python
|
||||
# Add debug logging
|
||||
logger.debug(f"Processing server {server_id}")
|
||||
|
||||
# Log important state changes
|
||||
logger.info(f"Server {name} changed state to {new_state}")
|
||||
|
||||
# Log warnings
|
||||
logger.warning(f"API rate limit approaching")
|
||||
|
||||
# Log errors with context
|
||||
logger.error(f"Failed to update embed: {str(e)}")
|
||||
```
|
||||
|
||||
#### Common Debugging Commands
|
||||
|
||||
```bash
|
||||
# View logs in real-time
|
||||
tail -f logs/pterodisbot.log
|
||||
|
||||
# Search logs for errors
|
||||
grep ERROR logs/pterodisbot.log
|
||||
|
||||
# Run bot with verbose logging
|
||||
PYTHONUNBUFFERED=1 python pterodisbot.py
|
||||
|
||||
# Debug specific test
|
||||
pytest test_pterodisbot.py::test_name --pdb # Drop into debugger on failure
|
||||
pytest test_pterodisbot.py -vv --showlocals # Show local variables
|
||||
```
|
||||
|
||||
#### VS Code Launch Configuration
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Python: Bot",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/pterodisbot.py",
|
||||
"console": "integratedTerminal",
|
||||
"env": {
|
||||
"PYTHONUNBUFFERED": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Python: Current Test",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"module": "pytest",
|
||||
"args": [
|
||||
"${file}",
|
||||
"-v"
|
||||
],
|
||||
"console": "integratedTerminal"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### CI/CD Integration
|
||||
|
||||
#### Automated Workflows
|
||||
|
||||
The project uses Gitea Actions for continuous integration and deployment:
|
||||
|
||||
**1. Test Workflow** (`.gitea/workflows/test.yml`)
|
||||
- Triggers: Push to any branch, PRs to main
|
||||
- Matrix testing: Python 3.9, 3.10, 3.11
|
||||
- Steps: Lint → Test → Security Scan → Coverage Report
|
||||
|
||||
**2. CI/CD Workflow** (`.gitea/workflows/ci-cd.yml`)
|
||||
- Triggers: Push to main/experimental/dev, version tags, manual dispatch
|
||||
- Steps: Test → Build Docker → Push Registry → Report
|
||||
- Features: Multi-arch builds, automatic versioning
|
||||
|
||||
#### Local CI Simulation
|
||||
|
||||
```bash
|
||||
# Run full CI pipeline locally
|
||||
make ci
|
||||
|
||||
# This executes:
|
||||
# 1. Clean previous artifacts
|
||||
# 2. Install dependencies
|
||||
# 3. Run all tests with coverage
|
||||
# 4. Run linting checks
|
||||
# 5. Run security scans
|
||||
# 6. Generate reports
|
||||
```
|
||||
|
||||
#### Branch Protection Rules
|
||||
|
||||
Recommended settings for `main` branch:
|
||||
- ✅ Require status checks to pass
|
||||
- ✅ Unit Tests (Python 3.11)
|
||||
- ✅ Code Quality
|
||||
- ✅ Security Scan
|
||||
- ✅ Require branches to be up to date
|
||||
- ✅ Require pull request reviews (1+ approvals)
|
||||
- ✅ Dismiss stale reviews on new commits
|
||||
|
||||
### Performance Testing
|
||||
|
||||
```bash
|
||||
# Profile the application
|
||||
python -m cProfile -o profile.stats pterodisbot.py
|
||||
|
||||
# Analyze profile
|
||||
python -m pstats profile.stats
|
||||
> sort cumtime
|
||||
> stats 20
|
||||
|
||||
# Memory profiling
|
||||
pip install memory_profiler
|
||||
python -m memory_profiler pterodisbot.py
|
||||
```
|
||||
|
||||
### Documentation
|
||||
|
||||
#### Generating API Documentation
|
||||
|
||||
```bash
|
||||
# Install documentation tools
|
||||
pip install pdoc3
|
||||
|
||||
# Generate HTML documentation
|
||||
pdoc --html --output-dir docs pterodisbot.py server_metrics_graphs.py
|
||||
|
||||
# View documentation
|
||||
python -m http.server --directory docs 8080
|
||||
```
|
||||
|
||||
#### Updating Documentation
|
||||
|
||||
When adding new features:
|
||||
1. Update inline code comments
|
||||
2. Update function/class docstrings
|
||||
3. Update README.md if user-facing
|
||||
5. Add architecture diagrams if complex
|
||||
Reference in New Issue
Block a user