Development Guide¶
Welcome to the imgif development guide! This guide will help you set up your development environment and contribute to the project.
Prerequisites¶
Before you begin, ensure you have:
- Python 3.9 or higher
- uv package manager
- Git
- A GitHub account (for contributing)
Setting Up Development Environment¶
1. Fork and Clone¶
Fork the repository on GitHub and clone it locally:
# Clone your fork
git clone https://github.com/YOUR_USERNAME/img2gif.git
cd img2gif
# Add upstream remote
git remote add upstream https://github.com/atick-faisal/img2gif.git
2. Install Dependencies¶
Use uv to install all dependencies including development tools:
This installs:
- Core dependencies (Pillow, rich, click)
- Development tools (pytest, ruff, hatch)
- Documentation tools (mkdocs, mkdocs-material)
3. Verify Installation¶
Verify everything is set up correctly:
Project Structure¶
img2gif/
├── src/
│ └── img2gif/ # Main package
│ ├── __init__.py # Public API exports
│ ├── converter.py # ImageToGifConverter class
│ ├── config.py # GifConfig class
│ ├── exceptions.py # Custom exceptions
│ ├── types.py # Type definitions
│ ├── cli.py # CLI implementation
│ └── __main__.py # Entry point
├── tests/ # Test suite
│ ├── __init__.py
│ ├── conftest.py # Shared fixtures
│ ├── unit/ # Unit tests
│ │ ├── test_cli.py
│ │ ├── test_config.py
│ │ └── test_converter.py
│ ├── e2e/ # E2E tests
│ │ └── test_workflow.py
│ └── fixtures/ # Test data
│ ├── generate_test_images.py
│ └── ...
├── docs/ # Documentation
│ ├── index.md
│ ├── getting-started/
│ ├── guide/
│ ├── api/
│ └── contributing/
├── .github/
│ └── workflows/ # CI/CD workflows
├── pyproject.toml # Project configuration
├── mkdocs.yml # Documentation configuration
└── README.md
Development Workflow¶
1. Create a Feature Branch¶
# Update main branch
git checkout main
git pull upstream main
# Create feature branch
git checkout -b feature/your-feature-name
2. Make Changes¶
Edit code following our code style guidelines.
3. Run Tests¶
Always run tests before committing:
# Run all tests
hatch run test
# Run specific test file
hatch run pytest tests/unit/test_converter.py
# Run with coverage
hatch run pytest --cov=src --cov-report=term-missing
4. Run Linter¶
Format and lint your code:
# Auto-format code
ruff format .
# Check for linting issues
ruff check .
# Auto-fix linting issues
ruff check --fix .
5. Commit Changes¶
Follow Conventional Commits specification:
# Stage changes
git add .
# Commit with conventional commit message
git commit -m "feat: add new configuration option"
git commit -m "fix: handle corrupted images gracefully"
git commit -m "docs: update API reference"
Commit types:
feat:- New featuresfix:- Bug fixesdocs:- Documentation changestest:- Test additions/changesrefactor:- Code refactoringchore:- Build process/tooling changes
6. Push and Create PR¶
Then create a Pull Request on GitHub.
Adding New Features¶
1. Plan Your Feature¶
Before coding:
- Open an issue to discuss the feature
- Get feedback from maintainers
- Plan the implementation
2. Write Tests First (TDD)¶
Write tests before implementing:
# tests/test_new_feature.py
import pytest
from imgif import ImageToGifConverter
def test_new_feature():
"""Test the new feature."""
converter = ImageToGifConverter()
# Test your feature
assert result == expected
3. Implement Feature¶
Implement the feature following our code standards:
# src/img2gif/converter.py
def new_feature(self, param: str) -> int:
"""
Brief description of feature.
Args:
param: Description of parameter
Returns:
Description of return value
Example:
>>> converter = ImageToGifConverter()
>>> result = converter.new_feature("test")
>>> result
42
"""
# Implementation
return 42
4. Add Documentation¶
Document your feature in:
- Docstrings (code documentation)
- API reference (docs/api/)
- User guide (docs/guide/)
- Examples (docs/getting-started/examples.md)
5. Update Tests¶
Ensure 100% coverage:
# Run tests with coverage
hatch run pytest --cov=src --cov-report=term-missing
# Check coverage report
# Aim for 100% coverage
Fixing Bugs¶
1. Reproduce the Bug¶
Create a failing test that demonstrates the bug:
def test_bug_reproduction():
"""Reproduce the reported bug."""
# Setup that triggers the bug
converter = ImageToGifConverter()
# This should fail before the fix
with pytest.raises(ExpectedException):
converter.problematic_method()
2. Fix the Bug¶
Fix the issue in the source code.
3. Verify Fix¶
Ensure the test now passes:
4. Add Regression Test¶
Keep the test to prevent regression.
Working with Tests¶
Running Tests¶
# Run all tests
hatch run test
# Run specific test file
hatch run pytest tests/test_converter.py
# Run specific test
hatch run pytest tests/unit/test_converter.py::test_convert
# Run with verbose output
hatch run pytest -v
# Run with coverage
hatch run pytest --cov=src --cov-report=html
Test Matrix¶
Test across multiple Python versions:
# Test on all Python versions (3.9, 3.11, 3.13)
hatch run test:all
# Test on specific version
hatch run test:py39
hatch run test:py311
hatch run test:py313
Writing Tests¶
Follow these guidelines:
import pytest
from pathlib import Path
from imgif import ImageToGifConverter
class TestConverter:
"""Test suite for ImageToGifConverter."""
def test_basic_conversion(self, tmp_path):
"""Test basic GIF conversion."""
# Setup
converter = ImageToGifConverter()
output = tmp_path / "output.gif"
# Execute
converter.convert("./test_images", output)
# Assert
assert output.exists()
assert output.stat().st_size > 0
def test_error_handling(self):
"""Test error handling for invalid input."""
converter = ImageToGifConverter()
with pytest.raises(InvalidInputError):
converter.convert("./nonexistent", "output.gif")
See Testing Guide for detailed testing practices.
Working with Documentation¶
Serving Documentation Locally¶
Building Documentation¶
Documentation Structure¶
- index.md - Home page
- getting-started/ - Installation, quickstart, examples
- guide/ - User guides (basic usage, configuration, CLI)
- api/ - API reference (converter, config, exceptions)
- contributing/ - Development guides (this section)
Writing Documentation¶
Use MkDocs Material features:
!!! note "Note Title"
This is a note admonition.
!!! tip
This is a helpful tip.
!!! warning
This is a warning.
=== "Tab 1"
Content for tab 1
=== "Tab 2"
Content for tab 2
Dependency Management¶
Adding Dependencies¶
# Add runtime dependency
uv add pillow
# Add development dependency
uv add --dev pytest
# Update dependencies
uv sync
Updating Dependencies¶
Pre-commit Hooks¶
Pre-commit hooks automatically run linting and formatting before each commit.
Setup¶
Install pre-commit hooks once after cloning the repository:
# Install pre-commit hooks
uv run pre-commit install
# Verify installation
uv run pre-commit run --all-files
What the Hooks Do¶
The pre-commit hooks automatically:
- Lint code with ruff (auto-fixes issues when possible)
- Format code with ruff
- Trim trailing whitespace
- Fix end of files (ensures newline at end)
- Check YAML/JSON/TOML files for syntax errors
- Check for large files (>1MB)
- Check for merge conflicts
Running Manually¶
# Run all hooks on all files
uv run pre-commit run --all-files
# Run hooks on staged files only
uv run pre-commit run
# Update hook versions
uv run pre-commit autoupdate
Bypass Hooks (Not Recommended)¶
Only in emergencies:
Note: All commits should pass pre-commit hooks before pushing to ensure CI passes.
Continuous Integration¶
GitHub Actions Workflows¶
CI Workflow¶
Runs on every push and PR:
- Linting with ruff
- Tests on Python 3.9, 3.11, 3.13
- Coverage reporting
CD Workflow¶
Runs on tags/releases:
- Linting
- Testing
- Publishing to PyPI
Local CI Simulation¶
Simulate CI locally:
# Run linter (as CI does)
ruff check .
# Run tests on all versions (as CI does)
hatch run test:all
# Check coverage
hatch run pytest --cov=src --cov-report=term-missing
Getting Help¶
- Issues - GitHub Issues
- Discussions - GitHub Discussions
- Documentation - Check existing docs first
Code Review Process¶
Submitting PRs¶
- Ensure all tests pass
- Ensure linting passes
- Update documentation
- Write clear PR description
- Reference related issues
PR Checklist¶
- Tests added/updated
- Documentation updated
- Linting passes
- All tests pass
- Conventional commit messages
- PR description is clear
Review Guidelines¶
Reviewers will check:
- Code quality and style
- Test coverage
- Documentation completeness
- Backward compatibility
- Performance implications
Release Process¶
Releases are handled by maintainers:
- Update version in
pyproject.toml - Update
CHANGELOG.md - Create git tag:
git tag v0.2.0 - Push tag:
git push origin v0.2.0 - GitHub Actions publishes to PyPI
Versioning¶
Follow Semantic Versioning:
- MAJOR (v1.0.0 → v2.0.0) - Breaking changes
- MINOR (v1.0.0 → v1.1.0) - New features (backward compatible)
- PATCH (v1.0.0 → v1.0.1) - Bug fixes (backward compatible)
Best Practices¶
Code Quality¶
- Write clear, self-documenting code
- Add type annotations everywhere
- Write comprehensive docstrings
- Keep functions small and focused
- Avoid premature optimization
Testing¶
- Aim for 100% coverage
- Test edge cases
- Test error conditions
- Use descriptive test names
- Follow AAA pattern (Arrange, Act, Assert)
Documentation¶
- Keep documentation up-to-date
- Include code examples
- Write for your audience
- Use clear, simple language
Git Workflow¶
- Keep commits atomic and focused
- Write clear commit messages
- Rebase before pushing (when appropriate)
- Keep branch up-to-date with main
Next Steps¶
- Read the Testing Guide
- Review Code Style Guidelines
- Check out Examples
- Explore the API Reference