195 lines
6.1 KiB
Makefile
195 lines
6.1 KiB
Makefile
# List of phony targets (targets that don't represent files)
|
|
.PHONY: all clean venv run format format-check lint mypy test dist reformat dev celery celery-flower redis run-all
|
|
|
|
# Define Python and pip executables inside virtual environment
|
|
PYTHON := venv/bin/python
|
|
PIP := venv/bin/pip
|
|
CELERY := venv/bin/celery
|
|
FLASK := venv/bin/flask
|
|
|
|
# Default target that runs the application
|
|
all: run
|
|
|
|
# Remove all generated files and directories
|
|
clean:
|
|
rm -rf venv build dist .pytest_cache .mypy_cache *.egg-info
|
|
|
|
# Define database path
|
|
DB_PATH=scipaperloader/papers.db
|
|
|
|
# Backup the database with timestamp
|
|
backup-db:
|
|
@mkdir -p backups
|
|
@timestamp=$$(date +%Y%m%d_%H%M%S); \
|
|
cp $(DB_PATH) backups/papers_$$timestamp.db && \
|
|
echo "Database backed up to backups/papers_$$timestamp.db"
|
|
|
|
# Create sample test data for development and testing
|
|
sample-data: venv
|
|
$(PYTHON) scipaperloader/scripts/create_sample_data.py
|
|
|
|
# Export database as SQL script with timestamp
|
|
export-db: venv
|
|
@mkdir -p exports
|
|
@timestamp=$$(date +%Y%m%d_%H%M%S); \
|
|
$(PYTHON) -c "import sqlite3; conn = sqlite3.connect('$(DB_PATH)'); with open('exports/papers_$$timestamp.sql', 'w') as f: f.write(''.join(conn.iterdump()));" && \
|
|
echo "Database exported to exports/papers_$$timestamp.sql"
|
|
|
|
# Run the application with production settings
|
|
run-prod: venv
|
|
FLASK_ENV=production venv/bin/flask --app scipaperloader run --host=0.0.0.0
|
|
|
|
# Check for security vulnerabilities in dependencies
|
|
security-check: venv
|
|
$(PIP) install safety
|
|
venv/bin/safety check
|
|
|
|
# Create a new database migration with provided message
|
|
db-migrate: venv
|
|
venv/bin/flask --app scipaperloader db migrate -m "$(message)"
|
|
|
|
# Apply pending database migrations
|
|
db-upgrade: venv
|
|
venv/bin/flask --app scipaperloader db upgrade
|
|
|
|
# Revert the last database migration
|
|
db-downgrade: venv
|
|
venv/bin/flask --app scipaperloader db downgrade
|
|
|
|
# Generate API documentation using Sphinx
|
|
docs: venv
|
|
$(PIP) install sphinx sphinx_rtd_theme
|
|
cd docs && venv/bin/sphinx-build -b html source build
|
|
|
|
# Create a code coverage report for the test suite
|
|
coverage: venv
|
|
$(PYTHON) -m pytest --cov=scipaperloader --cov-report=html
|
|
@echo "Coverage report generated in htmlcov/"
|
|
|
|
# Generate a requirements.txt file from current environment
|
|
requirements: venv
|
|
$(PIP) freeze > requirements.txt
|
|
@echo "Requirements file updated"
|
|
|
|
# Show project statistics (code lines, routes, database size)
|
|
stats:
|
|
@echo "Lines of Python code:"
|
|
@find scipaperloader -name "*.py" | xargs wc -l | sort -nr
|
|
@echo "Number of routes:"
|
|
@grep -r "@bp.route" scipaperloader | wc -l
|
|
@echo "Database file size:"
|
|
@du -h $(DB_PATH) 2>/dev/null || echo "Database file not found"
|
|
|
|
# Show TODOs and FIXMEs in code
|
|
todos:
|
|
@grep -r "TODO\|FIXME" scipaperloader || echo "No TODOs found"
|
|
|
|
# Reset the database: delete, initialize, and migrate
|
|
reset-db: venv
|
|
rm -f $(DB_PATH)
|
|
$(PYTHON) -m flask --app scipaperloader db init || true
|
|
$(PYTHON) -m flask --app scipaperloader db migrate -m "Initial migration"
|
|
$(PYTHON) -m flask --app scipaperloader db upgrade
|
|
|
|
# Create and set up virtual environment
|
|
venv:
|
|
python3 -m venv venv && \
|
|
$(PIP) install --upgrade pip setuptools && \
|
|
$(PIP) install --editable ".[dev]"
|
|
|
|
# Run the application in debug mode
|
|
run: venv
|
|
$(FLASK) --app scipaperloader --debug run
|
|
|
|
# Format code using Black and isort
|
|
format: venv
|
|
venv/bin/black .
|
|
venv/bin/isort .
|
|
|
|
# Check if code meets formatting standards
|
|
format-check: venv
|
|
venv/bin/black --check .
|
|
venv/bin/isort --check .
|
|
|
|
# Reformat and lint code
|
|
reformat: format lint
|
|
|
|
# Check code for style issues using flake8
|
|
lint: venv
|
|
venv/bin/flake8 .
|
|
|
|
# Run static type checking with mypy
|
|
mypy: venv
|
|
venv/bin/mypy scipaperloader
|
|
|
|
# Run the test suite
|
|
test: venv
|
|
venv/bin/pytest
|
|
|
|
# Build distribution package after running checks
|
|
dist: format-check lint mypy test
|
|
$(PIP) wheel --wheel-dir dist --no-deps .
|
|
|
|
# Set up complete development environment
|
|
dev: clean venv
|
|
|
|
# Start Celery worker - PURGE FIRST
|
|
celery: venv redis
|
|
@echo "Purging Celery task queue before starting worker..."
|
|
# Purge the queue forcefully. Ignore errors if queue is empty/unreachable initially.
|
|
@-$(CELERY) -A celery_worker:celery purge -f
|
|
@echo "Starting Celery worker..."
|
|
$(CELERY) -A celery_worker:celery worker --loglevel=info
|
|
|
|
# Monitor Celery tasks with flower web interface
|
|
celery-flower: venv
|
|
$(PIP) install flower
|
|
$(CELERY) -A celery_worker:celery flower --port=5555
|
|
|
|
# Run Celery beat scheduler for periodic tasks
|
|
celery-beat: venv redis
|
|
@echo "Starting Celery beat scheduler..."
|
|
# Ensure celerybeat-schedule file is removed for clean start if needed
|
|
@-rm -f celerybeat-schedule.db
|
|
# Use the default file-based scheduler (removed the --scheduler flag)
|
|
$(CELERY) -A celery_worker:celery beat --loglevel=info
|
|
|
|
# Check if Redis is running, start if needed
|
|
redis:
|
|
@if ! redis-cli ping > /dev/null 2>&1; then \
|
|
echo "Starting Redis server..."; \
|
|
redis-server --daemonize yes; \
|
|
sleep 1; \
|
|
else \
|
|
echo "Redis is already running."; \
|
|
fi
|
|
|
|
# Run complete application stack (Flask app + Celery worker + Redis + Beat scheduler)
|
|
run-all: redis
|
|
@echo "Starting Flask, Celery worker and Beat scheduler..."
|
|
# Run them in parallel. Ctrl+C will send SIGINT to make, which propagates.
|
|
# Use trap to attempt cleanup, but primary cleanup is purge on next start.
|
|
@trap '$(MAKE) stop-all;' INT TERM; \
|
|
$(MAKE) -j3 run celery celery-beat & wait
|
|
|
|
# Stop running Celery worker and beat gracefully
|
|
stop-celery:
|
|
@echo "Attempting graceful shutdown of Celery worker and beat..."
|
|
@-pkill -TERM -f "celery -A celery_worker:celery worker" || echo "Worker not found or already stopped."
|
|
@-pkill -TERM -f "celery -A celery_worker:celery beat" || echo "Beat not found or already stopped."
|
|
@sleep 1 # Give processes a moment to terminate
|
|
@echo "Purging remaining tasks from Celery queue..."
|
|
@-$(CELERY) -A celery_worker:celery purge -f || echo "Purge failed or queue empty."
|
|
|
|
# Stop Flask development server
|
|
stop-flask:
|
|
@echo "Attempting shutdown of Flask development server..."
|
|
@-pkill -TERM -f "flask --app scipaperloader --debug run" || echo "Flask server not found or already stopped."
|
|
|
|
# Stop all components potentially started by run-all
|
|
stop-all: stop-celery stop-flask
|
|
@echo "All components stopped."
|
|
|
|
# Default target
|
|
all: run
|