Skip to content

Commit eb8948d

Browse files
committed
add hooks for cpvirtualenv; make deactivate work better under ksh
1 parent 62f0fe6 commit eb8948d

File tree

8 files changed

+124
-17
lines changed

8 files changed

+124
-17
lines changed

docs/source/command_ref.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ Syntax::
4444
* :ref:`scripts-prermvirtualenv`
4545
* :ref:`scripts-postrmvirtualenv`
4646

47+
.. _command-cpvirtualenv:
48+
4749
cpvirtualenv
4850
------------
4951

@@ -58,6 +60,13 @@ Syntax::
5860
The environment created by the copy operation is made `relocatable
5961
<http://virtualenv.openplans.org/#making-environments-relocatable>`__.
6062

63+
.. seealso::
64+
65+
* :ref:`scripts-precpvirtualenv`
66+
* :ref:`scripts-postcpvirtualenv`
67+
* :ref:`scripts-premkvirtualenv`
68+
* :ref:`scripts-postmkvirtualenv`
69+
6170
==================================
6271
Controlling the Active Environment
6372
==================================

docs/source/history.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Dev
1313
- Update :ref:`command-mkvirtualenv` documentation to include the
1414
fact that a new environment is activated immediately after it is
1515
created (issue #30).
16+
- Added hooks around :ref:`command-cpvirtualenv`.
17+
- Made deactivation more robust, especially under ksh.
1618

1719
2.0.2
1820

docs/source/scripts.rst

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,34 @@ postmkvirtualenv
4848
``$WORKON_HOME/postmkvirtualenv`` is sourced after the new environment
4949
is created and activated.
5050

51+
.. _scripts-precpvirtualenv:
52+
53+
precpvirtualenv
54+
===============
55+
56+
:Global/Local: global
57+
:Argument(s): name of original environment, name of new environment
58+
:Sourced/Run: run
59+
60+
``$WORKON_HOME/precpvirtualenv`` is run as an external program after
61+
the source environment is duplicated and made relocatable, but before
62+
the ``premkvirtualenv`` hook is run or the current environment is
63+
switched to point to the new env. The current working directory for
64+
the script is ``$WORKON_HOME`` and the names of the source and new
65+
environments are passed as arguments to the script.
66+
67+
.. _scripts-postcpvirtualenv:
68+
69+
postcpvirtualenv
70+
================
71+
72+
:Global/Local: global
73+
:Argument(s): none
74+
:Sourced/Run: sourced
75+
76+
``$WORKON_HOME/postcpvirtualenv`` is sourced after the new environment
77+
is created and activated.
78+
5179
.. _scripts-preactivate:
5280

5381
preactivate

setup.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,13 @@ def find_package_data(
167167
'user_scripts = virtualenvwrapper.user_scripts:post_mkvirtualenv_source',
168168
],
169169

170+
'virtualenvwrapper.pre_cpvirtualenv': [
171+
'user_scripts = virtualenvwrapper.user_scripts:pre_cpvirtualenv',
172+
],
173+
'virtualenvwrapper.post_cpvirtualenv_source': [
174+
'user_scripts = virtualenvwrapper.user_scripts:post_cpvirtualenv_source',
175+
],
176+
170177
'virtualenvwrapper.pre_rmvirtualenv': [
171178
'user_scripts = virtualenvwrapper.user_scripts:pre_rmvirtualenv',
172179
],

tests/test_cd.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ test_cdvirtual() {
2727
assertSame "$VIRTUAL_ENV" "$(pwd)"
2828
cdvirtualenv bin
2929
assertSame "$VIRTUAL_ENV/bin" "$(pwd)"
30-
cd "$(start_dir)"
30+
cd "$start_dir"
3131
}
3232

3333
test_cdsitepackages () {
@@ -36,7 +36,7 @@ test_cdsitepackages () {
3636
pyvers=$(python -V 2>&1 | cut -f2 -d' ' | cut -f1-2 -d.)
3737
sitepackages="$VIRTUAL_ENV/lib/python${pyvers}/site-packages"
3838
assertSame "$sitepackages" "$(pwd)"
39-
cd "$(start_dir)"
39+
cd "$start_dir"
4040
}
4141

4242
test_cdsitepackages_with_arg () {
@@ -46,7 +46,7 @@ test_cdsitepackages_with_arg () {
4646
mkdir -p "${sitepackage_subdir}"
4747
cdsitepackages subdir
4848
assertSame "$sitepackage_subdir" "$(pwd)"
49-
cd "$(start_dir)"
49+
cd "$start_dir"
5050
}
5151

5252
test_cdvirtualenv_no_workon_home () {

tests/test_cp.sh

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,20 @@ setUp () {
1010
rm -rf "$WORKON_HOME"
1111
mkdir -p "$WORKON_HOME"
1212
source "$test_dir/../virtualenvwrapper.sh"
13-
echo
1413
rm -f "$test_dir/catch_output"
14+
echo
1515
}
1616

1717
tearDown() {
1818
rm -rf "$WORKON_HOME"
1919
}
2020

21-
2221
test_cpvirtualenv () {
2322
mkvirtualenv "source"
24-
(cd tests/testpackage && python setup.py install)
23+
(cd tests/testpackage && python setup.py install) >/dev/null 2>&1
2524
cpvirtualenv "source" "destination"
26-
deactivate
25+
assertSame "destination" $(basename "$VIRTUAL_ENV")
2726
rmvirtualenv "source"
28-
workon "destination"
2927
testscript="$(which testscript.py)"
3028
assertTrue "Environment test script not found in path" "[ $WORKON_HOME/destination/bin/testscript.py -ef $testscript ]"
3129
testscriptcontent="$(cat $testscript)"
@@ -36,7 +34,7 @@ test_cpvirtualenv () {
3634

3735
test_cprelocatablevirtualenv () {
3836
mkvirtualenv "source"
39-
(cd tests/testpackage && python setup.py install)
37+
(cd tests/testpackage && python setup.py install) >/dev/null 2>&1
4038
assertTrue "virtualenv --relocatable \"$WORKON_HOME/source\""
4139
cpvirtualenv "source" "destination"
4240
testscript="$(which testscript.py)"
@@ -50,5 +48,33 @@ test_cp_notexists () {
5048
assertSame "$out" "virtualenvthatdoesntexist virtualenv doesn't exist"
5149
}
5250

51+
test_hooks () {
52+
mkvirtualenv "source"
53+
54+
export pre_test_dir=$(cd "$test_dir"; pwd)
55+
echo "echo GLOBAL premkvirtualenv \`pwd\` \"\$@\" >> \"$pre_test_dir/catch_output\"" >> "$WORKON_HOME/premkvirtualenv"
56+
chmod +x "$WORKON_HOME/premkvirtualenv"
57+
echo "echo GLOBAL postmkvirtualenv >> $test_dir/catch_output" > "$WORKON_HOME/postmkvirtualenv"
58+
echo "#!/bin/sh" > "$WORKON_HOME/precpvirtualenv"
59+
echo "echo GLOBAL precpvirtualenv \`pwd\` \"\$@\" >> \"$pre_test_dir/catch_output\"" >> "$WORKON_HOME/precpvirtualenv"
60+
chmod +x "$WORKON_HOME/precpvirtualenv"
61+
echo "#!/bin/sh" > "$WORKON_HOME/postcpvirtualenv"
62+
echo "echo GLOBAL postcpvirtualenv >> $test_dir/catch_output" > "$WORKON_HOME/postcpvirtualenv"
63+
64+
cpvirtualenv "source" "destination"
65+
66+
output=$(cat "$test_dir/catch_output")
67+
68+
expected="GLOBAL precpvirtualenv $WORKON_HOME source destination
69+
GLOBAL premkvirtualenv $WORKON_HOME destination
70+
GLOBAL postmkvirtualenv
71+
GLOBAL postcpvirtualenv"
72+
73+
assertSame "$expected" "$output"
74+
rm -f "$WORKON_HOME/premkvirtualenv"
75+
rm -f "$WORKON_HOME/postmkvirtualenv"
76+
deactivate
77+
}
78+
5379
. "$test_dir/shunit2"
5480

virtualenvwrapper.sh

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -229,31 +229,43 @@ workon () {
229229
if [ $? -eq 0 ]
230230
then
231231
deactivate
232+
unset -f deactivate >/dev/null 2>&1
232233
fi
233234

234235
virtualenvwrapper_run_hook "pre_activate" "$env_name"
235236

236237
source "$activate"
237238

238-
# Save the deactivate function from virtualenv
239-
virtualenvwrapper_saved_deactivate=$(typeset -f deactivate)
239+
# Save the deactivate function from virtualenv under a different name
240+
virtualenvwrapper_original_deactivate=`typeset -f deactivate | sed 's/deactivate/virtualenv_deactivate/g'`
241+
eval "$virtualenvwrapper_original_deactivate"
242+
unset -f deactivate >/dev/null 2>&1
243+
# virtualenvwrapper_saved_deactivate=$(tempfile --directory "$VIRTUALENVWRAPPER_TMPDIR")
244+
# $(typeset -f deactivate | sed 's/deactivate/original_deactivate/g' > $virtualenvwrapper_saved_deactivate)
245+
# echo "original_deactivate" >> $virtualenvwrapper_saved_deactivate
246+
# echo "SAVED: \"$virtualenvwrapper_saved_deactivate\""
247+
# cat $virtualenvwrapper_saved_deactivate
240248

241249
# Replace the deactivate() function with a wrapper.
242250
eval 'deactivate () {
251+
243252
# Call the local hook before the global so we can undo
244253
# any settings made by the local postactivate first.
245254
virtualenvwrapper_run_hook "pre_deactivate"
246255
247256
env_postdeactivate_hook="$VIRTUAL_ENV/bin/postdeactivate"
248257
old_env=$(basename "$VIRTUAL_ENV")
249258
250-
# Restore the original definition of deactivate
251-
eval "$virtualenvwrapper_saved_deactivate"
252-
253-
# Instead of recursing, this calls the now restored original function.
254-
deactivate
259+
# Call the original function.
260+
#source "$virtualenvwrapper_saved_deactivate"
261+
#rm -f "$virtualenvwrapper_saved_deactivate"
262+
virtualenv_deactivate
255263
256264
virtualenvwrapper_run_hook "post_deactivate" "$old_env"
265+
266+
# Remove this function
267+
unset -f deactivate
268+
257269
}'
258270

259271
virtualenvwrapper_run_hook "post_activate"
@@ -429,8 +441,14 @@ cpvirtualenv() {
429441

430442
virtualenv "$target_env" --relocatable
431443
sed "s/VIRTUAL_ENV\(.*\)$env_name/VIRTUAL_ENV\1$new_env/g" < "$source_env/bin/activate" > "$target_env/bin/activate"
432-
echo "Created $new_env virtualenv"
444+
445+
(cd "$WORKON_HOME" &&
446+
virtualenvwrapper_run_hook "pre_cpvirtualenv" "$env_name" "$new_env" &&
447+
virtualenvwrapper_run_hook "pre_mkvirtualenv" "$new_env"
448+
)
433449
workon "$new_env"
450+
virtualenvwrapper_run_hook "post_mkvirtualenv"
451+
virtualenvwrapper_run_hook "post_cpvirtualenv"
434452
}
435453

436454
#

virtualenvwrapper/user_scripts.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,23 @@ def post_mkvirtualenv_source(args):
147147
[ -f "$WORKON_HOME/postmkvirtualenv" ] && source "$WORKON_HOME/postmkvirtualenv"
148148
"""
149149

150+
def pre_cpvirtualenv(args):
151+
log.debug('pre_cpvirtualenv %s', str(args))
152+
envname=args[0]
153+
for filename, comment in LOCAL_HOOKS:
154+
make_hook(os.path.join('$WORKON_HOME', envname, 'bin', filename), comment)
155+
run_global('precpvirtualenv', *args)
156+
return
157+
158+
159+
def post_cpvirtualenv_source(args):
160+
return """
161+
#
162+
# Run user-provided scripts
163+
#
164+
[ -f "$WORKON_HOME/postcpvirtualenv" ] && source "$WORKON_HOME/postcpvirtualenv"
165+
"""
166+
150167

151168
def pre_rmvirtualenv(args):
152169
log.debug('pre_rmvirtualenv')

0 commit comments

Comments
 (0)