Commits

Doug Hellmann committed e96e532

add hooks for cpvirtualenv; make deactivate work better under ksh

  • Participants
  • Parent commits 81bd2ed

Comments (0)

Files changed (8)

File docs/source/command_ref.rst

    * :ref:`scripts-prermvirtualenv`
    * :ref:`scripts-postrmvirtualenv`
 
+.. _command-cpvirtualenv:
+
 cpvirtualenv
 ------------
 
    The environment created by the copy operation is made `relocatable
    <http://virtualenv.openplans.org/#making-environments-relocatable>`__.
 
+.. seealso::
+
+   * :ref:`scripts-precpvirtualenv`
+   * :ref:`scripts-postcpvirtualenv`
+   * :ref:`scripts-premkvirtualenv`
+   * :ref:`scripts-postmkvirtualenv`
+
 ==================================
 Controlling the Active Environment
 ==================================

File docs/source/history.rst

   - Update :ref:`command-mkvirtualenv` documentation to include the
     fact that a new environment is activated immediately after it is
     created (issue #30).
+  - Added hooks around :ref:`command-cpvirtualenv`.
+  - Made deactivation more robust, especially under ksh.
 
 2.0.2
 

File docs/source/scripts.rst

 ``$WORKON_HOME/postmkvirtualenv`` is sourced after the new environment
 is created and activated.
 
+.. _scripts-precpvirtualenv:
+
+precpvirtualenv
+===============
+
+  :Global/Local: global
+  :Argument(s): name of original environment, name of new environment
+  :Sourced/Run: run
+
+``$WORKON_HOME/precpvirtualenv`` is run as an external program after
+the source environment is duplicated and made relocatable, but before
+the ``premkvirtualenv`` hook is run or the current environment is
+switched to point to the new env. The current working directory for
+the script is ``$WORKON_HOME`` and the names of the source and new
+environments are passed as arguments to the script.
+
+.. _scripts-postcpvirtualenv:
+
+postcpvirtualenv
+================
+
+  :Global/Local: global
+  :Argument(s): none
+  :Sourced/Run: sourced
+
+``$WORKON_HOME/postcpvirtualenv`` is sourced after the new environment
+is created and activated.
+
 .. _scripts-preactivate:
 
 preactivate
             'user_scripts = virtualenvwrapper.user_scripts:post_mkvirtualenv_source',
             ],
 
+        'virtualenvwrapper.pre_cpvirtualenv': [
+            'user_scripts = virtualenvwrapper.user_scripts:pre_cpvirtualenv',
+            ],
+        'virtualenvwrapper.post_cpvirtualenv_source': [
+            'user_scripts = virtualenvwrapper.user_scripts:post_cpvirtualenv_source',
+            ],
+
         'virtualenvwrapper.pre_rmvirtualenv': [
             'user_scripts = virtualenvwrapper.user_scripts:pre_rmvirtualenv',
             ],

File tests/test_cd.sh

     assertSame "$VIRTUAL_ENV" "$(pwd)"
     cdvirtualenv bin
     assertSame "$VIRTUAL_ENV/bin" "$(pwd)"
-    cd "$(start_dir)"
+    cd "$start_dir"
 }
 
 test_cdsitepackages () {
     pyvers=$(python -V 2>&1 | cut -f2 -d' ' | cut -f1-2 -d.)
     sitepackages="$VIRTUAL_ENV/lib/python${pyvers}/site-packages"
     assertSame "$sitepackages" "$(pwd)"
-    cd "$(start_dir)"
+    cd "$start_dir"
 }
 
 test_cdsitepackages_with_arg () {
     mkdir -p "${sitepackage_subdir}"
     cdsitepackages subdir
     assertSame "$sitepackage_subdir" "$(pwd)"
-    cd "$(start_dir)"
+    cd "$start_dir"
 }
 
 test_cdvirtualenv_no_workon_home () {

File tests/test_cp.sh

     rm -rf "$WORKON_HOME"
     mkdir -p "$WORKON_HOME"
     source "$test_dir/../virtualenvwrapper.sh"
+    rm -f "$test_dir/catch_output"
     echo
-    rm -f "$test_dir/catch_output"
 }
 
 tearDown() {
     rm -rf "$WORKON_HOME"
 }
 
-
 test_cpvirtualenv () {
     mkvirtualenv "source"
-    (cd tests/testpackage && python setup.py install)
+    (cd tests/testpackage && python setup.py install) >/dev/null 2>&1
     cpvirtualenv "source" "destination"
-    deactivate
+    assertSame "destination" $(basename "$VIRTUAL_ENV")
     rmvirtualenv "source"
-    workon "destination"
     testscript="$(which testscript.py)"
     assertTrue "Environment test script not found in path" "[ $WORKON_HOME/destination/bin/testscript.py -ef $testscript ]"
     testscriptcontent="$(cat $testscript)"
 
 test_cprelocatablevirtualenv () {
     mkvirtualenv "source"
-    (cd tests/testpackage && python setup.py install)
+    (cd tests/testpackage && python setup.py install) >/dev/null 2>&1
     assertTrue "virtualenv --relocatable \"$WORKON_HOME/source\""
     cpvirtualenv "source" "destination"
     testscript="$(which testscript.py)"
     assertSame "$out" "virtualenvthatdoesntexist virtualenv doesn't exist"
 }
 
+test_hooks () {
+    mkvirtualenv "source"
+
+    export pre_test_dir=$(cd "$test_dir"; pwd)
+    echo "echo GLOBAL premkvirtualenv \`pwd\` \"\$@\" >> \"$pre_test_dir/catch_output\"" >> "$WORKON_HOME/premkvirtualenv"
+    chmod +x "$WORKON_HOME/premkvirtualenv"
+    echo "echo GLOBAL postmkvirtualenv >> $test_dir/catch_output" > "$WORKON_HOME/postmkvirtualenv"
+    echo "#!/bin/sh" > "$WORKON_HOME/precpvirtualenv"
+    echo "echo GLOBAL precpvirtualenv \`pwd\` \"\$@\" >> \"$pre_test_dir/catch_output\"" >> "$WORKON_HOME/precpvirtualenv"
+    chmod +x "$WORKON_HOME/precpvirtualenv"
+    echo "#!/bin/sh" > "$WORKON_HOME/postcpvirtualenv"
+    echo "echo GLOBAL postcpvirtualenv >> $test_dir/catch_output" > "$WORKON_HOME/postcpvirtualenv"
+
+    cpvirtualenv "source" "destination"
+
+    output=$(cat "$test_dir/catch_output")
+
+    expected="GLOBAL precpvirtualenv $WORKON_HOME source destination
+GLOBAL premkvirtualenv $WORKON_HOME destination
+GLOBAL postmkvirtualenv
+GLOBAL postcpvirtualenv"
+
+    assertSame "$expected" "$output"
+    rm -f "$WORKON_HOME/premkvirtualenv"
+    rm -f "$WORKON_HOME/postmkvirtualenv"
+    deactivate
+}
+
 . "$test_dir/shunit2"
 

File virtualenvwrapper.sh

     if [ $? -eq 0 ]
     then
         deactivate
+        unset -f deactivate >/dev/null 2>&1
     fi
 
     virtualenvwrapper_run_hook "pre_activate" "$env_name"
     
     source "$activate"
     
-    # Save the deactivate function from virtualenv
-    virtualenvwrapper_saved_deactivate=$(typeset -f deactivate)
+    # Save the deactivate function from virtualenv under a different name
+    virtualenvwrapper_original_deactivate=`typeset -f deactivate | sed 's/deactivate/virtualenv_deactivate/g'`
+    eval "$virtualenvwrapper_original_deactivate"
+    unset -f deactivate >/dev/null 2>&1
+#     virtualenvwrapper_saved_deactivate=$(tempfile --directory "$VIRTUALENVWRAPPER_TMPDIR")
+#     $(typeset -f deactivate | sed 's/deactivate/original_deactivate/g' > $virtualenvwrapper_saved_deactivate)
+#     echo "original_deactivate" >> $virtualenvwrapper_saved_deactivate
+#     echo "SAVED: \"$virtualenvwrapper_saved_deactivate\""
+#     cat $virtualenvwrapper_saved_deactivate
 
     # Replace the deactivate() function with a wrapper.
     eval 'deactivate () {
+
         # Call the local hook before the global so we can undo
         # any settings made by the local postactivate first.
         virtualenvwrapper_run_hook "pre_deactivate"
         env_postdeactivate_hook="$VIRTUAL_ENV/bin/postdeactivate"
         old_env=$(basename "$VIRTUAL_ENV")
         
-        # Restore the original definition of deactivate
-        eval "$virtualenvwrapper_saved_deactivate"
-
-        # Instead of recursing, this calls the now restored original function.
-        deactivate
+        # Call the original function.
+        #source "$virtualenvwrapper_saved_deactivate"
+        #rm -f "$virtualenvwrapper_saved_deactivate"
+        virtualenv_deactivate
 
         virtualenvwrapper_run_hook "post_deactivate" "$old_env"
+
+        # Remove this function
+        unset -f deactivate
+
     }'
     
     virtualenvwrapper_run_hook "post_activate"
 
     virtualenv "$target_env" --relocatable
     sed "s/VIRTUAL_ENV\(.*\)$env_name/VIRTUAL_ENV\1$new_env/g" < "$source_env/bin/activate" > "$target_env/bin/activate"
-    echo "Created $new_env virtualenv"
+
+    (cd "$WORKON_HOME" && 
+        virtualenvwrapper_run_hook "pre_cpvirtualenv" "$env_name" "$new_env" &&
+        virtualenvwrapper_run_hook "pre_mkvirtualenv" "$new_env"
+        )
     workon "$new_env"
+    virtualenvwrapper_run_hook "post_mkvirtualenv"
+    virtualenvwrapper_run_hook "post_cpvirtualenv"
 }
 
 #

File virtualenvwrapper/user_scripts.py

 [ -f "$WORKON_HOME/postmkvirtualenv" ] && source "$WORKON_HOME/postmkvirtualenv"
 """
 
+def pre_cpvirtualenv(args):
+    log.debug('pre_cpvirtualenv %s', str(args))
+    envname=args[0]
+    for filename, comment in LOCAL_HOOKS:
+        make_hook(os.path.join('$WORKON_HOME', envname, 'bin', filename), comment)
+    run_global('precpvirtualenv', *args)
+    return
+
+
+def post_cpvirtualenv_source(args):
+    return """
+#
+# Run user-provided scripts
+#
+[ -f "$WORKON_HOME/postcpvirtualenv" ] && source "$WORKON_HOME/postcpvirtualenv"
+"""
+
 
 def pre_rmvirtualenv(args):
     log.debug('pre_rmvirtualenv')