From 6df893aad7550c191d876f6edb94df93a61d2adb Mon Sep 17 00:00:00 2001 From: John Lago <750845+Lagoja@users.noreply.github.com> Date: Wed, 11 Sep 2024 10:23:54 -0700 Subject: [PATCH] [Python] Change `.venv` script to be more compatible with IDEs (#2259) ## Summary Moves `.venv` to the Devbox Project Root, and adds some checks to ensure we warn the user if we are going to squash a user created venv. Moving `.venv` to the project root makes it more likely that Python Extensions and IDEs will pick up the devbox managed python, instead of a system python Fixes DEV-105 ## How was it tested? --------- Co-authored-by: John Lago <> --- plugins/pip/venvShellHook.sh | 54 +++++++++++++++++++++++++++++++++--- plugins/python.json | 16 ++++------- 2 files changed, 55 insertions(+), 15 deletions(-) diff --git a/plugins/pip/venvShellHook.sh b/plugins/pip/venvShellHook.sh index 40cc09b5bfb..bb2341be662 100755 --- a/plugins/pip/venvShellHook.sh +++ b/plugins/pip/venvShellHook.sh @@ -1,8 +1,54 @@ #!/bin/sh +set -eu +STATE_FILE="$DEVBOX_PROJECT_ROOT/.devbox/venv_check_completed" -if ! [ -d "$VENV_DIR" ]; then - echo "Creating new venv environment in path: '${VENV_DIR}'" - python3 -m venv "$VENV_DIR" - echo "You can activate the virtual environment by running '. \$VENV_DIR/bin/activate' (for fish shell, replace '.' with 'source')" >&2 +is_valid_venv() { + [ -f "$1/bin/activate" ] && [ -f "$1/bin/python" ] +} + +is_devbox_venv() { + [ "$1/bin/python" -ef "$DEVBOX_PACKAGES_DIR/bin/python" ] +} + +create_venv() { + python -m venv "$VENV_DIR" --clear + echo "*\n.*" >> "$VENV_DIR/.gitignore" +} + +# Check if we've already run this script +if [ -f "$STATE_FILE" ]; then + # "We've already run this script. Exiting..." + exit 0 fi +# Check that Python version supports venv +if ! python -c 'import venv' 1> /dev/null 2> /dev/null; then + echo "\033[1;33mWARNING: Python version must be > 3.3 to create a virtual environment.\033[0m" + touch "$STATE_FILE" + exit 1 +fi + +# Check if the directory exists +if [ -d "$VENV_DIR" ]; then + if is_valid_venv "$VENV_DIR"; then + if ! is_devbox_venv "$VENV_DIR"; then + echo "\033[1;33mWARNING: Virtual environment at $VENV_DIR doesn't use Devbox Python.\033[0m" + read -p "Do you want to overwrite it? (y/n) " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + echo "Overwriting existing virtual environment..." + create_venv + else + echo "Using your existing virtual environment. We recommend changing \$VENV_DIR to a different location" + touch "$STATE_FILE" + exit 1 + fi + fi + else + echo "Directory exists but is not a valid virtual environment. Creating a new one..." + create_venv + fi +else + echo "Virtual environment directory doesn't exist. Creating new one..." + create_venv +fi diff --git a/plugins/python.json b/plugins/python.json index 3f04299e2ba..1532ca5c211 100644 --- a/plugins/python.json +++ b/plugins/python.json @@ -1,20 +1,14 @@ { "name": "python", - "version": "0.0.3", - "description": "Python in Devbox works best when used with a virtual environment (vent, virtualenv, etc.). Devbox will automatically create a virtual environment using `venv` for python3 projects, so you can install packages with pip as normal.\nTo activate the environment, run `. $VENV_DIR/bin/activate` or add it to the init_hook of your devbox.json\nTo change where your virtual environment is created, modify the $VENV_DIR environment variable in your init_hook", + "version": "0.0.4", + "description": "Python in Devbox works best when used with a virtual environment (venv, virtualenv, etc.). Devbox will automatically create a virtual environment using `venv` for python3 projects, so you can install packages with pip as normal.\nTo activate the environment, run `. $VENV_DIR/bin/activate` or add it to the init_hook of your devbox.json\nTo change where your virtual environment is created, modify the $VENV_DIR environment variable in your init_hook", "env": { - /* - This is a block comment - */ - "VENV_DIR": "{{ .Virtenv }}/.venv" + "VENV_DIR": "{{ .DevboxProjectDir }}/.venv" }, "create_files": { - "{{ .Virtenv }}/bin/venvShellHook.sh": "pip/venvShellHook.sh" + "{{ .Virtenv }}/bin/venvShellHook.sh": "pip/venvShellHook.sh" }, - // this is a line comment above shell "shell": { - "init_hook": [ - "{{ .Virtenv }}/bin/venvShellHook.sh" - ] + "init_hook": ["{{ .Virtenv }}/bin/venvShellHook.sh"] } }