From 359ce583d0bcbc5c70a6513480f222d54357f239 Mon Sep 17 00:00:00 2001 From: John Lago <750845+Lagoja@users.noreply.github.com> Date: Mon, 9 Sep 2024 15:01:45 -0700 Subject: [PATCH 1/6] Change venv dir, tweak detection logic --- plugins/pip/venvShellHook.sh | 73 +++++++++++++++++++++++++++++++++--- plugins/python.json | 16 +++----- 2 files changed, 73 insertions(+), 16 deletions(-) diff --git a/plugins/pip/venvShellHook.sh b/plugins/pip/venvShellHook.sh index 40cc09b5bfb..b17adcd9312 100755 --- a/plugins/pip/venvShellHook.sh +++ b/plugins/pip/venvShellHook.sh @@ -1,8 +1,71 @@ -#!/bin/sh +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" ] +} + +# Function to check if Python is a symlink to a Devbox Python +is_devbox_python() { + if [ -z "$DEVBOX_PACKAGES_DIR" ]; then + echo "DEVBOX_PACKAGES_DIR is not set. Unable to check for Devbox Python." + return 1 + fi + local python_path=$(readlink "$1/bin/python") + echo $python_path + echo $DEVBOX_PACKAGES_DIR + [[ $python_path == $DEVBOX_PACKAGES_DIR/bin/python* ]] +} + +# Function to check Python version +check_python_version() { + python_version=$(python -c 'import sys; print(".".join(map(str, sys.version_info[:2])))') + if [ "$(printf '%s\n' "3.3" "$python_version" | sort -V | head -n1)" = "3.3" ]; then + return 0 + else + return 1 + fi +} + +# Check if we've already run this script +if [ -f "$STATE_FILE" ]; then + exit 0 fi +# Check Python version +if ! check_python_version; then + echo "\n\033[1;33m========================================\033[0m" + echo "\033[1;33mWARNING: Python version must be > 3.3 to create a virtual environment.\033[0m" + echo "\033[1;33m========================================\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_python "$VENV_DIR"; then + echo "\n\033[1;33m========================================\033[0m" + echo "\033[1;33mWARNING: Existing virtual environment doesn't use Devbox Python.\033[0m" + echo "\033[1;33m========================================\033[0m" + echo "Virtual environment: $VENV_DIR" + read -p "Do you want to overwrite it? (y/n) " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + echo "Overwriting existing virtual environment..." + rm -rf "$VENV_DIR" + python3 -m venv "$VENV_DIR" + else + echo "Operation cancelled." + touch "$STATE_FILE" + exit 1 + fi + fi + else + echo "Directory exists but is not a valid virtual environment. Creating new one..." + rm -rf "$VENV_DIR" + python -m venv "$VENV_DIR" + fi +else + echo "Virtual environment directory doesn't exist. Creating new one..." + python -m venv "$VENV_DIR" +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"] } } From 9411c3d612d4f5af88e5e9dcc687aab5ca4a2904 Mon Sep 17 00:00:00 2001 From: John Lago <750845+Lagoja@users.noreply.github.com> Date: Mon, 9 Sep 2024 16:34:08 -0700 Subject: [PATCH 2/6] Improve Script --- plugins/pip/venvShellHook.sh | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/plugins/pip/venvShellHook.sh b/plugins/pip/venvShellHook.sh index b17adcd9312..88a452943ac 100755 --- a/plugins/pip/venvShellHook.sh +++ b/plugins/pip/venvShellHook.sh @@ -1,4 +1,5 @@ STATE_FILE="$DEVBOX_PROJECT_ROOT/.devbox/venv_check_completed" +echo $STATE_FILE is_valid_venv() { [ -f "$1/bin/activate" ] && [ -f "$1/bin/python" ] @@ -10,10 +11,31 @@ is_devbox_python() { echo "DEVBOX_PACKAGES_DIR is not set. Unable to check for Devbox Python." return 1 fi - local python_path=$(readlink "$1/bin/python") - echo $python_path - echo $DEVBOX_PACKAGES_DIR - [[ $python_path == $DEVBOX_PACKAGES_DIR/bin/python* ]] + local python_path="$1/bin/python" + local link_target + + while true; do + if [ ! -L "$python_path" ]; then + echo $python_path + # Not a symlink, we're done + break + fi + + link_target=$(readlink "$python_path") + echo "Checking symlink: $link_target" + + if [[ "$link_target" == /* ]]; then + # Absolute path, we're done + python_path="$link_target" + break + elif [[ "$link_target" == python* ]] || [[ "$link_target" == ./* ]] || [[ "$link_target" == ../* ]]; then + # Relative path or python symlink, continue resolving + python_path=$(dirname "$python_path")/"$link_target" + else + # Unexpected format, stop here + break + fi + done } # Function to check Python version From 796706e7f6a797fb770bb951fea5809c99ad16e6 Mon Sep 17 00:00:00 2001 From: John Lago <750845+Lagoja@users.noreply.github.com> Date: Tue, 10 Sep 2024 08:57:45 -0700 Subject: [PATCH 3/6] cleanup script --- plugins/pip/venvShellHook.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/plugins/pip/venvShellHook.sh b/plugins/pip/venvShellHook.sh index 88a452943ac..81e9ec5e064 100755 --- a/plugins/pip/venvShellHook.sh +++ b/plugins/pip/venvShellHook.sh @@ -1,3 +1,4 @@ +set -eu STATE_FILE="$DEVBOX_PROJECT_ROOT/.devbox/venv_check_completed" echo $STATE_FILE @@ -16,7 +17,6 @@ is_devbox_python() { while true; do if [ ! -L "$python_path" ]; then - echo $python_path # Not a symlink, we're done break fi @@ -36,6 +36,8 @@ is_devbox_python() { break fi done + + [[ $python_path == $DEVBOX_PACKAGES_DIR/* ]] } # Function to check Python version @@ -50,14 +52,13 @@ check_python_version() { # Check if we've already run this script if [ -f "$STATE_FILE" ]; then + # "We've already run this script. Exiting..." exit 0 fi # Check Python version if ! check_python_version; then - echo "\n\033[1;33m========================================\033[0m" echo "\033[1;33mWARNING: Python version must be > 3.3 to create a virtual environment.\033[0m" - echo "\033[1;33m========================================\033[0m" touch "$STATE_FILE" exit 1 fi @@ -66,9 +67,7 @@ fi if [ -d "$VENV_DIR" ]; then if is_valid_venv "$VENV_DIR"; then if ! is_devbox_python "$VENV_DIR"; then - echo "\n\033[1;33m========================================\033[0m" - echo "\033[1;33mWARNING: Existing virtual environment doesn't use Devbox Python.\033[0m" - echo "\033[1;33m========================================\033[0m" + echo "\033[1;33mWARNING: Virtual environment at $VENV_DIR doesn't use Devbox Python.\033[0m" echo "Virtual environment: $VENV_DIR" read -p "Do you want to overwrite it? (y/n) " -n 1 -r echo @@ -77,7 +76,7 @@ if [ -d "$VENV_DIR" ]; then rm -rf "$VENV_DIR" python3 -m venv "$VENV_DIR" else - echo "Operation cancelled." + echo "Using existing virtual environment. We recommend changing \$VENV_DIR" touch "$STATE_FILE" exit 1 fi From 1daaef4946dd7d041c152fb00f4bc12274e98a8f Mon Sep 17 00:00:00 2001 From: John Lago <750845+Lagoja@users.noreply.github.com> Date: Tue, 10 Sep 2024 11:46:20 -0700 Subject: [PATCH 4/6] cleanup, add gitignore --- plugins/pip/venvShellHook.sh | 66 ++++++++---------------------------- 1 file changed, 14 insertions(+), 52 deletions(-) diff --git a/plugins/pip/venvShellHook.sh b/plugins/pip/venvShellHook.sh index 81e9ec5e064..a76d524193c 100755 --- a/plugins/pip/venvShellHook.sh +++ b/plugins/pip/venvShellHook.sh @@ -1,53 +1,18 @@ +#!/bin/sh set -eu STATE_FILE="$DEVBOX_PROJECT_ROOT/.devbox/venv_check_completed" -echo $STATE_FILE is_valid_venv() { [ -f "$1/bin/activate" ] && [ -f "$1/bin/python" ] } -# Function to check if Python is a symlink to a Devbox Python -is_devbox_python() { - if [ -z "$DEVBOX_PACKAGES_DIR" ]; then - echo "DEVBOX_PACKAGES_DIR is not set. Unable to check for Devbox Python." - return 1 - fi - local python_path="$1/bin/python" - local link_target - - while true; do - if [ ! -L "$python_path" ]; then - # Not a symlink, we're done - break - fi - - link_target=$(readlink "$python_path") - echo "Checking symlink: $link_target" - - if [[ "$link_target" == /* ]]; then - # Absolute path, we're done - python_path="$link_target" - break - elif [[ "$link_target" == python* ]] || [[ "$link_target" == ./* ]] || [[ "$link_target" == ../* ]]; then - # Relative path or python symlink, continue resolving - python_path=$(dirname "$python_path")/"$link_target" - else - # Unexpected format, stop here - break - fi - done - - [[ $python_path == $DEVBOX_PACKAGES_DIR/* ]] +is_devbox_venv() { + [ "$1/bin/python" -ef "$DEVBOX_PACKAGES_DIR/bin/python" ] } -# Function to check Python version -check_python_version() { - python_version=$(python -c 'import sys; print(".".join(map(str, sys.version_info[:2])))') - if [ "$(printf '%s\n' "3.3" "$python_version" | sort -V | head -n1)" = "3.3" ]; then - return 0 - else - return 1 - fi +create_venv() { + python -m venv "$VENV_DIR" --clear + echo "*\n.*" >> "$VENV_DIR/.gitignore" } # Check if we've already run this script @@ -56,8 +21,8 @@ if [ -f "$STATE_FILE" ]; then exit 0 fi -# Check Python version -if ! check_python_version; then +# Check that Python version suports venv +if ! python -c "import venv" &>/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 @@ -66,27 +31,24 @@ fi # Check if the directory exists if [ -d "$VENV_DIR" ]; then if is_valid_venv "$VENV_DIR"; then - if ! is_devbox_python "$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" - echo "Virtual environment: $VENV_DIR" read -p "Do you want to overwrite it? (y/n) " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then echo "Overwriting existing virtual environment..." - rm -rf "$VENV_DIR" - python3 -m venv "$VENV_DIR" + create_venv else - echo "Using existing virtual environment. We recommend changing \$VENV_DIR" + 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 new one..." - rm -rf "$VENV_DIR" - python -m venv "$VENV_DIR" + 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..." - python -m venv "$VENV_DIR" + create_venv fi From 3e248ae1807614a33cdb5aa44cefe500d0b7265e Mon Sep 17 00:00:00 2001 From: John Lago <750845+Lagoja@users.noreply.github.com> Date: Tue, 10 Sep 2024 12:54:00 -0700 Subject: [PATCH 5/6] fix typo --- plugins/pip/venvShellHook.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/pip/venvShellHook.sh b/plugins/pip/venvShellHook.sh index a76d524193c..c650b458e77 100755 --- a/plugins/pip/venvShellHook.sh +++ b/plugins/pip/venvShellHook.sh @@ -21,7 +21,7 @@ if [ -f "$STATE_FILE" ]; then exit 0 fi -# Check that Python version suports venv +# Check that Python version supports venv if ! python -c "import venv" &>/dev/null; then echo "\033[1;33mWARNING: Python version must be > 3.3 to create a virtual environment.\033[0m" touch "$STATE_FILE" From 7910c41a768ef28c073bd562f7f32a13f0f003b1 Mon Sep 17 00:00:00 2001 From: John Lago <> Date: Tue, 10 Sep 2024 21:28:00 +0000 Subject: [PATCH 6/6] Fix test somehow --- plugins/pip/venvShellHook.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/pip/venvShellHook.sh b/plugins/pip/venvShellHook.sh index c650b458e77..bb2341be662 100755 --- a/plugins/pip/venvShellHook.sh +++ b/plugins/pip/venvShellHook.sh @@ -22,7 +22,7 @@ if [ -f "$STATE_FILE" ]; then fi # Check that Python version supports venv -if ! python -c "import venv" &>/dev/null; then +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