Thank you for your interest in contributing to Simple Port Checker! This guide will help you get started.
This project adheres to a code of conduct. By participating, you are expected to uphold this code. Please be respectful and professional in all interactions.
-
Fork and clone the repository
git clone https://github.com/yourusername/simple-port-checker.git cd simple-port-checker -
Set up development environment
./setup_dev.sh # Or manually: python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate pip install -e ".[dev]"
-
Install pre-commit hooks
pre-commit install
-
Verify setup
make test port-checker --help
-
Create a feature branch
git checkout -b feature/your-feature-name
-
Make your changes
- Write code following the existing style
- Add tests for new functionality
- Update documentation as needed
-
Run quality checks
make dev # Runs format, lint, and test -
Commit your changes
git add . git commit -m "Add: description of your changes"
-
Push and create a pull request
git push origin feature/your-feature-name
- PEP 8: Follow Python style guidelines
- Black: Code formatting (line length: 88)
- isort: Import sorting
- Type hints: Use type annotations for all functions
- Docstrings: Use Google-style docstrings
Example:
async def scan_port(host: str, port: int, timeout: float = 3.0) -> PortResult:
"""
Scan a single port on a target host.
Args:
host: Target hostname or IP address
port: Port number to scan
timeout: Connection timeout in seconds
Returns:
PortResult containing scan information
Raises:
ConnectionError: If unable to connect to host
"""
# Implementation heresrc/simple_port_checker/
├── __init__.py # Package exports
├── core/ # Core functionality
│ ├── port_scanner.py # Port scanning logic
│ └── l7_detector.py # L7 protection detection
├── models/ # Data models
│ ├── scan_result.py # Scan result models
│ └── l7_result.py # L7 detection models
├── utils/ # Utility functions
│ ├── common_ports.py # Port definitions
│ └── l7_signatures.py # L7 service signatures
└── cli.py # Command-line interface
# Run all tests
make test
# Run with coverage
make test-cov
# Run specific test file
pytest tests/test_port_scanner.py -v
# Run specific test
pytest tests/test_port_scanner.py::TestPortChecker::test_scan_host_success -v- Use
pytestfor all tests - Write tests for both success and failure cases
- Use async tests for async code
- Mock external dependencies
- Aim for >90% code coverage
Example test:
@pytest.mark.asyncio
async def test_scan_host_success(self):
"""Test successful host scanning."""
checker = PortChecker()
with patch('socket.gethostbyname', return_value='127.0.0.1'):
with patch('asyncio.open_connection') as mock_conn:
mock_conn.return_value = (AsyncMock(), AsyncMock())
result = await checker.scan_host("example.com", [80])
assert result.host == "example.com"
assert len(result.ports) == 1-
Add to L7Protection enum in
models/l7_result.py:NEW_SERVICE = "new_service"
-
Add signatures in
utils/l7_signatures.py:L7Protection.NEW_SERVICE: { "headers": { "X-New-Service": [r".*"], "Server": [r"NewService.*"], }, "server": [r"NewService.*"], "body": [r"blocked by new service"], "status_codes": [403], "description": "New Service WAF" }
-
Add tests in
tests/test_l7_detector.py -
Update documentation
- Add functionality to
core/port_scanner.py - Add models if needed in
models/ - Add CLI command in
cli.py - Add tests in
tests/ - Update documentation
- README.md: Main project documentation
- docs/quickstart.md: Quick start guide
- Docstrings: Inline code documentation
- Examples: Add to
examples/directory
- Use clear, concise language
- Include code examples
- Keep examples up-to-date
- Document breaking changes
- Ensure CI passes: All tests and checks must pass
- Update documentation: Include relevant documentation updates
- Add tests: New features must include tests
- Follow commit conventions: Use clear, descriptive commit messages
- Update CHANGELOG.md: Add entry for your changes
Type: Brief description
Longer description if needed
- Detail 1
- Detail 2
Fixes #123
Types:
Add: New featureFix: Bug fixUpdate: Modify existing featureRemove: Remove featureDocs: Documentation changesTest: Test changesRefactor: Code refactoring
## Description
Brief description of changes
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Testing
- [ ] Tests pass locally
- [ ] New tests added
- [ ] Manual testing completed
## Checklist
- [ ] Code follows style guidelines
- [ ] Self-review completed
- [ ] Documentation updated
- [ ] CHANGELOG.md updatedWe follow Semantic Versioning:
- MAJOR: Breaking changes
- MINOR: New features (backward compatible)
- PATCH: Bug fixes (backward compatible)
- Update version in
pyproject.toml - Update CHANGELOG.md
- Create release tag:
git tag v1.0.0 - Push tag:
git push origin v1.0.0 - GitHub Actions will automatically publish to PyPI
- GitHub Issues: Bug reports and feature requests
- GitHub Discussions: Questions and general discussion
- Pull Requests: Code review and collaboration
Bug Report:
- Description of the bug
- Steps to reproduce
- Expected vs actual behavior
- Environment details
- Relevant logs/screenshots
Feature Request:
- Clear description of the feature
- Use case and motivation
- Proposed implementation (if any)
- Alternative solutions considered
Do not open public issues for security vulnerabilities. Instead:
- Email security concerns to: [security@example.com]
- Include detailed description
- Provide steps to reproduce
- Allow reasonable time for response
- Never commit secrets or credentials
- Validate all user inputs
- Use secure defaults
- Follow principle of least privilege
- Keep dependencies updated
Contributors will be recognized in:
- CONTRIBUTORS.md file
- Release notes for significant contributions
- GitHub contributors page
Thank you for contributing to Simple Port Checker! 🎉