File size: 6,991 Bytes
99f834c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# ─────────────────────────────────────────────────────────────────────────────
#  mRNA Design Studio β€” Makefile
#
#  Quick start (from scratch, no Python required):
#    make setup        # one-time: installs uv, Python 3.13, and all deps
#    make run          # start the app β†’ http://localhost:5007
# ─────────────────────────────────────────────────────────────────────────────
.PHONY: help setup run run-debug run-secure kill restart clean test lint \
        db-up db-down db-status docker-build docker-run

# ── OS detection ──────────────────────────────────────────────────────────────
# $(OS) is set to "Windows_NT" on Windows by the shell; empty on macOS/Linux.
ifeq ($(OS),Windows_NT)
    VENV_BIN := .venv/Scripts
else
    VENV_BIN := .venv/bin
endif

PYTHON  := $(VENV_BIN)/python
PORT    := 5007
URL     := http://localhost:$(PORT)
COMPOSE := docker compose -f demo/docker-compose.yml

# Where uv installs itself by default (used right after first install,
# before the user's shell has reloaded PATH).
UV_HOME := $(or $(XDG_BIN_HOME),$(HOME)/.local/bin)
UV      := $(shell command -v uv 2>/dev/null || echo "$(UV_HOME)/uv")

# ── Default target ────────────────────────────────────────────────────────────
help: ## Show available commands
	@echo ""
	@echo "  mRNA Design Studio"
	@echo "  ===================="
	@echo ""
	@echo "  First time?  Run:  make setup"
	@echo "  Then:              make run     β†’  $(URL)"
	@echo ""
	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
		awk 'BEGIN {FS = ":.*?## "}; {printf "  \033[36m%-14s\033[0m %s\n", $$1, $$2}'
	@echo ""

# ── Setup ─────────────────────────────────────────────────────────────────────
setup: _ensure-uv _ensure-venv _install-deps ## One-time setup: install Python, create venv, install deps
	@echo ""
	@echo "  Setup complete!"
	@echo "  Run 'make run' to start the app."
	@echo ""

_ensure-uv:
	@command -v uv >/dev/null 2>&1 && exit 0; \
	if [ -x "$(UV_HOME)/uv" ]; then exit 0; fi; \
	echo "Installing uv (fast Python package manager)..."; \
	curl -LsSf https://astral.sh/uv/install.sh | sh 2>/dev/null \
		|| { echo "curl failed β€” trying wget..."; \
		     wget -qO- https://astral.sh/uv/install.sh | sh; }; \
	if ! command -v uv >/dev/null 2>&1 && [ ! -x "$(UV_HOME)/uv" ]; then \
		echo ""; \
		echo "  ERROR: uv installed but not found in PATH."; \
		echo "  Restart your terminal, then re-run:  make setup"; \
		echo ""; \
		exit 1; \
	fi

_ensure-venv:
	@if [ ! -d ".venv" ]; then \
		echo "Creating virtual environment..."; \
		if command -v $(UV) >/dev/null 2>&1; then \
			$(UV) venv .venv --python 3.13; \
		else \
			python3 -m venv .venv; \
		fi; \
	fi

_install-deps:
	@echo "Installing dependencies..."
	@if command -v $(UV) >/dev/null 2>&1; then \
		$(UV) pip install -r requirements-dev.txt --python $(PYTHON) --quiet; \
	else \
		$(PYTHON) -m pip install -r requirements-dev.txt --quiet; \
	fi

# ── App ───────────────────────────────────────────────────────────────────────
run: _check-venv ## Start the app β†’ http://localhost:5007
	$(PYTHON) -m ui.app

run-secure: _check-venv ## Start with password protection (.env must exist)
	@if [ ! -f .env ]; then \
		echo ""; \
		echo "  No .env file found. Copy the template first:"; \
		echo "    cp .env.example .env"; \
		echo "  Then set MRNA_STUDIO_PASSWORD in .env"; \
		echo ""; \
		exit 1; \
	fi
	MRNA_STUDIO_RELOAD=1 $(PYTHON) -m ui.app

run-debug: _check-venv ## Start with DEBUG-level logging
	LOG_LEVEL=DEBUG $(PYTHON) -c "\
		import logging, sys, os; \
		logging.basicConfig(level=getattr(logging, os.environ.get('LOG_LEVEL','INFO')), \
			format='%(asctime)s [%(levelname)s] %(name)s: %(message)s', datefmt='%H:%M:%S', stream=sys.stderr); \
		from ui.app import main; main()"

kill: ## Stop the app if it's running
ifeq ($(OS),Windows_NT)
	@powershell -Command \
		"Get-NetTCPConnection -LocalPort $(PORT) -ErrorAction SilentlyContinue \
		 | ForEach-Object { Stop-Process -Id $$_.OwningProcess -Force }" 2>/dev/null \
		|| echo "Nothing running on port $(PORT)"
else
	@lsof -ti:$(PORT) | xargs kill -9 2>/dev/null || echo "Nothing running on port $(PORT)"
endif

restart: kill run ## Kill + restart the app

# ── Dev tools ─────────────────────────────────────────────────────────────────
test: _check-venv ## Run the test suite
	$(PYTHON) -m pytest tests/ -v

lint: _check-venv ## Lint with ruff
	$(PYTHON) -m ruff check .

clean: ## Remove the virtual environment
	rm -rf .venv
	@echo "Removed .venv β€” run 'make setup' to recreate."

# ── Database ──────────────────────────────────────────────────────────────────
db-up: ## Start the demo PostgreSQL database
	$(COMPOSE) up -d
	@echo "Waiting for PostgreSQL to be ready..."
	@until docker exec mrna_studio_demo_db pg_isready -U demo_user -d mrna_studio >/dev/null 2>&1; do sleep 1; done
	@echo "PostgreSQL is ready on localhost:5432"

db-down: ## Stop the demo database
	$(COMPOSE) down

db-status: ## Check database container status
	@docker ps --filter name=mrna_studio_demo_db --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" 2>/dev/null || echo "Container not running"

# ── Docker (production) ──────────────────────────────────────────────────────
docker-build: ## Build production Docker image
	docker build -t mrna-studio .

docker-run: ## Run container with .env file (password-protected)
	docker run --rm -p 5007:5007 --env-file .env mrna-studio

# ── Internal helpers ──────────────────────────────────────────────────────────
_check-venv:
	@if [ ! -d ".venv" ]; then \
		echo ""; \
		echo "  No virtual environment found."; \
		echo "  Run 'make setup' first."; \
		echo ""; \
		exit 1; \
	fi