.PHONY: clean clean-pyc clean-build clean-test clean-all test test-cov run-mcp run-cli build publish publish-test publish-check help install dev-install lint format typecheck check info demo setup-dev
# Default target
help:
@echo "๐ iOS Device Control MCP Server - Available targets:"
@echo ""
@echo "๐ฆ Installation & Setup:"
@echo " install - Install package in current environment"
@echo " dev-install - Install package in development mode with dev dependencies"
@echo " setup-dev - Full development setup (install + check iOS tools)"
@echo ""
@echo "๐งน Cleaning:"
@echo " clean - Remove Python bytecode and basic artifacts"
@echo " clean-all - Deep clean everything (pyc, build, test, cache)"
@echo " clean-pyc - Remove Python bytecode files"
@echo " clean-build - Remove build artifacts"
@echo " clean-test - Remove test artifacts"
@echo ""
@echo "๐งช Testing & Quality:"
@echo " test - Run tests with pytest"
@echo " test-cov - Run tests with coverage reporting"
@echo " lint - Run code linting (ruff)"
@echo " format - Format code with ruff"
@echo " typecheck - Run type checking with mypy"
@echo " check - Run all code quality checks"
@echo ""
@echo "๐ Running:"
@echo " run-main - Run the main dispatcher (shows help)"
@echo " run-mcp - Run the MCP server"
@echo " run-cli - Run the CLI interface"
@echo " run-cli-status - Run CLI status command"
@echo " demo - Run interactive demo"
@echo " demo-auto - Run automated demo"
@echo " demo-mcp - Run MCP end-to-end demo"
@echo " test-sim - Test simulator connectivity"
@echo ""
@echo "๐ฆ Building & Publishing:"
@echo " build - Build the project"
@echo " publish-check - Check package before publishing"
@echo " publish-test - Publish to test PyPI"
@echo " publish - Build and publish to PyPI"
@echo ""
@echo "โน๏ธ Information:"
@echo " info - Show project and environment info"
@echo " check-ios - Check iOS development environment"
# Basic clean - Python bytecode and common artifacts
clean: clean-pyc clean-build
@echo "๐งน Basic clean complete."
# Remove Python bytecode files and __pycache__ directories
clean-pyc:
@echo "๐งน Cleaning Python bytecode files..."
@find . -type f -name '*.pyc' -delete 2>/dev/null || true
@find . -type f -name '*.pyo' -delete 2>/dev/null || true
@find . -type d -name '__pycache__' -exec rm -rf {} + 2>/dev/null || true
@find . -type d -name '*.egg-info' -exec rm -rf {} + 2>/dev/null || true
# Remove build artifacts
clean-build:
@echo "๐งน Cleaning build artifacts..."
@rm -rf build/ dist/ *.egg-info 2>/dev/null || true
@rm -rf .eggs/ 2>/dev/null || true
@find . -name '*.egg' -exec rm -f {} + 2>/dev/null || true
# Remove test artifacts
clean-test:
@echo "๐งน Cleaning test artifacts..."
@rm -rf .pytest_cache/ 2>/dev/null || true
@rm -rf .coverage 2>/dev/null || true
@rm -rf htmlcov/ 2>/dev/null || true
@rm -rf .tox/ 2>/dev/null || true
@rm -rf .cache/ 2>/dev/null || true
@find . -name '.coverage.*' -delete 2>/dev/null || true
# Deep clean - everything including demo outputs
clean-all: clean-pyc clean-build clean-test
@echo "๐งน Deep cleaning..."
@rm -rf .mypy_cache/ 2>/dev/null || true
@rm -rf .ruff_cache/ 2>/dev/null || true
@rm -rf .uv/ 2>/dev/null || true
@rm -rf node_modules/ 2>/dev/null || true
@find . -name '.DS_Store' -delete 2>/dev/null || true
@find . -name 'Thumbs.db' -delete 2>/dev/null || true
@find . -name '*.log' -delete 2>/dev/null || true
@find . -name '*.tmp' -delete 2>/dev/null || true
@find . -name '*~' -delete 2>/dev/null || true
@echo "๐งน Cleaning demo outputs..."
@rm -rf simulator_demo_output/ 2>/dev/null || true
@rm -rf mcp_e2e_demo_output/ 2>/dev/null || true
@rm -rf techmeme_news/ 2>/dev/null || true
@rm -rf ~/.ios-device-control/sessions/*.json 2>/dev/null || true
@echo "โ
Deep clean complete."
# Install package
install:
@echo "๐ฆ Installing package..."
@if command -v uv >/dev/null 2>&1; then \
uv pip install .; \
else \
pip install .; \
fi
# Install package in development mode with dev dependencies
dev-install:
@echo "๐ฆ Installing package in development mode..."
@if command -v uv >/dev/null 2>&1; then \
uv pip install -e ".[dev]"; \
else \
pip install -e ".[dev]"; \
fi
# Full development setup
setup-dev: dev-install check-ios
@echo "๐ฏ Development setup complete!"
@echo "๐ก Try: make demo"
# Run tests
test:
@echo "๐งช Running tests..."
@if command -v uv >/dev/null 2>&1; then \
uv run pytest tests/ -v; \
elif command -v pytest >/dev/null 2>&1; then \
pytest tests/ -v; \
else \
python -m pytest tests/ -v; \
fi
# Run tests with coverage
test-cov:
@echo "๐งช Running tests with coverage..."
@if command -v uv >/dev/null 2>&1; then \
uv run pytest tests/ --cov=src/chuk_mcp_ios --cov-report=html --cov-report=term --cov-report=xml -v; \
else \
pytest tests/ --cov=src/chuk_mcp_ios --cov-report=html --cov-report=term --cov-report=xml -v; \
fi
# Run the main dispatcher (new unified entry point)
run-main:
@echo "๐ Starting chuk-mcp-ios main dispatcher..."
@if command -v uv >/dev/null 2>&1; then \
PYTHONPATH=src uv run python -m chuk_mcp_ios.main; \
else \
PYTHONPATH=src python3 -m chuk_mcp_ios.main; \
fi
# Run the MCP server (via dispatcher)
run-mcp:
@echo "๐ Starting MCP iOS Server..."
@if command -v uv >/dev/null 2>&1; then \
PYTHONPATH=src uv run python -m chuk_mcp_ios.main mcp; \
else \
PYTHONPATH=src python3 -m chuk_mcp_ios.main mcp; \
fi
# Run the CLI interface (via dispatcher)
run-cli:
@echo "๐ Starting iOS Control CLI..."
@if command -v uv >/dev/null 2>&1; then \
PYTHONPATH=src uv run python -m chuk_mcp_ios.main cli; \
else \
PYTHONPATH=src python3 -m chuk_mcp_ios.main cli; \
fi
# Run CLI with status command
run-cli-status:
@echo "๐ Running iOS Control CLI Status..."
@if command -v uv >/dev/null 2>&1; then \
PYTHONPATH=src uv run python -m chuk_mcp_ios.main cli status; \
else \
PYTHONPATH=src python3 -m chuk_mcp_ios.main cli status; \
fi
# Run interactive demo
demo:
@echo "๐ฎ Starting Interactive iOS Demo..."
@if command -v uv >/dev/null 2>&1; then \
uv run python examples/interactive_demo.py; \
else \
python3 examples/interactive_demo.py; \
fi
# Run automated demo
demo-auto:
@echo "๐ค Starting Automated iOS Demo..."
@if command -v uv >/dev/null 2>&1; then \
uv run python examples/automated_demo.py; \
else \
python3 examples/automated_demo.py; \
fi
# Run MCP E2E demo
demo-mcp:
@echo "๐ง Starting MCP End-to-End Demo..."
@if command -v uv >/dev/null 2>&1; then \
uv run python examples/e2e_mcp_demo.py; \
else \
python3 examples/e2e_mcp_demo.py; \
fi
# Test simulator connectivity
test-sim:
@echo "๐ฑ Testing iOS Simulator connectivity..."
@if command -v uv >/dev/null 2>&1; then \
uv run python examples/test_simulator.py; \
else \
python3 examples/test_simulator.py; \
fi
# Run Techmeme news capture demo
demo-news:
@echo "๐ฐ Starting Techmeme News Demo..."
@if command -v uv >/dev/null 2>&1; then \
uv run python examples/techmeme.py; \
else \
python3 examples/techmeme.py; \
fi
# Build the project using the pyproject.toml configuration
build: clean-build
@echo "๐จ Building project..."
@if command -v uv >/dev/null 2>&1; then \
uv build; \
else \
python3 -m build; \
fi
@echo "โ
Build complete. Distributions are in the 'dist' folder."
# Check package before publishing (using external script)
publish-check: build
@echo "๐ Checking package before publishing..."
@if [ -f "scripts/validate_package.py" ]; then \
python3 scripts/validate_package.py; \
else \
echo "๐ Basic package validation..."; \
echo "๐ฆ Built distributions:"; \
ls -la dist/ 2>/dev/null || echo "โ No dist directory found"; \
if command -v twine >/dev/null 2>&1; then \
echo "๐ Running twine check..."; \
twine check dist/* 2>/dev/null || echo "โ ๏ธ Twine check had warnings"; \
else \
echo "๐ Twine not available, basic validation only"; \
fi; \
echo "โ
Basic validation complete"; \
echo "๐ก For detailed validation, create scripts/validate_package.py"; \
fi
# Check for .pypirc file
check-pypirc:
@echo "๐ Checking for .pypirc configuration..."
@if [ -f "$$HOME/.pypirc" ]; then \
echo "โ
Found .pypirc file at $$HOME/.pypirc"; \
echo "๐ Configuration sections:"; \
grep -E '^\[.*\]$$' $$HOME/.pypirc || echo "No sections found"; \
else \
echo "โ No .pypirc file found at $$HOME/.pypirc"; \
echo "๐ก Create .pypirc with:"; \
echo " [pypi]"; \
echo " username = __token__"; \
echo " password = pypi-your-token-here"; \
fi
# Publish the package to PyPI using .pypirc
publish: build check-pypirc
@echo "๐ค Publishing package to PyPI using .pypirc..."
@if [ ! -d "dist" ] || [ -z "$$(ls -A dist 2>/dev/null)" ]; then \
echo "โ Error: No distribution files found. Run 'make build' first."; \
exit 1; \
fi
@echo "๐ Found distribution files:"
@ls -la dist/
@echo ""
@if [ ! -f "$$HOME/.pypirc" ]; then \
echo "โ Error: .pypirc file not found at $$HOME/.pypirc"; \
echo "๐ก Create .pypirc file with your PyPI token:"; \
echo " [pypi]"; \
echo " username = __token__"; \
echo " password = pypi-your-token-here"; \
exit 1; \
fi
@if command -v twine >/dev/null 2>&1; then \
echo "๐ค Using twine to publish (reads .pypirc automatically)..."; \
last_build=$$(ls -t dist/*.tar.gz dist/*.whl 2>/dev/null | head -n 2); \
if [ -z "$$last_build" ]; then \
echo "โ Error: No valid distribution files found."; \
exit 1; \
fi; \
echo "๐ค Uploading: $$last_build"; \
twine upload $$last_build; \
elif command -v uv >/dev/null 2>&1; then \
echo "๐ค Using uv to publish..."; \
echo "โ ๏ธ Note: uv publish may not read .pypirc reliably"; \
echo "๐ก If prompted for credentials, use __token__ and your PyPI token"; \
uv publish dist/* || { \
echo "โ uv publish failed. Trying with explicit credentials..."; \
if [ -f "$$HOME/.pypirc" ]; then \
USERNAME=$$(grep -A 5 '^\[pypi\]' $$HOME/.pypirc | grep '^username' | cut -d'=' -f2 | tr -d ' '); \
PASSWORD=$$(grep -A 5 '^\[pypi\]' $$HOME/.pypirc | grep '^password' | cut -d'=' -f2 | tr -d ' '); \
if [ -n "$$USERNAME" ] && [ -n "$$PASSWORD" ]; then \
echo "๐ค Using credentials from .pypirc..."; \
uv publish dist/* --username "$$USERNAME" --password "$$PASSWORD"; \
else \
echo "โ Could not extract credentials from .pypirc"; \
exit 1; \
fi; \
else \
exit 1; \
fi; \
}; \
else \
echo "โ Neither twine nor uv found for publishing"; \
echo " Install with: pip install twine"; \
exit 1; \
fi
@echo "โ
Package published successfully!"
@echo "๐ Users can now run:"
@echo " uvx chuk-mcp-ios cli status"
@echo " uvx chuk-mcp-ios mcp"
# Publish to test PyPI using .pypirc
publish-test: build check-pypirc
@echo "๐ค Publishing to test PyPI using .pypirc..."
@if [ ! -d "dist" ] || [ -z "$$(ls -A dist 2>/dev/null)" ]; then \
echo "โ Error: No distribution files found. Run 'make build' first."; \
exit 1; \
fi
@echo "๐ Found distribution files:"
@ls -la dist/
@echo ""
@if command -v twine >/dev/null 2>&1; then \
echo "๐ค Using twine to publish to test PyPI..."; \
last_build=$$(ls -t dist/*.tar.gz dist/*.whl 2>/dev/null | head -n 2); \
if [ -z "$$last_build" ]; then \
echo "โ Error: No valid distribution files found."; \
exit 1; \
fi; \
echo "๐ค Uploading to test PyPI: $$last_build"; \
if grep -q '^\[testpypi\]' $$HOME/.pypirc 2>/dev/null; then \
echo "๐ Using testpypi section from .pypirc"; \
twine upload --repository testpypi $$last_build; \
else \
echo "โ ๏ธ No [testpypi] section in .pypirc, using default test PyPI"; \
twine upload --repository-url https://test.pypi.org/legacy/ $$last_build; \
fi; \
elif command -v uv >/dev/null 2>&1; then \
echo "๐ค Using uv to publish to test PyPI..."; \
uv publish --repository testpypi dist/*; \
else \
echo "โ Neither uv nor twine found for publishing"; \
echo " Install with: pip install twine"; \
exit 1; \
fi
@echo "โ
Package published to test PyPI!"
@echo "๐งช Test with:"
@echo " uvx --index-url https://test.pypi.org/simple/ chuk-mcp-ios cli status"
# Check code quality
lint:
@echo "๐ Running linters..."
@if command -v uv >/dev/null 2>&1; then \
uv run ruff check src/ examples/ tests/; \
uv run ruff format --check src/ examples/ tests/; \
elif command -v ruff >/dev/null 2>&1; then \
ruff check src/ examples/ tests/; \
ruff format --check src/ examples/ tests/; \
else \
echo "โ ๏ธ Ruff not found. Install with: pip install ruff"; \
fi
# Fix code formatting
format:
@echo "๐จ Formatting code..."
@if command -v uv >/dev/null 2>&1; then \
uv run ruff format src/ examples/ tests/; \
uv run ruff check --fix src/ examples/ tests/; \
elif command -v ruff >/dev/null 2>&1; then \
ruff format src/ examples/ tests/; \
ruff check --fix src/ examples/ tests/; \
else \
echo "โ ๏ธ Ruff not found. Install with: pip install ruff"; \
fi
# Type checking
typecheck:
@echo "๐ Running type checker..."
@if command -v uv >/dev/null 2>&1; then \
uv run mypy src/chuk_mcp_ios/; \
elif command -v mypy >/dev/null 2>&1; then \
mypy src/chuk_mcp_ios/; \
else \
echo "โ ๏ธ MyPy not found. Install with: pip install mypy"; \
fi
# Run all checks
check: lint typecheck test
@echo "โ
All checks completed."
# Check iOS development environment
check-ios:
@echo "๐ฑ Checking iOS development environment..."
@echo "Checking Xcode Command Line Tools..."
@if command -v xcrun >/dev/null 2>&1; then \
echo "โ
Xcode Command Line Tools found"; \
if xcrun simctl help >/dev/null 2>&1; then \
echo "โ
iOS Simulator tools available"; \
echo "๐ Available simulators:"; \
xcrun simctl list devices | grep -E "(iPhone|iPad)" | head -5; \
else \
echo "โ iOS Simulator tools not available"; \
fi; \
else \
echo "โ Xcode Command Line Tools not found"; \
echo "๐ก Install with: xcode-select --install"; \
fi
@echo ""
@echo "Checking optional tools..."
@if command -v idb >/dev/null 2>&1; then \
echo "โ
idb found (real device support available)"; \
else \
echo "โ ๏ธ idb not found (optional - for real device support)"; \
echo "๐ก Install with: brew install idb-companion"; \
fi
# Show project info
info:
@echo "๐ iOS Device Control MCP Server"
@echo "================================="
@if [ -f "pyproject.toml" ]; then \
echo "๐ pyproject.toml found"; \
if command -v uv >/dev/null 2>&1; then \
echo "๐ง UV version: $$(uv --version)"; \
fi; \
if command -v python >/dev/null 2>&1; then \
echo "๐ Python version: $$(python --version)"; \
fi; \
else \
echo "โ No pyproject.toml found"; \
fi
@echo "๐ Current directory: $$(pwd)"
@echo "๐ Source structure:"
@echo " src/chuk_mcp_ios/ - Main package"
@echo " examples/ - Demo scripts"
@echo " tests/ - Test suite"
@echo ""
@echo "๐ฏ Quick start:"
@echo " make setup-dev - Set up development environment"
@echo " make test-sim - Test simulator connectivity"
@echo " make run-cli-status - Check system status"
@echo " make demo - Run interactive demo"
@echo " make run-cli - Start CLI interface"
@echo " make run-mcp - Start MCP server"
@echo ""
@echo "๐ค Publishing workflow:"
@echo " make publish-check - Validate package"
@echo " make publish-test - Test on test PyPI"
@echo " make publish - Publish to PyPI"
@echo " # Then users can: uvx chuk-mcp-ios cli status"
@echo ""
@echo "๐ Git status:"
@git status --porcelain 2>/dev/null || echo "Not a git repository"
# Development shortcuts
dev: setup-dev
@echo "๐ฏ Development environment ready!"
quick-test: test-sim demo-auto
@echo "๐ Quick test complete!"
all-demos: demo-auto demo-mcp demo-news
@echo "๐ฌ All demos complete!"