From b0b663b7d8a4ab708b8053951835ee0f925aa7c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Hells=C3=A9n?= Date: Wed, 18 Jun 2025 06:01:01 +0200 Subject: [PATCH] dev: add dev tools, pre-commit, Makefile, contributing, changelog, CI, and fix python version --- .github/workflows/ci.yml | 88 +++++++++++++++++++++++ .pre-commit-config.yaml | 36 ++++++++++ CHANGELOG.md | 42 +++++++++++ CONTRIBUTING.md | 146 +++++++++++++++++++++++++++++++++++++++ Makefile | 49 +++++++++++++ pyproject.toml | 62 ++++++++++++++++- tests/__init__.py | 1 + 7 files changed, 423 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .pre-commit-config.yaml create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 Makefile diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..1b12e4a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,88 @@ +name: CI + +on: + push: + branches: [ main, develop ] + pull_request: + branches: [ main ] + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: Install uv + uses: astral-sh/setup-uv@v3 + with: + version: "latest" + + - name: Cache dependencies + uses: actions/cache@v3 + with: + path: | + .venv + .cache/uv + key: ${{ runner.os }}-uv-${{ hashFiles('**/pyproject.toml') }} + restore-keys: | + ${{ runner.os }}-uv- + + - name: Install dependencies + run: | + uv pip install -e ".[dev]" + + - name: Run linting + run: | + uv run ruff check src/ tests/ example/ + + - name: Run formatting check + run: | + uv run ruff format --check src/ tests/ example/ + + - name: Run type checking + run: | + uv run mypy src/ + + - name: Run tests + run: | + uv run pytest --cov=src --cov-report=xml + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v3 + with: + file: ./coverage.xml + flags: unittests + name: codecov-umbrella + fail_ci_if_error: false + + pre-commit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.13" + + - name: Install uv + uses: astral-sh/setup-uv@v3 + with: + version: "latest" + + - name: Install dependencies + run: | + uv pip install -e ".[dev]" + + - name: Run pre-commit + run: | + uv run pre-commit run --all-files \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..a2a0527 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,36 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files + - id: check-merge-conflict + - id: check-case-conflict + - id: check-docstring-first + - id: debug-statements + + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.12.0 + hooks: + - id: ruff + args: [--fix] + - id: ruff-format + + - repo: https://github.com/pre-commit/mirrors-mypy + rev: v1.8.0 + hooks: + - id: mypy + additional_dependencies: [types-PyYAML] + args: [--ignore-missing-imports] + + - repo: local + hooks: + - id: pytest + name: pytest + entry: pytest + language: system + pass_filenames: false + always_run: true + stages: [manual] \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..d3cee86 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,42 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added +- Initial project structure +- DockerComposeManager class for programmatic Docker Compose file management +- Support for services, volumes, networks, configs, and secrets +- Basic example demonstrating usage +- Comprehensive test suite +- Development tools configuration (Ruff, MyPy, Pre-commit) +- Makefile for common development commands +- Contributing guidelines + +### Changed +- Lowered Python version requirement from 3.13+ to 3.9+ for broader compatibility + +### Fixed +- None yet + +## [0.1.0] - 2024-01-XX + +### Added +- Initial release +- Core DockerComposeManager functionality +- Support for basic Docker Compose features: + - Services with full configuration options + - Volumes + - Networks + - Configs + - Secrets +- Context manager support for auto-saving +- Pydantic models for type safety +- YAML file generation and parsing + +[Unreleased]: https://github.com/yourusername/compose/compare/v0.1.0...HEAD +[0.1.0]: https://github.com/yourusername/compose/releases/tag/v0.1.0 \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..7feb27d --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,146 @@ +# Contributing to Compose + +Thank you for your interest in contributing to the Compose project! This document provides guidelines and information for contributors. + +## Development Setup + +1. **Clone the repository:** + ```bash + git clone + cd compose + ``` + +2. **Install development dependencies:** + ```bash + uv pip install -e ".[dev]" + ``` + +3. **Install pre-commit hooks:** + ```bash + make pre-commit-install + ``` + +## Development Workflow + +### Code Quality + +We use several tools to maintain code quality: + +- **Ruff**: For linting and formatting +- **MyPy**: For type checking +- **Pre-commit**: For automated checks on commit + +### Running Checks + +```bash +# Run all checks +make check-all + +# Run individual checks +make lint # Linting +make format # Code formatting +make type-check # Type checking +make test # Tests +make test-cov # Tests with coverage +``` + +### Pre-commit Hooks + +Pre-commit hooks will automatically run on each commit. To run them manually: + +```bash +make pre-commit-run +``` + +## Testing + +### Running Tests + +```bash +# Run all tests +make test + +# Run tests with coverage +make test-cov + +# Run specific test file +uv run pytest tests/test_specific.py + +# Run tests with verbose output +uv run pytest -v +``` + +### Writing Tests + +- Place all tests in the `tests/` directory +- Use descriptive test names +- Follow the existing test patterns +- Include both positive and negative test cases +- Test edge cases and error conditions + +## Code Style + +### Python Code + +- Follow PEP 8 style guidelines +- Use type hints for all function parameters and return values +- Write docstrings for all public functions and classes +- Use Google-style docstrings + +### Commit Messages + +- Use clear, descriptive commit messages +- Start with a verb in present tense (e.g., "Add", "Fix", "Update") +- Keep the first line under 50 characters +- Add more details in the body if needed + +Example: +``` +Add support for Docker Compose volumes + +- Implement VolumeConfig class +- Add add_volume and remove_volume methods +- Include comprehensive tests +``` + +## Pull Request Process + +1. **Create a feature branch** from the main branch +2. **Make your changes** following the coding guidelines +3. **Write tests** for new functionality +4. **Run all checks** to ensure code quality +5. **Update documentation** if needed +6. **Submit a pull request** with a clear description + +### Pull Request Checklist + +- [ ] Code follows the project's style guidelines +- [ ] Tests pass and coverage is maintained +- [ ] Documentation is updated +- [ ] Pre-commit hooks pass +- [ ] Type checking passes +- [ ] Linting passes + +## Reporting Issues + +When reporting issues, please include: + +- A clear description of the problem +- Steps to reproduce the issue +- Expected behavior +- Actual behavior +- Environment details (Python version, OS, etc.) +- Any relevant error messages or logs + +## Getting Help + +If you need help or have questions: + +- Check the existing documentation +- Look at existing issues and pull requests +- Create a new issue for bugs or feature requests +- Ask questions in discussions + +## License + +By contributing to this project, you agree that your contributions will be licensed under the same license as the project. \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..083b427 --- /dev/null +++ b/Makefile @@ -0,0 +1,49 @@ +.PHONY: help install install-dev test test-cov lint format type-check clean build publish + +help: ## Show this help message + @echo "Available commands:" + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' + +install: ## Install the package in development mode + uv pip install -e . + +install-dev: ## Install the package with development dependencies + uv pip install -e ".[dev]" + +test: ## Run tests + uv run pytest + +test-cov: ## Run tests with coverage + uv run pytest --cov=src --cov-report=html --cov-report=term-missing + +lint: ## Run linting checks + uv run ruff check src/ tests/ example/ + +format: ## Format code + uv run ruff format src/ tests/ example/ + +type-check: ## Run type checking + uv run mypy src/ + +clean: ## Clean up build artifacts + rm -rf build/ + rm -rf dist/ + rm -rf *.egg-info/ + rm -rf .pytest_cache/ + rm -rf .coverage + rm -rf htmlcov/ + rm -rf .mypy_cache/ + +build: ## Build the package + uv run python -m build + +publish: ## Publish to PyPI (requires authentication) + uv run python -m twine upload dist/* + +pre-commit-install: ## Install pre-commit hooks + uv run pre-commit install + +pre-commit-run: ## Run pre-commit on all files + uv run pre-commit run --all-files + +check-all: lint type-check test ## Run all checks (lint, type-check, test) \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 3f6b375..823b2e0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ name = "compose" version = "0.1.0" description = "A simple Python package for managing Docker Compose files" readme = "README.md" -requires-python = ">=3.13" +requires-python = ">=3.9" dependencies = [ "pydantic>=2.11.7", "pytest>=8.4.0", @@ -11,6 +11,16 @@ dependencies = [ "ruff>=0.12.0", ] +[project.optional-dependencies] +dev = [ + "mypy>=1.8.0", + "pre-commit>=3.6.0", + "pytest-cov>=4.1.0", + "pytest-mock>=3.12.0", + "hypothesis>=6.98.0", + "types-PyYAML>=6.0.12", +] + [build-system] requires = ["hatchling"] build-backend = "hatchling.build" @@ -66,3 +76,53 @@ lint.ignore = [ [tool.ruff.lint.per-file-ignores] "tests/*" = ["S101", "D103", "PLR2004"] + +[tool.mypy] +python_version = "3.9" +warn_return_any = true +warn_unused_configs = true +disallow_untyped_defs = true +disallow_incomplete_defs = true +check_untyped_defs = true +disallow_untyped_decorators = true +no_implicit_optional = true +warn_redundant_casts = true +warn_unused_ignores = true +warn_no_return = true +warn_unreachable = true +strict_equality = true + +[tool.pytest.ini_options] +testpaths = ["tests"] +python_files = ["test_*.py"] +python_classes = ["Test*"] +python_functions = ["test_*"] +addopts = [ + "--strict-markers", + "--strict-config", + "--cov=src", + "--cov-report=term-missing", + "--cov-report=html", + "--cov-report=xml", +] + +[tool.coverage.run] +source = ["src"] +omit = [ + "*/tests/*", + "*/test_*", +] + +[tool.coverage.report] +exclude_lines = [ + "pragma: no cover", + "def __repr__", + "if self.debug:", + "if settings.DEBUG", + "raise AssertionError", + "raise NotImplementedError", + "if 0:", + "if __name__ == .__main__.:", + "class .*\\bProtocol\\):", + "@(abc\\.)?abstractmethod", +] diff --git a/tests/__init__.py b/tests/__init__.py index e69de29..09f3e0a 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -0,0 +1 @@ +"""Test package for the compose library."""