98f9f0ed07ec7b8d445ed824ffaced1169df7ebc

Author
Michael Aquilina <michaelaquilina@gmail.com>
Committer
Michael Aquilina <michaelaquilina@gmail.com>
Date

Message

Improved integration of pipenv and poetry

Diff

This diff is truncated to protect this page.

  1diff --git a/autoswitch_virtualenv.plugin.zsh b/autoswitch_virtualenv.plugin.zsh
  2index 4f5e1f174b29529cf69bf9a3410db152cd7e4756..3fbd0a21477956e53d68e2b1703f4e5a6e6a5fcc 100644
  3--- a/autoswitch_virtualenv.plugin.zsh
  4+++ b/autoswitch_virtualenv.plugin.zsh
  5@@ -47,17 +47,16 @@ function _autoswitch_message() {
  6     fi
  7 }
  8 
  9+
 10 function _get_venv_type() {
 11     local venv_dir="$1"
 12     local venv_type="${2:-virtualenv}"
 13     if [[ -f "$venv_dir/Pipfile" ]]; then
 14         venv_type="pipenv"
 15+    elif [[ -f "$venv_dir/poetry.lock" ]]; then
 16+        venv_type="poetry"
 17     elif [[ -f "$venv_dir/requirements.txt" || -f "$venv_dir/setup.py" ]]; then
 18         venv_type="virtualenv"
 19-    # TODO: this is not technically correct as lots of tools use pyproject.toml
 20-    # however it's probably a good enough approximation for this function
 21-    elif [[ -f "$venv_dir/pyproject.toml" ]]; then
 22-        venv_type="poetry"
 23     fi
 24     printf "%s" "$venv_type"
 25 }
 26@@ -137,6 +136,34 @@ function _check_path()
 27 }
 28 
 29 
 30+function _activate_poetry() {
 31+    # check if any environments exist before trying to activate
 32+    # if env list is empty, then no environment exists that can be activated
 33+    if [[ -n "$(poetry env list)" ]]; then
 34+        # we need to infer the target virtualenv directory based on poetry's data
 35+        # to easiest way is to actually get the location of the python binary and
 36+        # infer the location of the virtualenv from there.
 37+        if poetry_python=$(poetry run which python); then
 38+            if venv_path="$(dirname $(dirname $poetry_python))"; then
 39+                _maybeworkon "$venv_path" "poetry"
 40+                return 0
 41+            fi
 42+        fi
 43+    fi
 44+    return 1
 45+}
 46+
 47+
 48+function _activate_pipenv() {
 49+    # unfortunately running pipenv each time we are in a pipenv project directory is slow :(
 50+    if venv_path="$(PIPENV_IGNORE_VIRTUALENVS=1 pipenv --venv 2>/dev/null)"; then
 51+        _maybeworkon "$venv_path" "pipenv"
 52+        return 0
 53+    fi
 54+    return 1
 55+}
 56+
 57+
 58 # Automatically switch virtualenv when $AUTOSWITCH_FILE file detected
 59 function check_venv()
 60 {
 61@@ -175,39 +202,29 @@ function check_venv()
 62     # check if Pipfile exists rather than invoking pipenv as it is slow
 63     local pipfile_path="$(_check_path "$PWD" "Pipfile")"
 64     # Same logic applies to poetry
 65-    local pyproject_path="$(_check_path "$PWD" "pyproject.toml")"
 66+    local poetry_lock="$(_check_path "$PWD" "poetry.lock")"
 67 
 68     if [[ -n "$pipfile_path" ]] && type "pipenv" > /dev/null; then
 69-        # unfortunately running pipenv each time we are in a pipenv project directory is slow :(
 70-        if venv_path="$(PIPENV_IGNORE_VIRTUALENVS=1 pipenv --venv 2>/dev/null)"; then
 71-            _maybeworkon "$venv_path" "pipenv"
 72+        if _activate_pipenv; then
 73             return
 74         fi
 75-    elif [[ -n "$pyproject_path" ]] && type "poetry" > /dev/null; then
 76-        # we need to infer the target virtualenv directory based on poetry's data
 77-        # to easiest way is to actually get the location of the python binary and
 78-        # infer the location of the virtualenv from there.
 79-        if poetry_python=$(poetry run which python); then
 80-            if venv_path="$(dirname $(dirname $poetry_python))"; then
 81-                _maybeworkon "$venv_path" "poetry"
 82-                return
 83-            fi
 84+    elif [[ -n "$poetry_lock" ]] && type "poetry" > /dev/null; then
 85+        if _activate_poetry; then
 86+            return
 87         fi
 88     fi
 89 
 90     local venv_type="$(_get_venv_type "$PWD" "unknown")"
 91 
 92     # If we still haven't got anywhere, fallback to defaults
 93-    if [[ "$venv_type" == "pipenv" ]]; then
 94-        printf "Python project detected. "
 95-        printf "Run ${PURPLE}pipenv install${NORMAL} to setup autoswitching\n"
 96-    elif [[ "$venv_type" == "virtualenv" ]]; then
 97-        printf "Python project detected. "
 98+    if [[ "$venv_type" != "unknown" ]]; then
 99+        printf "Python ${PURPLE}$venv_type${NORMAL} project detected. "
100         printf "Run ${PURPLE}mkvenv${NORMAL} to setup autoswitching\n"
101     fi
102     _default_venv
103 }
104 
105diff --git a/tests/test_check_venv.zunit b/tests/test_check_venv.zunit
106index 4b3b17953e952afa7f9711a433205de18a316950..64ea4cc195ff4d557bde2b640595aabd156db86b 100644
107--- a/tests/test_check_venv.zunit
108+++ b/tests/test_check_venv.zunit
109@@ -36,7 +36,7 @@
110     run check_venv
111 
112     assert $status equals 0
113-    assert "$output" same_as "Python project detected. Run \e[35mmkvenv\e[0m to setup autoswitching"
114+    assert "$output" same_as "Python \e[35mvirtualenv\e[0m project detected. Run \e[35mmkvenv\e[0m to setup autoswitching"
115 }
116 
117 @test 'check_venv - Displays message on project detection (setup.py)' {
118@@ -46,7 +46,7 @@
119     run check_venv
120 
121     assert $status equals 0
122-    assert "$output" same_as "Python project detected. Run \e[35mmkvenv\e[0m to setup autoswitching"
123+    assert "$output" same_as "Python \e[35mvirtualenv\e[0m project detected. Run \e[35mmkvenv\e[0m to setup autoswitching"
124 }
125 
126 @test 'check_venv - Displays message on project detection (Pipfile)' {
127@@ -56,7 +56,17 @@
128     run check_venv
129 
130     assert $status equals 0
131-    assert "$output" same_as "Python project detected. Run \e[35mpipenv install\e[0m to setup autoswitching"
132+    assert "$output" same_as "Python \e[35mpipenv\e[0m project detected. Run \e[35mmkvenv\e[0m to setup autoswitching"
133+}
134+
135+@test 'check_venv - Displays message on project detection (poetry.lock)' {
136+    PWD="$TARGET"
137+    touch "$TARGET/poetry.lock"
138+
139+    run check_venv
140+
141+    assert $status equals 0
142+    assert "$output" same_as "Python \e[35mpoetry\e[0m project detected. Run \e[35mmkvenv\e[0m to setup autoswitching"
143 }
144 
145 @test 'check_venv - Displays message on project detection (setup.py + requirements.txt)' {
146@@ -67,7 +77,7 @@
147     run check_venv
148 
149     assert $status equals 0
150-    assert "$output" same_as "Python project detected. Run \e[35mmkvenv\e[0m to setup autoswitching"
151+    assert "$output" same_as "Python \e[35mvirtualenv\e[0m project detected. Run \e[35mmkvenv\e[0m to setup autoswitching"
152 }
153 
154 @test 'check_venv - Security warning for weak writeable by group permissions' {
155@@ -156,7 +166,7 @@
156 
157 @test 'check_venv - activate if .venv unavailable but poetry available' {
158     PWD="$TARGET/sub-directory"  # Should also work in subdirectories where pyproject.toml is found
159-    touch "$TARGET/pyproject.toml"
160+    touch "$TARGET/poetry.lock"
161 
162     # Mimic "poetry run which python"
163     function poetry {
164diff --git a/tests/test_mkvenv.zunit b/tests/test_mkvenv.zunit
165index 9b08b8eedcbe20946093e1368ab53cb6cf74cf6d..7af9626ad387f577f52f860b9827dd745cd02dd8 100644
166--- a/tests/test_mkvenv.zunit
167+++ b/tests/test_mkvenv.zunit
168@@ -95,7 +95,7 @@
169     run mkvenv
170 
171     assert $status equals 0
172-    assert "$lines[1]" contains "zsh-autoswitch-virtualenv requires virtualenv to be installed!"
173+    assert "$lines[1]" contains "zsh-autoswitch-virtualenv requires 'virtualenv' to install this project!"
174     assert "$lines[2]" is_empty
175     assert "$lines[3]" contains "If this is already installed but you are still seeing this message,"
176     assert "$lines[4]" contains "then make sure the \e[1mvirtualenv\e[0m command is in your PATH.\n"