@@ -6,6 +6,17 @@ GREEN := \033[0;32m
66YELLOW := \033[1;33m
77NC := \033[0m # No Color
88
9+ # Virtual environment configuration
10+ VENV_DIR := .venv
11+ # Use the venv python/pip if the venv exists, otherwise fall back to system
12+ ifeq ($(wildcard $(VENV_DIR ) /bin/python) ,)
13+ PYTHON := $(shell command -v python3 2>/dev/null || pyenv which python 2>/dev/null || echo python)
14+ PIP := $(shell command -v pip3 2>/dev/null || echo pip)
15+ else
16+ PYTHON := $(CURDIR ) /$(VENV_DIR ) /bin/python
17+ PIP := $(CURDIR ) /$(VENV_DIR ) /bin/pip
18+ endif
19+
920# Update version across all packages
1021# Usage: make version V=0.6.0
1122.PHONY : version
@@ -33,17 +44,33 @@ endif
3344# Default target - run both lint and test
3445all : lint test
3546
36- # Install idp_common, idp-cli, and idp_sdk packages in development mode
47+ # Create virtual environment and install all packages in development mode
3748setup :
38- @echo " Installing idp_common package..."
39- pip install -e lib/idp_common_pkg
49+ @echo " Creating virtual environment in $( VENV_DIR) ..."
50+ @PYENV_PYTHON=$$(pyenv which python 2>/dev/null ) ; \
51+ SYS_PYTHON=$$(command -v python3 2>/dev/null ) ; \
52+ BASE_PYTHON=$$ {PYENV_PYTHON:-$$ SYS_PYTHON}; \
53+ if [ -z " $$ BASE_PYTHON" ]; then \
54+ echo -e " $( RED) ERROR: No python3 or pyenv python found. Install Python 3.12+ first.$( NC) " ; \
55+ exit 1; \
56+ fi ; \
57+ echo " Using base Python: $$ BASE_PYTHON ($$ ($$ BASE_PYTHON --version))" ; \
58+ $$ BASE_PYTHON -m venv $(VENV_DIR )
59+ @echo " Upgrading pip..."
60+ $(VENV_DIR ) /bin/pip install --upgrade pip
61+ @echo " Installing idp_common package with all dependencies (including test)..."
62+ $(VENV_DIR ) /bin/pip install -e " lib/idp_common_pkg[all,dev,test]"
4063 @echo " Installing idp-cli package..."
41- pip install -e lib/idp_cli_pkg
64+ $( VENV_DIR ) /bin/ pip install -e lib/idp_cli_pkg
4265 @echo " Installing idp_sdk package..."
43- pip install -e lib/idp_sdk
66+ $( VENV_DIR ) /bin/ pip install -e lib/idp_sdk
4467 @echo " Installing capacity planning test dependencies..."
45- pip install -r src/lambda/calculate_capacity/requirements-test.txt
46- @echo -e " $( GREEN) ✅ Setup complete! idp_common, idp-cli, idp_sdk, and test dependencies are now installed.$( NC) "
68+ $(VENV_DIR ) /bin/pip install -r src/lambda/calculate_capacity/requirements-test.txt
69+ @echo " "
70+ @echo -e " $( GREEN) ✅ Setup complete! Virtual environment created at $( VENV_DIR) $( NC) "
71+ @echo -e " $( GREEN) idp_common, idp-cli, idp_sdk, and test dependencies are now installed.$( NC) "
72+ @echo -e " $( YELLOW) All 'make' targets will automatically use $( VENV_DIR) /bin/python.$( NC) "
73+ @echo -e " $( YELLOW) To activate manually: source $( VENV_DIR) /bin/activate$( NC) "
4774
4875# Start the UI development server
4976# Usage: make ui-start [STACK_NAME=<stack-name>]
@@ -75,34 +102,34 @@ ui-start:
75102
76103# Run tests in idp_common_pkg, idp_cli, idp_sdk, capacity planning Lambda, and config library
77104test :
78- $(MAKE ) -C lib/idp_common_pkg test
79- cd lib/idp_cli_pkg && python -m pytest -v
80- cd lib/idp_sdk && python -m pytest -m " not integration" -v
105+ $(MAKE ) -C lib/idp_common_pkg test PYTHON= $( PYTHON )
106+ cd lib/idp_cli_pkg && $( PYTHON ) -m pytest -v
107+ cd lib/idp_sdk && $( PYTHON ) -m pytest -m " not integration" -v
81108 @echo " Running capacity planning Lambda tests..."
82- cd src/lambda/calculate_capacity && python -m pytest -v
109+ cd src/lambda/calculate_capacity && $( PYTHON ) -m pytest -v
83110 @echo " Validating config library files..."
84- python -m pytest config_library/test_config_library.py -v
111+ $( PYTHON ) -m pytest config_library/test_config_library.py -v
85112
86113# Run only config library validation tests
87114test-config-library :
88115 @echo " Validating config library YAML/JSON files..."
89- python -m pytest config_library/test_config_library.py -v
116+ $( PYTHON ) -m pytest config_library/test_config_library.py -v
90117
91118# Run only IDP CLI tests
92119test-cli :
93120 @echo " Running IDP CLI tests..."
94- cd lib/idp_cli_pkg && python -m pytest -v
121+ cd lib/idp_cli_pkg && $( PYTHON ) -m pytest -v
95122 @echo -e " $( GREEN) ✅ All CLI tests passed!$( NC) "
96123
97124# Run only capacity planning tests
98125test-capacity :
99126 @echo " Running capacity planning Lambda tests..."
100- cd src/lambda/calculate_capacity && python -m pytest -v
127+ cd src/lambda/calculate_capacity && $( PYTHON ) -m pytest -v
101128
102129# Run capacity planning tests with coverage
103130test-capacity-coverage :
104131 @echo " Running capacity planning Lambda tests with coverage..."
105- cd src/lambda/calculate_capacity && python -m pytest --cov=. --cov-report=term --cov-report=html -v
132+ cd src/lambda/calculate_capacity && $( PYTHON ) -m pytest --cov=. --cov-report=term --cov-report=html -v
106133 @echo -e " $( GREEN) ✅ Coverage report generated at src/lambda/calculate_capacity/htmlcov/index.html$( NC) "
107134
108135# Run both linting and formatting in one command
@@ -153,7 +180,7 @@ lint-cicd:
153180# Validate AWS CodeBuild buildspec files
154181validate-buildspec :
155182 @echo " Validating buildspec files..."
156- @python3 scripts/sdlc/validate_buildspec.py patterns/* /buildspec.yml || \
183+ @$( PYTHON ) scripts/sdlc/validate_buildspec.py patterns/* /buildspec.yml || \
157184 (echo -e " $( RED) ERROR: Buildspec validation failed!$( NC) " && exit 1)
158185 @echo -e " $( GREEN) ✅ All buildspec files are valid!$( NC) "
159186
@@ -203,12 +230,12 @@ typecheck-stats:
203230TARGET_BRANCH ?= main
204231typecheck-pr :
205232 @echo " Type checking changed files against $( TARGET_BRANCH) ..."
206- python3 scripts/sdlc/typecheck_pr_changes.py $(TARGET_BRANCH )
233+ $( PYTHON ) scripts/sdlc/typecheck_pr_changes.py $(TARGET_BRANCH )
207234
208235
209236ui-lint :
210237 @echo " Checking if UI lint is needed..."
211- @CURRENT_HASH=$$(python3 -c "from publish import IDPPublisher; p = IDPPublisher( ) ; print(p.get_directory_checksum(' src/ui' ))" ); \
238+ @CURRENT_HASH=$$($( PYTHON ) -c "from publish import IDPPublisher; p = IDPPublisher() ; print(p.get_directory_checksum(' src/ui' ))" ); \
212239 STORED_HASH=$$(test -f src/ui/.checksum && cat src/ui/.checksum || echo "" ) ; \
213240 if [ " $$ CURRENT_HASH" != " $$ STORED_HASH" ]; then \
214241 echo " UI code checksum changed - running lint..." ; \
@@ -290,21 +317,21 @@ docs-deploy: docs-build
290317# Fetches all AWS standard blueprints and converts them to IDP class schemas
291318classes-from-bda :
292319 @echo " Generating standard class catalog from BDA standard blueprints..."
293- python3 scripts/generate_standard_classes.py --region us-east-1 --output src/ui/src/data/standard-classes.json
320+ $( PYTHON ) scripts/generate_standard_classes.py --region us-east-1 --output src/ui/src/data/standard-classes.json
294321 @echo -e " $( GREEN) ✅ Standard class catalog updated! Review changes in src/ui/src/data/standard-classes.json$( NC) "
295322
296323# DSR (Deliverable Security Review) targets
297324dsr-setup :
298325 @echo " Setting up DSR tool..."
299- python3 scripts/dsr/setup.py
326+ $( PYTHON ) scripts/dsr/setup.py
300327
301328dsr-scan :
302329 @echo " Running DSR security scan..."
303- python3 scripts/dsr/run.py
330+ $( PYTHON ) scripts/dsr/run.py
304331
305332dsr-fix :
306333 @echo " Running DSR interactive fix..."
307- python3 scripts/dsr/fix.py
334+ $( PYTHON ) scripts/dsr/fix.py
308335
309336dsr :
310337 @if [ ! -f .dsr/dsr ]; then \
0 commit comments