b54524c036a8ad60307889b4f8ca582714d4515b
- Author
- TheEdgeOfRage <git@theedgeofrage.com>
- Committer
- TheEdgeOfRage <git@theedgeofrage.com>
- Date
Message
Diff
This diff is truncated to protect this page.
1diff --git a/README.rst b/README.rst
2index c4b89cc9ef27ef175c79ff7fe97ae15691816d05..c801a97b656887bee4262166a1fe0e3766e3ee7d 100644
3--- a/README.rst
4+++ b/README.rst
5@@ -27,18 +27,17 @@ Simply call the ``mkvenv`` command in the directory you wish to setup a
6 virtual environment. A virtual environment specific to that folder will
7 now activate every time you enter it.
8
9-``zsh-autoswitch-virtualenv`` will detect python projects and remind
10-you to create a virtual environment. This mainly occurs if one of the following
11-is found in current the directory:
12+``zsh-autoswitch-virtualenv`` detects Python projects when one of the
13+following files is in the current directory:
14
15 * setup.py
16 * requirements.txt
17 * Pipfile
18 * poetry.lock
19+* uv.lock
20
21 To create a virtual environment for that project, simply run ``mkvenv``.
22-This command works as expected for all popular python project types
23-(virtualenvs, pipenv and poetry).
24+This command works as expected for virtualenvs, UV, Pipenv, and Poetry projects.
25
26 See the Commands_ section below for more detail.
27
28@@ -71,10 +70,11 @@ projects (or equivalent file for the Version Control you are using).
29 Installing
30 ----------
31
32-``autoswitch-virtualenv`` requires `virtualenv <https://pypi.org/project/virtualenv/>`__ to be installed.
33-You will also need to make sure that ``python`` (without a suffix; both Python 2 and 3 are supported) is available in your ``$PATH``.
34+``autoswitch-virtualenv`` requires Python 3 with the ``venv`` module available.
35+Make sure that ``python3`` is available in your ``$PATH``, or configure
36+``AUTOSWITCH_DEFAULT_PYTHON`` to use a different Python binary.
37
38-Once ``virtualenv`` is installed, add one of the following lines to your ``.zshrc`` file depending on the
39+Add one of the following lines to your ``.zshrc`` file depending on the
40 package manager you are using:
41
42 ZPlug_
43@@ -146,13 +146,8 @@ helper command.
44 $ cd my-python-project
45 $ mkvenv
46 Creating my-python-project virtualenv
47- Found a requirements.txt. Install? [y/N]:
48- Collecting requests (from -r requirements.txt (line 1))
49- Using cached requests-2.11.1-py2.py3-none-any.whl
50- Installing collected packages: requests
51- Successfully installed requests-2.11.1
52
53-This command also works as expected with both ``poetry`` and ``pipenv``.
54+This command also works as expected with ``uv``, ``poetry``, and ``pipenv``.
55
56 Optionally, you can specify the python binary to use for this virtual environment
57
58@@ -161,8 +156,9 @@ Optionally, you can specify the python binary to use for this virtual environmen
59 $ mkvenv --python=/usr/bin/python3
60
61
62-In fact any parameters passed to mkvenv will be passed to the relevant setup command.
63-The same applies to passing additional parameters to ``pipenv install`` and ``poetry install``.
64+The ``--python`` option selects the Python binary used to run ``python -m venv``.
65+Use ``--verbose`` to show its output. Other parameters are passed to the relevant
66+setup command, including ``uv sync``, ``pipenv install``, and ``poetry install``.
67
68 Autoswitching is smart enough to detect that you have traversed to a
69 project subdirectory. So your virtualenv will not be deactivated if you
70@@ -284,19 +280,6 @@ changed by setting the value of ``AUTOSWITCH_FILE``. For example:
71
72 export AUTOSWITCH_FILE=".autoswitch"
73
74-**Default requirements file**
75-
76-You may specify a default requirements file to use when creating a virtualenv by
77-setting the value of ``AUTOSWITCH_DEFAULT_REQUIREMENTS``. For example:
78-
79-::
80-
81- export AUTOSWITCH_DEFAULT_REQUIREMENTS="$HOME/.requirements.txt"
82-
83-If the value is set and the target file exists you will be prompted to install with that file
84-each time you create a new virtualenv.
85-
86-
87 **Set verbosity when changing environments**
88
89 You can prevent verbose messages from being displayed when moving
90@@ -320,9 +303,8 @@ then you can set the variable to use a relative path. For example:
91
92 **Customising pip install invocation**
93
94-By default `mkvenv` will install setup.py via pip in `editable (i.e. development) mode
95-<https://pip.pypa.io/en/stable/cli/pip_install/#editable-installs>`__.
96-To change this set ``AUTOSWITCH_PIPINSTALL`` to ``FULL``.
97+By default, ``mkvenv`` installs Pipenv projects in editable mode. To use a full
98+Pipenv install instead, set ``AUTOSWITCH_PIPINSTALL`` to ``FULL``.
99
100 Security Warnings
101 -----------------
102diff --git a/autoswitch_virtualenv.plugin.zsh b/autoswitch_virtualenv.plugin.zsh
103index 86ae44873f793411e688a781954bcf45d1a60f01..359b37015827a379d3f2d24f8fd54f8e1dee52b9 100644
104--- a/autoswitch_virtualenv.plugin.zsh
105+++ b/autoswitch_virtualenv.plugin.zsh
106@@ -233,13 +233,6 @@ function check_venv()
107 fi
108 fi
109
110- local venv_type="$(_get_venv_type "$PWD" "unknown")"
111-
112- # If we still haven't got anywhere, fallback to defaults
113- if [[ "$venv_type" != "unknown" ]]; then
114- printf "Python ${AUTOSWITCH_PURPLE}$venv_type${AUTOSWITCH_NORMAL} project detected. "
115- printf "Run ${AUTOSWITCH_PURPLE}mkvenv${AUTOSWITCH_NORMAL} to setup autoswitching\n"
116- fi
117 _default_venv
118 }
119
120@@ -313,7 +306,8 @@ function _missing_error_message() {
121
122 function randstr()
123 {
124- ${AUTOSWITCH_DEFAULT_PYTHON:-python3} -c "from __future__ import print_function; import string, random; print(''.join(random.choice(string.ascii_lowercase) for _ in range(4)))"
125+ local python_bin="${1:-${AUTOSWITCH_DEFAULT_PYTHON:-python3}}"
126+ "$python_bin" -c "from __future__ import print_function; import string, random; print(''.join(random.choice(string.ascii_lowercase) for _ in range(4)))"
127 }
128
129
130@@ -358,82 +352,70 @@ function mkvenv()
131 _activate_uv
132 return
133 else
134- if ! type "virtualenv" > /dev/null; then
135- _missing_error_message virtualenv
136+ local python_bin="${AUTOSWITCH_DEFAULT_PYTHON:-python3}"
137+ local use_default_python=1
138+ local verbose=0
139+ local -a venv_params
140+ local index
141+
142+ for (( index = 1; index <= ${#params}; index++ )); do
143+ if [[ "${params[index]}" == "--python" ]]; then
144+ (( index++ ))
145+ if (( index > ${#params} )); then
146+ printf "mkvenv: --python requires a value\n"
147+ return 1
148+ fi
149+ python_bin="${params[index]}"
150+ use_default_python=0
151+ elif [[ "${params[index]}" == --python=* ]]; then
152+ python_bin="${params[index]#--python=}"
153+ use_default_python=0
154+ elif [[ "${params[index]}" == "--verbose" ]]; then
155+ verbose=1
156+ else
157+ venv_params+=("${params[index]}")
158+ fi
159+ done
160+
161+ if [[ -z "$python_bin" ]]; then
162+ printf "mkvenv: --python requires a value\n"
163+ return 1
164+ fi
165+
166+ if ! type "$python_bin" > /dev/null; then
167+ _missing_error_message "$python_bin"
168 return
169 fi
170
171 if [[ -f "$AUTOSWITCH_FILE" ]]; then
172 printf "$AUTOSWITCH_FILE file already exists. If this is a mistake use the rmvenv command\n"
173 else
174- local venv_name="$(basename $PWD)-$(randstr)"
175+ local venv_name="$(basename $PWD)-$(randstr "$python_bin")"
176+ local venv_path="$(_virtual_env_dir "$venv_name")"
177
178 printf "Creating ${AUTOSWITCH_PURPLE}%s${NONE} virtualenv\n" "$venv_name"
179
180-
181- if [[ -n "$AUTOSWITCH_DEFAULT_PYTHON" && ${params[(I)--python*]} -eq 0 ]]; then
182+ if (( use_default_python )) && [[ -n "$AUTOSWITCH_DEFAULT_PYTHON" ]]; then
183 printf "${AUTOSWITCH_PURPLE}"
184 printf 'Using $AUTOSWITCH_DEFAULT_PYTHON='
185 printf "$AUTOSWITCH_DEFAULT_PYTHON"
186 printf "${NONE}\n"
187- params+="--python=$AUTOSWITCH_DEFAULT_PYTHON"
188 fi
189
190 /bin/mkdir -p "$VIRTUAL_ENV_DIR"
191
192- if [[ ${params[(I)--verbose]} -eq 0 ]]; then
193- virtualenv $params "$(_virtual_env_dir "$venv_name")"
194+ if (( verbose )); then
195+ "$python_bin" -m venv "${venv_params[@]}" "$venv_path" || return
196 else
197- virtualenv $params "$(_virtual_env_dir "$venv_name")" > /dev/null
198+ "$python_bin" -m venv "${venv_params[@]}" "$venv_path" > /dev/null || return
199 fi
200
201 printf "$venv_name\n" > "$AUTOSWITCH_FILE"
202 chmod 600 "$AUTOSWITCH_FILE"
203
204- _maybeworkon "$(_virtual_env_dir "$venv_name")" "virtualenv"
205-
206diff --git a/tests/test_check_venv.zunit b/tests/test_check_venv.zunit
207index c0017cc2b2c8b177ee6cc2c2909dd8fc5587658a..045bca38116317be361a0d67198f9590304a4de1 100644
208--- a/tests/test_check_venv.zunit
209+++ b/tests/test_check_venv.zunit
210@@ -33,59 +33,16 @@
211 rm -rf Pipfile
212 }
213
214-@test 'check_venv - Displays message on project detection (requirements.txt)' {
215+@test 'check_venv - does not display a project detection message' {
216 PWD="$TARGET"
217+ unset AUTOSWITCH_DEFAULTENV
218+ unset VIRTUAL_ENV
219 touch "$TARGET/requirements.txt"
220
221 run check_venv
222
223 assert $status equals 0
224- assert "$output" same_as "Python \e[35mvirtualenv\e[0m project detected. Run \e[35mmkvenv\e[0m to setup autoswitching"
225-}
226-
227-@test 'check_venv - Displays message on project detection (setup.py)' {
228- PWD="$TARGET"
229- touch "$TARGET/setup.py"
230-
231- run check_venv
232-
233- assert $status equals 0
234- assert "$output" same_as "Python \e[35mvirtualenv\e[0m project detected. Run \e[35mmkvenv\e[0m to setup autoswitching"
235-}
236-
237-@test 'check_venv - Displays message on project detection (Pipfile)' {
238- PWD="$TARGET"
239- touch "$TARGET/Pipfile"
240-
241- run check_venv
242-
243- assert $status equals 0
244- assert "$output" same_as "Python \e[35mpipenv\e[0m project detected. Run \e[35mmkvenv\e[0m to setup autoswitching"
245-}
246-
247-@test 'check_venv - Displays message on project detection (poetry.lock)' {
248- PWD="$TARGET"
249- touch "$TARGET/poetry.lock"
250-
251- function poetry {
252- echo ""
253- }
254-
255- run check_venv
256-
257- assert $status equals 0
258- assert "$output" same_as "Python \e[35mpoetry\e[0m project detected. Run \e[35mmkvenv\e[0m to setup autoswitching"
259-}
260-
261-@test 'check_venv - Displays message on project detection (setup.py + requirements.txt)' {
262- PWD="$TARGET"
263- touch "$TARGET/setup.py"
264- touch "$TARGET/requirements.txt"
265-
266- run check_venv
267-
268- assert $status equals 0
269- assert "$output" same_as "Python \e[35mvirtualenv\e[0m project detected. Run \e[35mmkvenv\e[0m to setup autoswitching"
270+ assert "$output" is_empty
271 }
272
273 @test 'check_venv - Security warning for weak writeable by group permissions' {
274diff --git a/tests/test_install_requirements.zunit b/tests/test_install_requirements.zunit
275deleted file mode 100644
276index e92c13ad423cfe11077ebf405ceb3fe5de9202bf..0000000000000000000000000000000000000000
277--- a/tests/test_install_requirements.zunit
278+++ /dev/null
279@@ -1,145 +0,0 @@
280-#!/usr/bin/env zunit
281-
282-@setup {
283- export DISABLE_AUTOSWITCH_VENV="1"
284- load "../autoswitch_virtualenv.plugin.zsh"
285- unset AUTOSWITCH_DEFAULT_REQUIREMENTS
286- unset AUTOSWITCH_PIPINSTALL
287-
288- function read {
289- eval $1=\"y\"
290- echo y
291- }
292-
293- TARGET="$(mktemp -d)"
294- cd "$TARGET"
295-}
296-
297-@teardown {
298- rm -rf "$TARGET"
299-}
300-
301-@test 'install_requirements - does nothing if no files found' {
302- run install_requirements
303-
304- assert $status equals 0
305- assert "$output" is_empty
306-}
307-
308-@test 'install_requirements - does not install with no input' {
309- echo "django" > requirements.txt
310- echo "pytest" > dev-requirements.txt
311-
312- # override default mock to return nothing
313- function read {
314- eval $1=\"\"
315- echo ""
316- }
317-
318- # mock pip to make it testable
319- function pip {
320- echo "pip $@"
321- cat "$3"
322- }
323-
324- run install_requirements
325-
326- assert $status equals 0
327- assert "$lines[1]" same_as "Found a \e[35mdev-requirements.txt\e[0m file. Install? [y/N]: "
328- assert "$lines[2]" same_as "Found a \e[35mrequirements.txt\e[0m file. Install? [y/N]: "
329-}
330-
331-@test 'install_requirements - installs default requirements' {
332- AUTOSWITCH_DEFAULT_REQUIREMENTS="$(mktemp -d)/default-requirements.txt"
333- echo "django" > "$AUTOSWITCH_DEFAULT_REQUIREMENTS"
334-
335- # mock pip to make it testable
336- function pip {
337- echo "pip $@"
338- cat "$3"
339- }
340-
341- run install_requirements
342-
343- assert $status equals 0
344- assert "$lines[1]" same_as "Install default requirements? (\e[35m$AUTOSWITCH_DEFAULT_REQUIREMENTS\e[0m) [y/N]: y"
345- assert "$lines[2]" same_as "pip install -r $AUTOSWITCH_DEFAULT_REQUIREMENTS"
346- assert "$lines[3]" same_as "django"
347-}
348-
349-@test 'install_requirements - installs *requirements.txt' {
350- echo "django" > requirements.txt
351- echo "pytest" > dev-requirements.txt
352-
353- # mock pip to make it testable
354- function pip {
355- echo "pip $@"
356- cat "$3"
357- }
358-
359- run install_requirements
360-
361- assert $status equals 0
362- assert "$lines[1]" same_as "Found a \e[35mdev-requirements.txt\e[0m file. Install? [y/N]: y"
363- assert "$lines[2]" same_as "pip install -r dev-requirements.txt"
364- assert "$lines[3]" same_as "pytest"
365- assert "$lines[4]" same_as "Found a \e[35mrequirements.txt\e[0m file. Install? [y/N]: y"
366- assert "$lines[5]" same_as "pip install -r requirements.txt"
367- assert "$lines[6]" same_as "django"
368-}
369-
370-@test 'install_requirements - installs setup.py' {
371- touch "setup.py"
372- echo "django" > requirements.txt
373-
374- # mock pip to make it testable
375- function pip {
376- echo "pip $@"
377- }
378-
379diff --git a/tests/test_mkvenv.zunit b/tests/test_mkvenv.zunit
380index 4b66d90ddd475f0759c0926797e967c1bb887e9d..74b278c31c69451f6d48cc9eb40528c9d5b5b07f 100644
381--- a/tests/test_mkvenv.zunit
382+++ b/tests/test_mkvenv.zunit
383@@ -1,16 +1,27 @@
384 #!/usr/bin/env zunit
385
386 @setup {
387- function virtualenv {
388- echo virtualenv $@
389+ function python3 {
390+ echo python3 $@
391+ }
392+
393+ function python_foo {
394+ echo python_foo $@
395 }
396
397 export DISABLE_AUTOSWITCH_VENV="1"
398 load "../autoswitch_virtualenv.plugin.zsh"
399- unset AUTOSWITCH_DEFAULT_REQUIREMENTS
400+ unset AUTOSWITCH_DEFAULT_PYTHON
401 TARGET="$(mktemp -d)"
402 cd "$TARGET"
403
404+ function randstr {
405+ printf test
406+ }
407+
408+ function _maybeworkon {
409+ }
410+
411 function poetry {
412 echo "poetry" $@
413 }
414@@ -57,6 +68,28 @@
415 assert "$output" matches "myproject-[a-z]{4}"
416 }
417
418+@test 'mkvenv - uses default Python if set' {
419+ mkdir myproject
420+ cd myproject
421+ AUTOSWITCH_DEFAULT_PYTHON="python_foo"
422+
423+ run mkvenv --system-site-packages
424+
425+ assert $status equals 0
426+ assert "$lines[2]" contains 'Using $AUTOSWITCH_DEFAULT_PYTHON=python_foo'
427+ assert "$lines[3]" same_as "python_foo -m venv --system-site-packages $HOME/.virtualenvs/myproject-test"
428+}
429+
430+@test 'mkvenv - uses explicitly specified Python' {
431+ mkdir myproject
432+ cd myproject
433+
434+ run mkvenv --python python_foo --clear
435+
436+ assert $status equals 0
437+ assert "$lines[2]" same_as "python_foo -m venv --clear $HOME/.virtualenvs/myproject-test"
438+}
439+
440 @test 'mkvenv - (poetry project) runs correct command' {
441 mkdir myproject
442 cd myproject
443@@ -81,10 +114,10 @@
444 assert "$lines[2]" same_as "activating pipenv"
445 }
446
447-@test 'prints help message and disables plugin if virtualenv not setup' {
448+@test 'prints help message if Python is not setup' {
449 # Mock type to fail
450 function type() {
451- if [[ "$1" == "virtualenv" ]]; then
452+ if [[ "$1" == "python3" ]]; then
453 return 1
454 fi
455 return 0
456@@ -93,10 +126,10 @@
457 run mkvenv
458
459 assert $status equals 0
460- assert "$lines[1]" contains "zsh-autoswitch-virtualenv requires 'virtualenv' to install this project!"
461+ assert "$lines[1]" contains "zsh-autoswitch-virtualenv requires 'python3' to install this project!"
462 assert "$lines[2]" is_empty
463 assert "$lines[3]" contains "If this is already installed but you are still seeing this message,"
464- assert "$lines[4]" contains "then make sure the \e[1mvirtualenv\e[0m command is in your PATH.\n"
465+ assert "$lines[4]" contains "then make sure the \e[1mpython3\e[0m command is in your PATH.\n"
466 assert "$lines[5]" is_empty
467 assert ${#lines} equals 4
468 }
469diff --git a/tests/test_rmvenv.zunit b/tests/test_rmvenv.zunit
470index 53a6a0285123e21b2a61151262d506d717c27fba..c423c795bc430cf8f518c56a0b19f8b5b184f6f7 100644
471--- a/tests/test_rmvenv.zunit
472+++ b/tests/test_rmvenv.zunit
473@@ -4,7 +4,6 @@
474
475 export DISABLE_AUTOSWITCH_VENV="1"
476 load "../autoswitch_virtualenv.plugin.zsh"
477- unset AUTOSWITCH_DEFAULT_REQUIREMENTS
478 TARGET="$(mktemp -d)"
479 cd "$TARGET"
480