pyproject.toml•10.4 kB
[project]
name = "mcp-server-git"
version = "0.6.3"
description = "A Model Context Protocol server providing tools to read, search, and manipulate Git repositories programmatically via LLMs"
readme = "README.md"
requires-python = ">=3.12"
authors = [{ name = "Anthropic, PBC." }]
maintainers = [{ name = "Memento 'RC' Mori" }]
keywords = ["git", "mcp", "llm", "automation"]
license = { text = "MIT" }
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.12",
]
dependencies = [
# Core dependencies now managed by pixi
]
# Dependencies now managed by pixi tiered features
[project.scripts]
mcp-server-git = "mcp_server_git:main"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = "test_*.py"
python_classes = "Test*"
python_functions = "test_*"
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
pythonpath = ["src"]
addopts = "-v --tb=short --timeout=30"
timeout = 30
markers = [
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
"e2e: marks tests as end-to-end tests (deselect with '-m \"not e2e\"')",
"ci_skip: marks tests to skip in CI environment",
"mcp_verification: tests that replicate manual MCP verification process",
"phase1: basic git operations (status, log, diff)",
"phase2: GitHub API operations (list PRs, get details, status)",
"phase3: advanced git operations (show, security validation)",
"phase4: error handling and edge cases",
"requires_github_token: tests that require GitHub API access"
]
[tool.ruff]
target-version = "py312"
line-length = 88
[tool.ruff.lint]
select = ["F", "E9", "W", "I", "B", "C4", "UP"]
ignore = ["E501"]
[tool.ruff.lint.per-file-ignores]
"tests/**/*.py" = ["F821", "F401", "F841"]
# TDD type tests: Allow undefined names and unused imports during red phase
"tests/unit/types/*.py" = ["F821", "F401", "F841"]
# Ensure production code maintains strict standards
"src/mcp_server_git/types/*.py" = []
[tool.ruff.format]
# Ensure consistent formatting across ruff versions
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"
[tool.pixi.project]
channels = ["conda-forge"]
platforms = ["linux-64"] # CI-optimized: single platform for reliability
[tool.pixi.dependencies]
# Core runtime dependencies
python = ">=3.12"
aiohttp = ">=3.8.0"
click = ">=8.1.7"
gitpython = ">=3.1.43"
mcp = ">=1.11.0"
psutil = ">=5.9.0"
pydantic = ">=2.0.0"
python-dotenv = ">=1.0.0"
# No PyPI dependencies - everything from conda-forge
# ===== TIERED QUALITY FEATURES =====
# TIER 1: Essential Quality Gates (ZERO-TOLERANCE)
[tool.pixi.feature.quality.dependencies]
# Core Testing Framework
pytest = ">=8.0.0"
pytest-cov = ">=4.0.0"
pytest-timeout = ">=2.1.0"
pytest-asyncio = ">=0.21.0"
pytest-xdist = ">=3.3.0"
# Linting & Formatting
ruff = ">=0.7.3"
# Type Checking
mypy = ">=1.0.0"
# Type checking moved to conda-forge in quality dependencies
# TIER 2: Extended Quality & Security
[tool.pixi.feature.quality-extended.dependencies]
# Security Scanning
bandit = ">=1.7.0"
# Code Quality Analysis
hypothesis = ">=6.0.0"
# Git Hooks
pre-commit = ">=3.0.0"
# Security Scanning
safety = ">=2.3.0"
# Security tools from conda-forge only
# TIER 3: CI/CD & Build
[tool.pixi.feature.quality-ci.dependencies]
# CI Reporting
coverage = ">=7.0.0"
pytest-json-report = ">=1.5.0"
pytest-html = ">=4.0.0"
# Build Tools (conda-forge versions)
twine = ">=4.0.0"
# Build tools from conda-forge only
# ===== DEVELOPMENT FEATURES =====
# Keep existing dev feature for specialized tools
[tool.pixi.feature.dev-specialized.dependencies]
# Development tools not needed for CI
memory_profiler = "*"
pytest-benchmark = "*"
pytest-aiohttp = ">=1.0.0"
pytest-mock = ">=3.10.0"
pytest-metadata = ">=3.0.0"
faker = "*"
[tool.pixi.environments]
# Basic runtime environment
default = {solve-group = "default"}
# Quality gate environments (tiered approach)
quality = {features = ["quality"], solve-group = "default"}
quality-extended = {features = ["quality", "quality-extended"], solve-group = "default"}
quality-full = {features = ["quality", "quality-extended", "quality-ci"], solve-group = "default"}
# Development environment (full quality + specialized tools)
dev = {features = ["quality", "quality-extended", "quality-ci", "dev-specialized"], solve-group = "default"}
# CI environment (quality + CI reporting)
ci = {features = ["quality", "quality-ci"], solve-group = "default"}
[tool.pixi.tasks]
# ===== TIER 1: CORE DEVELOPMENT TASKS (ESSENTIAL) =====
# Installation & Setup
install-editable = "python -c 'import sys; print(f\"PIXI environment active: {sys.executable}\", file=sys.stderr); print(\"Package available via PIXI - no pip needed\", file=sys.stderr)'"
dev-setup = "echo 'Development environment ready'"
# Testing (ZERO-TOLERANCE QUALITY GATES)
# NOTE: Tests require quality environment - run with: pixi run -e quality test
test = { cmd = "pytest tests/ -v --ignore=tests/test_e2e_server.py", env = { CLAUDECODE = "0" } }
test-cov = { cmd = "pytest tests/ --cov=src/mcp_server_git --cov-report=term-missing --cov-report=xml", env = { CLAUDECODE = "0" } }
test-unit = { cmd = "pytest tests/unit/ -v", env = { CLAUDECODE = "0" } }
test-integration = { cmd = "pytest tests/integration/ -v", env = { CLAUDECODE = "0" } }
test-e2e = { cmd = "pytest tests/test_e2e_server.py -v", env = { CLAUDECODE = "0" } }
test-property = { cmd = "pytest tests/ -m property -v", env = { CLAUDECODE = "0" } }
# Quality Gates (CRITICAL - MUST PASS)
# NOTE: These require quality environment - run with: pixi run -e quality lint
lint = "ruff check src/ tests/ --select=F,E9"
lint-fix = "ruff check --fix src/ tests/"
format = "ruff format src/ tests/"
format-check = "ruff format --check src/ tests/"
format-diff = "ruff format --diff src/ tests/"
typecheck = "pyright src/"
# Combined Quality Check
quality = { depends-on = ["test", "lint", "typecheck"] }
# Emergency Quality Fix - USE FOR "Found X errors" CI FAILURES
emergency-fix = "pixi run -e quality lint-fix && pixi run -e quality format && pixi run -e quality test"
# ===== TIER 2: SECURITY & COMPLIANCE TASKS =====
# Security Scanning
# NOTE: These require quality-extended environment - run with: pixi run -e quality-extended security-scan
security-scan = "bandit -r src/ --severity-level high"
safety-check = "safety check"
# Static Analysis Suite
static-analysis = { depends-on = ["security-scan", "safety-check"] }
# Pre-commit Integration - with Claude Code git bypass
# NOTE: These require quality-extended environment - run with: pixi run -e quality-extended pre-commit
pre-commit = { cmd = "pre-commit run --all-files", env = { CLAUDECODE = "0" } }
install-pre-commit = { cmd = "pre-commit install --install-hooks", env = { CLAUDECODE = "0" } }
# Comprehensive Check
check-all = { depends-on = ["quality", "static-analysis"] }
# ===== TIER 3: CI/CD & DEPLOYMENT TASKS =====
# CI-specific variants with environment simulation
ci-test = { cmd = "pytest tests/ --cov=src/mcp_server_git --cov-report=xml --timeout=180 --ignore=tests/test_e2e_server.py --ignore=tests/test_llm_compliant_server_e2e.py -m 'not ci_skip' --tb=short --maxfail=10 --disable-warnings", env = { ENVIRONMENT = "ci", PYTEST_CI = "true", CI = "true", CLAUDECODE = "0" } }
ci-test-debug = { cmd = "pytest tests/ --cov=src/mcp_server_git --cov-report=xml --timeout=180 --ignore=tests/test_e2e_server.py --ignore=tests/test_llm_compliant_server_e2e.py -m 'not ci_skip' --tb=long -v -s --capture=no", env = { ENVIRONMENT = "ci", PYTEST_CI = "true", CI = "true", CLAUDECODE = "0" } }
ci-lint = "ruff check src/ tests/ --output-format=github"
ci-format-check = "ruff format --check src/ tests/"
# Stress testing with CI environment simulation
# NOTE: These require quality environment - run with: pixi run -e quality test-stress-local
test-stress-ci = { cmd = "pytest tests/stress/ -v --tb=short", env = { PYTEST_CI = "true", CI = "true", CLAUDECODE = "0" } }
test-stress-local = { cmd = "pytest tests/stress/ -v --tb=short", env = { CLAUDECODE = "0" } }
# Build & Deploy
build = "python -m build"
clean = "rm -rf __pycache__ .pytest_cache .coverage htmlcov .ruff_cache dist build"
# ===== APPLICATION TASKS =====
# Server execution
serve = "python -m mcp_server_git"
pixi-git-server = { cmd = "python -m mcp_server_git", env = { PYTHONPATH = "src", CLAUDECODE = "0" } }
pixi-git-server-debug = { cmd = "python -m mcp_server_git -vv --enable-file-logging", env = { PYTHONPATH = "src", LOG_LEVEL = "DEBUG", CLAUDECODE = "0" } }
# Auto-install and run MCP server (for ClaudeCode integration)
mcp-server-git = { cmd = "python -m mcp_server_git", env = { PYTHONPATH = "src", CLAUDECODE = "0" } }
# Production testing
# NOTE: Requires quality environment - run with: pixi run -e quality test-production
test-production = { depends-on = ["install-editable"], cmd = "pytest tests/test_e2e_server.py -v", env = { CLAUDECODE = "0" } }
# ===== LEGACY/SPECIALIZED TASKS =====
# Keep existing specialized tasks - with Claude Code git bypass
# NOTE: These require specific environments - see comments
benchmark = { cmd = "pytest tests/ -m benchmark --benchmark-only --benchmark-sort=mean", env = { CLAUDECODE = "0" } } # requires dev environment
test-coverage = { cmd = "pytest tests/ --cov=src/mcp_server_git --cov-branch --cov-report=html --cov-report=xml --cov-report=json --cov-report=term-missing", env = { CLAUDECODE = "0" } } # requires quality-full environment
# Environment-specific test variants
# NOTE: These require quality environment - run with: pixi run -e quality test-quick
test-ci-simulation = { cmd = "pytest tests/ -v --ignore=tests/test_e2e_server.py --tb=short", env = { PYTEST_CI = "true", CI = "true", GITHUB_ACTIONS = "true", CLAUDECODE = "0" } }
test-local-full = { cmd = "pytest tests/ -v --ignore=tests/test_e2e_server.py", env = { CLAUDECODE = "0" } }
# Quick test variants
test-quick = { cmd = "pytest tests/unit/ tests/integration/ -v", env = { CLAUDECODE = "0" } }
test-quick-ci = { cmd = "pytest tests/unit/ tests/integration/ -v", env = { PYTEST_CI = "true", CI = "true", CLAUDECODE = "0" } }