Diff
1diff --git a/CHANGELOG.rst b/CHANGELOG.rst
2index 9c8d8ea8a42989f1c72b6880db5b9e1f51463b33..70b11915ac8e50840cadf5141cc5d45fd6ce9c49 100644
3--- a/CHANGELOG.rst
4+++ b/CHANGELOG.rst
5@@ -1,6 +1,10 @@
6 Changelog
7 =========
8
9+2.0.0
10+-----
11+* Support autoswitching of poetry projects
12+
13 1.16.2
14 ------
15 * Output messages to stderr instead of stdout
16diff --git a/README.rst b/README.rst
17index dda588d9d7db00f3a6fbb769df095881508c6983..fec802919df3622d64ccd919e2d43dcf89a58054 100644
18--- a/README.rst
19+++ b/README.rst
20@@ -6,7 +6,7 @@ Autoswitch Python Virtualenv
21 *zsh-autoswitch-virtualenv* is a simple and quick ZSH plugin that switches python
22 virtualenvs automatically as you move between directories.
23
24-*zsh-autoswitch-virtualenv* also automatically detects and activates your **Pipenv** projects
25+*zsh-autoswitch-virtualenv* also automatically detects and activates your **Pipenv** and **Poetry** projects
26 without any setup necessary.
27
28 * `How it Works`_
29@@ -31,7 +31,9 @@ now activate every time you enter it.
30 you to create a virtual environment if e.g. setup.py or requirements.txt is
31 found in the current directory.
32
33-**NOTE: Pipenv projects should not use 'mkvenv'. Use 'pipenv install' instead**
34+**NOTE: Pipenv and Poetry projects should not use 'mkvenv'.**
35+
36+**Use 'pipenv install' or 'poetry install' respectively instead**
37
38 See the Commands_ section below for more detail.
39
40@@ -50,7 +52,10 @@ is then a precommand hook that looks for a ``.venv`` file and switches
41 to the name specified if one is found.
42
43 For the case of pipenv projects, the plugin will look for a ``Pipfile``
44-and activate pipenv if it detects an existing virtual environment for it.
45+and activates pipenv if it detects an existing virtual environment for it.
46+
47+For the case of poetry projects, the plugin will look for a ``pyproject.toml``
48+and activates poetry if it detects an existing virtual environment for it.
49
50 **NOTE**: you may want to add ``.venv`` to your ``.gitignore`` in git
51 projects (or equivalent file for the Version Control you are using).
52@@ -232,7 +237,7 @@ By default, the following message is displayed in bold when an alias is found:
53
54 Where the following variables represent:
55
56-* ``%venv_type`` - the type of virtualenv being activated (virtualenv, pipenv)
57+* ``%venv_type`` - the type of virtualenv being activated (virtualenv, pipenv, poetry)
58 * ``%venv_name`` - the name of the virtualenv being activated
59 * ``%py_version`` - the version of python used by the virtualenv being activated
60
61diff --git a/autoswitch_virtualenv.plugin.zsh b/autoswitch_virtualenv.plugin.zsh
62index 605c2544b5d5623563161012493c5da030513dde..dd34416d374fc5c38ae788c487322389e90c0757 100644
63--- a/autoswitch_virtualenv.plugin.zsh
64+++ b/autoswitch_virtualenv.plugin.zsh
65@@ -1,4 +1,4 @@
66-export AUTOSWITCH_VERSION="1.16.2"
67+export AUTOSWITCH_VERSION="2.0.0"
68 export AUTOSWITCH_FILE=".venv"
69
70 RED="\e[31m"
71@@ -54,6 +54,10 @@ function _get_venv_type() {
72 venv_type="pipenv"
73 elif [[ -f "$venv_dir/requirements.txt" || -f "$venv_dir/setup.py" ]]; then
74 venv_type="virtualenv"
75+ # TODO: this is not technically correct as lots of tools use pyproject.toml
76+ # however it's probably a good enough approximation for this function
77+ elif [[ -f "$venv_dir/pyproject.toml" ]]; then
78+ venv_type="poetry"
79 fi
80 printf "%s" "$venv_type"
81 }
82@@ -170,6 +174,8 @@ function check_venv()
83
84 # check if Pipfile exists rather than invoking pipenv as it is slow
85 local pipfile_path="$(_check_path "$PWD" "Pipfile")"
86+ # Same logic applies to poetry
87+ local pyproject_path="$(_check_path "$PWD" "pyproject.toml")"
88
89 if [[ -n "$pipfile_path" ]] && type "pipenv" > /dev/null; then
90 # unfortunately running pipenv each time we are in a pipenv project directory is slow :(
91@@ -177,6 +183,12 @@ function check_venv()
92 _maybeworkon "$venv_path" "pipenv"
93 return
94 fi
95+ elif [[ -n "$pyproject_path" ]] && type "poetry" > /dev/null; then
96+ # we need to infer the target virtualenv directory based on poetry's data
97+ if venv_path="$(dirname $(dirname $(poetry run which python)))"; then
98+ _maybeworkon "$venv_path" "poetry"
99+ return
100+ fi
101 fi
102
103 local venv_type="$(_get_venv_type "$PWD" "unknown")"
104diff --git a/tests/test_check_venv.zunit b/tests/test_check_venv.zunit
105index a1194b02108b45a8e3051f0d87059f805b94d5a7..d942a1e99a274590d0f6f57becd9dc3751370a32 100644
106--- a/tests/test_check_venv.zunit
107+++ b/tests/test_check_venv.zunit
108@@ -154,6 +154,25 @@
109 assert "$output" same_as "Switching virtualenv: \e[1m\e[35mfoodefault\e[0m \e[32m[๐$PYTHON_VERSION]\e[0m"
110 }
111
112+@test 'check_venv - activate if .venv unavailable but poetry available' {
113+ PWD="$TARGET/sub-directory" # Should also work in subdirectories where pyproject.toml is found
114+ touch "$TARGET/pyproject.toml"
115+
116+ # Mimic poetry run which python
117+ function poetry {
118+ if [[ "$@" == "run which python" ]]; then
119+ echo "$HOME/.virtualenvs/foobar/bin/python"
120+ else
121+ echo "ERROR - wrong command from what was expected ran!"
122+ fi
123+ }
124+
125+ run check_venv
126+
127+ assert $status equals 0
128+ assert "$output" same_as "Switching poetry: \e[1m\e[35mfoobar\e[0m \e[32m[๐$PYTHON_VERSION]\e[0m"
129+}
130+
131
132 @test 'check_venv - activate if .venv unavailable but pipenv available' {
133 PWD="$TARGET/sub-directory" # Should also work in subdirectories where Pipfile is found