1. Luke Plant
  2. virtualenvwrapper

Commits

David Wolever  committed 03a5996

First pass at speeding things up by making fewer calls into Python. Needs review.

  • Participants
  • Parent commits f122464
  • Branches default

Comments (0)

Files changed (2)

File virtualenvwrapper.sh

View file
     VIRTUALENVWRAPPER_PYTHON="$(which python)"
 fi
 
-# Normalize the directory name in case it includes 
-# relative path components.
-WORKON_HOME=$("$VIRTUALENVWRAPPER_PYTHON" -c "import os; print os.path.abspath(os.path.expandvars(os.path.expanduser(\"$WORKON_HOME\")))")
-export WORKON_HOME
+# If the path is relative, prefix it with $HOME
+# (note: for compatibility)
+if echo "$WORKON_HOME" | grep -e '^[^/~]'
+then
+    export WORKON_HOME="$HOME/$WORKON_HOME"
+fi
+
+# Only call on Python to fix the path if it looks like the
+# path might contain stuff to expand.
+# (it might be possible to do this in shell, but I don't know a
+# cross-shell-safe way of doing it -wolever)
+if echo "$WORKON_HOME" | grep -e "[$~]"
+then
+    # This will normalize the path by:
+    # - Expanding variables (eg, $foo)
+    # - Converting ~s to complete paths (eg, ~/ to /home/brian/ and ~arthur to /home/arthur)
+    WORKON_HOME=$("$VIRTUALENVWRAPPER_PYTHON" -c "import os; print os.path.expandvars(os.path.expanduser(\"$WORKON_HOME\"))")
+    export WORKON_HOME
+fi
 
 # Verify that the WORKON_HOME directory exists
 virtualenvwrapper_verify_workon_home () {
 
 #HOOK_VERBOSE_OPTION="-v"
 
-# Use Python's tempfile module to create a temporary file
-# with a unique and not-likely-to-be-predictable name.
 # Expects 1 argument, the suffix for the new file.
 virtualenvwrapper_tempfile () {
-    typeset base=$("$VIRTUALENVWRAPPER_PYTHON" -c "import tempfile; print tempfile.NamedTemporaryFile(prefix='virtualenvwrapper.').name")
-    if [ -z "$base" ]
-    then
-        echo "${TMPDIR:-/tmp}/virtualenvwrapper.$$.`date +%s`.$1"
-    else
-        echo "$base.$1"
-    fi
+    tempfile "virtualenvwrapper-XXXXXX-$1"
 }
 
 # Run the hooks
 virtualenvwrapper_run_hook () {
-    # First anything that runs directly from the plugin
-    "$VIRTUALENVWRAPPER_PYTHON" -c 'from virtualenvwrapper.hook_loader import main; main()' $HOOK_VERBOSE_OPTION "$@"
-    # Now anything that wants to run inside this shell
     hook_script="$(virtualenvwrapper_tempfile hook)"
-    "$VIRTUALENVWRAPPER_PYTHON" -c 'from virtualenvwrapper.hook_loader import main; main()' $HOOK_VERBOSE_OPTION \
-        --source "$@" >>"$hook_script"
-    source "$hook_script"
-    rm -f "$hook_script"
+    "$VIRTUALENVWRAPPER_PYTHON" -c 'from virtualenvwrapper.hook_loader import main; main()' $HOOK_VERBOSE_OPTION --run-hook-and-write-source "$hook_script" "$@"
+    result=$?
+    
+    if [ $result -eq 0 ]
+    then
+        source "$hook_script"
+    fi
+    rm -f "$hook_script" > /dev/null 2>&1 
+    return $result
 }
 
 # Set up virtualenvwrapper properly
 virtualenvwrapper_initialize () {
     virtualenvwrapper_verify_workon_home -q || return 1
-    # Test for the virtualenvwrapper package we need so we can report
-    # an installation problem.
-    "$VIRTUALENVWRAPPER_PYTHON" -c "import virtualenvwrapper.hook_loader" >/dev/null 2>&1
+    virtualenvwrapper_run_hook "initialize"
     if [ $? -ne 0 ]
     then
-        echo "virtualenvwrapper.sh: Could not find Python module virtualenvwrapper.hook_loader using VIRTUALENVWRAPPER_PYTHON=$VIRTUALENVWRAPPER_PYTHON. Is the PATH set properly?" 1>&2
+        echo "virtualenvwrapper.sh: Python encountered a problem. If Python could not import the module virtualenvwrapper.hook_loader, check that virtualenv has been installed for VIRTUALENVWRAPPER_PYTHON=$VIRTUALENVWRAPPER_PYTHON and that PATH set properly." 1>&2
         return 1
     fi
-    virtualenvwrapper_run_hook "initialize"
 }
 
 # Verify that virtualenv is installed and visible

File virtualenvwrapper/hook_loader.py

View file
 import logging.handlers
 import optparse
 import os
+import sys
 
 import pkg_resources
 
         prog='virtualenvwrapper.hook_loader',
         description='Manage hooks for virtualenvwrapper',
         )
+
+    parser.add_option('-S', '--run-hook-and-write-source',
+                      help='Runs "hook" and runs "<hook>_source", writing the ' +
+                           'result to <file>',
+                      dest='source_filename',
+                      default=None,
+                      )
     parser.add_option('-s', '--source',
                       help='Print the shell commands to be run in the current shell',
                       action='store_true',
     if not args:
         parser.error('Please specify the hook to run')
     hook = args[0]
+
+    if options.sourcing and options.source_filename:
+        parser.error('--source and --run-hook-and-write-source are mutually ' +
+                     'exclusive.')
+
     if options.sourcing:
         hook += '_source'
 
+    run_hooks(hook, options, args)
+
+    if options.source_filename:
+        options.sourcing = True
+        output = open(options.source_filename, "w")
+        try:
+            run_hooks(hook + '_source', options, args, output)
+        finally:
+            output.close()
+
+    return 0
+
+def run_hooks(hook, options, args, output=None):
+    if output is None:
+        output = sys.stdout
+
     for ep in pkg_resources.iter_entry_points('virtualenvwrapper.%s' % hook):
         if options.names and ep.name not in options.names:
             continue
             # be run in the calling shell.
             contents = (plugin(args[1:]) or '').strip()
             if contents:
-                print contents
-                print
+                output.write(contents)
+                output.write("\n")
         else:
             # Just run the plugin ourselves
             plugin(args[1:])
-    return 0
 
 if __name__ == '__main__':
     main()