folio / Makefile
dystomachina's picture
fix: attempt to fix HF deploy
7b4d241
# Makefile for folio project
# Variables
SHELL := /bin/bash
PYTHON := python3
SCRIPTS_DIR := scripts
LOGS_DIR := logs
TIMESTAMP := $(shell date +%Y%m%d_%H%M%S)
PORT := 5000
POETRY := poetry
# Default target
.PHONY: help
help:
@echo "Available targets:"
@echo " help - Show this help message"
@echo " env - Set up Poetry and create a virtual environment"
@echo " install - Install dependencies and set script permissions"
@echo " hooks - Install git hooks for pre-commit checks"
@echo " folio - Start the portfolio dashboard with debug mode enabled"
@echo " Options: portfolio=path/to/file.csv (use custom portfolio file)"
@echo " log=LEVEL (set logging level: DEBUG, INFO, WARNING, ERROR)"
@echo " focli - Start the interactive Folio CLI shell for portfolio analysis"
@echo " clean - Clean up generated files and caches"
@echo " Options: --cache (also clear data cache)"
@echo " lint - Run type checker and linter"
@echo " Options: --fix (auto-fix linting issues)"
@echo " test - Run all unit tests in the tests directory"
@echo " test-e2e - Run end-to-end tests against real portfolio data"
@echo ""
@echo "Note: All targets now use Poetry under the hood for dependency management"
@echo ""
@echo "Docker targets:"
@echo " docker-build - Build the Docker image"
@echo " docker-run - Run the Docker container"
@echo " docker-up - Start the application with docker-compose"
@echo " docker-down - Stop the docker-compose services"
@echo " docker-logs - Tail the Docker logs"
@echo " docker-test - Run tests in a Docker container"
# Set up virtual environment
.PHONY: env
env:
@echo "Setting up virtual environment with Poetry..."
@if ! command -v $(POETRY) &> /dev/null; then \
echo "Poetry not found. Installing..."; \
curl -sSL https://install.python-poetry.org | $(PYTHON) -; \
fi
@$(POETRY) config virtualenvs.in-project true
@echo "Creating Poetry virtual environment..."
@$(POETRY) env use $(PYTHON)
@echo "Virtual environment created successfully."
@echo "NOTE: To activate the virtual environment in your current shell, run: poetry shell"
@echo "The virtual environment will be automatically activated for all make commands."
# Install dependencies
.PHONY: install
install:
@echo "Installing dependencies..."
@if ! command -v $(POETRY) &> /dev/null; then \
echo "Poetry not found. Please run 'make env' first."; \
exit 1; \
fi
@mkdir -p $(LOGS_DIR)
@(echo "=== Installation Log $(TIMESTAMP) ===" && \
echo "Starting installation at: $$(date)" && \
$(POETRY) install && \
echo "Setting script permissions..." && \
chmod +x $(SCRIPTS_DIR)/*.sh && \
chmod +x $(SCRIPTS_DIR)/*.py && \
echo "Installation complete at: $$(date)") | tee $(LOGS_DIR)/install_$(TIMESTAMP).log
@echo "Installation log saved to: $(LOGS_DIR)/install_$(TIMESTAMP).log"
@echo "To install git hooks, run 'make hooks'"
# Install git hooks
.PHONY: hooks
hooks:
@echo "Installing git hooks..."
@if ! command -v $(POETRY) &> /dev/null; then \
echo "Poetry not found. Please run 'make env' first."; \
exit 1; \
fi
@$(POETRY) run pre-commit install -c .pre-commit-config.yaml --hook-type pre-commit
@$(POETRY) run pre-commit install -c .pre-push-config.yaml --hook-type pre-push
@echo "Git hooks installed successfully!"
# Clean up generated files
.PHONY: clean
clean:
@echo "Cleaning up generated files..."
@bash $(SCRIPTS_DIR)/clean.sh
@find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
@find . -type d -name ".mypy_cache" -exec rm -rf {} + 2>/dev/null || true
@find . -type d -name ".ruff_cache" -exec rm -rf {} + 2>/dev/null || true
@if [ "$(findstring --cache,$(MAKECMDGOALS))" != "" ]; then \
echo "Clearing data cache..."; \
rm -rf cache/*; \
mkdir -p cache; \
echo "Cache cleared."; \
fi
# Lint Python code
.PHONY: lint
lint:
@echo "Running linter (ruff)..."
@if ! command -v $(POETRY) &> /dev/null; then \
echo "Poetry not found. Please run 'make env' first."; \
exit 1; \
fi
@mkdir -p $(LOGS_DIR)
@(echo "=== Code Check Log $(TIMESTAMP) ===" && \
echo "Starting checks at: $$(date)" && \
$(POETRY) run ruff check --fix src/ tests/ \
2>&1) | tee $(LOGS_DIR)/code_check_latest.log
@echo "Check log saved to: $(LOGS_DIR)/code_check_latest.log"
# Allow --fix as target without actions
.PHONY: --fix
--fix:
# Portfolio and CLI Projects
.PHONY: folio stop-folio port focli
# Poetry is used under the hood for all targets
# Docker targets
.PHONY: docker-build docker-run docker-up docker-down docker-logs docker-compose-up docker-compose-down docker-test deploy-hf
folio:
@echo "Starting portfolio dashboard with debug mode..."
@if ! command -v $(POETRY) &> /dev/null; then \
echo "Poetry not found. Please run 'make env' first."; \
exit 1; \
fi
@LOG_LEVEL=$(if $(log),$(log),INFO) \
$(POETRY) run python -m src.folio.app --port 8051 --debug $(if $(portfolio),--portfolio $(portfolio),)
stop-folio:
@echo "Stopping portfolio dashboard..."
@PIDS=$$(ps aux | grep "[p]ython.*folio" | awk '{print $$2}'); \
if [ -n "$$PIDS" ]; then \
echo "Found folio processes with PIDs: $$PIDS"; \
for PID in $$PIDS; do \
echo "Killing process $$PID..."; \
kill -9 $$PID 2>/dev/null || echo "Failed to kill process $$PID (might require sudo)"; \
done; \
echo "All folio processes have been terminated."; \
else \
echo "No running folio processes found."; \
fi
focli:
@echo "Starting Folio CLI interactive shell..."
@if ! command -v $(POETRY) &> /dev/null; then \
echo "Poetry not found. Please run 'make env' first."; \
exit 1; \
fi
@$(POETRY) run python src/focli/focli.py
# Test targets
.PHONY: test test-e2e
test:
@echo "Running unit tests..."
@if ! command -v $(POETRY) &> /dev/null; then \
echo "Poetry not found. Please run 'make env' first."; \
exit 1; \
fi
@mkdir -p $(LOGS_DIR)
@(echo "=== Test Run Log $(TIMESTAMP) ===" && \
echo "Starting tests at: $$(date)" && \
$(POETRY) run pytest tests/ -v 2>&1) | tee $(LOGS_DIR)/test_latest.log
@echo "Test log saved to: $(LOGS_DIR)/test_latest.log"
test-e2e:
@echo "Running end-to-end tests..."
@if ! command -v $(POETRY) &> /dev/null; then \
echo "Poetry not found. Please run 'make env' first."; \
exit 1; \
fi
@if [ ! -f "private-data/test/test-portfolio.csv" ]; then \
echo "Warning: Test portfolio file not found at private-data/test/test-portfolio.csv"; \
echo "E2E tests will try to use sample-data/sample-portfolio.csv instead."; \
fi
@mkdir -p $(LOGS_DIR)
@(echo "=== E2E Test Run Log $(TIMESTAMP) ===" && \
echo "Starting E2E tests at: $$(date)" && \
$(POETRY) run pytest tests/e2e/ -v 2>&1) | tee $(LOGS_DIR)/test_e2e_latest.log
@echo "E2E test log saved to: $(LOGS_DIR)/test_e2e_latest.log"
# Docker commands
docker-build:
@echo "Building Docker image..."
docker build --debug -t folio:latest .
# Run the Docker container
docker-run:
@echo "Running Docker container..."
docker run -p 8050:8050 --env-file .env folio:latest
# Start with docker-compose
docker-up:
@echo "Starting with docker-compose..."
docker-compose up -d
@echo "Folio app launched successfully!"
@echo "Access the app at: http://localhost:8060"
# Stop docker-compose services
docker-down:
@echo "Stopping docker-compose services..."
docker-compose down
# Alias for backward compatibility
docker-compose-up: docker-up
docker-compose-down: docker-down
# Tail Docker logs
docker-logs:
@echo "Tailing Docker logs..."
docker-compose logs -f
# Run tests in Docker container
docker-test:
@echo "Running tests in Docker container..."
@if [ -z "$$GEMINI_API_KEY" ]; then \
echo "Warning: GEMINI_API_KEY environment variable not set. Some tests may fail."; \
fi
@docker-compose -f docker-compose.test.yml build --build-arg INSTALL_DEV=true
@docker-compose -f docker-compose.test.yml run --rm folio
# Deploy to Hugging Face Spaces
deploy-hf:
@echo "Deploying to Hugging Face Spaces..."
@echo "Checking if Hugging Face Space remote exists..."
@if ! git remote | grep -q "space"; then \
echo "Adding Hugging Face Space remote..."; \
git remote add space git@hf.co:spaces/mingdom/folio; \
fi
@echo "Pushing to Hugging Face Space..."
@git push space main:main
@echo "\n✅ Deployment to Hugging Face Space completed!"
@echo "Your application is now available at: https://huggingface.co/spaces/mingdom/folio"
%:
@: