Skip to content

Commit 58cca48

Browse files
committed
First pass at speeding things up by making fewer calls into Python. Needs review.
1 parent a5dfd5b commit 58cca48

File tree

2 files changed

+62
-28
lines changed

2 files changed

+62
-28
lines changed

virtualenvwrapper.sh

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,25 @@ then
5757
VIRTUALENVWRAPPER_PYTHON="$(which python)"
5858
fi
5959

60-
# Normalize the directory name in case it includes
61-
# relative path components.
62-
WORKON_HOME=$("$VIRTUALENVWRAPPER_PYTHON" -c "import os; print os.path.abspath(os.path.expandvars(os.path.expanduser(\"$WORKON_HOME\")))")
63-
export WORKON_HOME
60+
# If the path is relative, prefix it with $HOME
61+
# (note: for compatibility)
62+
if echo "$WORKON_HOME" | grep -e '^[^/~]'
63+
then
64+
export WORKON_HOME="$HOME/$WORKON_HOME"
65+
fi
66+
67+
# Only call on Python to fix the path if it looks like the
68+
# path might contain stuff to expand.
69+
# (it might be possible to do this in shell, but I don't know a
70+
# cross-shell-safe way of doing it -wolever)
71+
if echo "$WORKON_HOME" | grep -e "[$~]"
72+
then
73+
# This will normalize the path by:
74+
# - Expanding variables (eg, $foo)
75+
# - Converting ~s to complete paths (eg, ~/ to /home/brian/ and ~arthur to /home/arthur)
76+
WORKON_HOME=$("$VIRTUALENVWRAPPER_PYTHON" -c "import os; print os.path.expandvars(os.path.expanduser(\"$WORKON_HOME\"))")
77+
export WORKON_HOME
78+
fi
6479

6580
# Verify that the WORKON_HOME directory exists
6681
virtualenvwrapper_verify_workon_home () {
@@ -74,43 +89,34 @@ virtualenvwrapper_verify_workon_home () {
7489

7590
#HOOK_VERBOSE_OPTION="-v"
7691

77-
# Use Python's tempfile module to create a temporary file
78-
# with a unique and not-likely-to-be-predictable name.
7992
# Expects 1 argument, the suffix for the new file.
8093
virtualenvwrapper_tempfile () {
81-
typeset base=$("$VIRTUALENVWRAPPER_PYTHON" -c "import tempfile; print tempfile.NamedTemporaryFile(prefix='virtualenvwrapper.').name")
82-
if [ -z "$base" ]
83-
then
84-
echo "${TMPDIR:-/tmp}/virtualenvwrapper.$$.`date +%s`.$1"
85-
else
86-
echo "$base.$1"
87-
fi
94+
tempfile "virtualenvwrapper-XXXXXX-$1"
8895
}
8996

9097
# Run the hooks
9198
virtualenvwrapper_run_hook () {
92-
# First anything that runs directly from the plugin
93-
"$VIRTUALENVWRAPPER_PYTHON" -c 'from virtualenvwrapper.hook_loader import main; main()' $HOOK_VERBOSE_OPTION "$@"
94-
# Now anything that wants to run inside this shell
9599
hook_script="$(virtualenvwrapper_tempfile hook)"
96-
"$VIRTUALENVWRAPPER_PYTHON" -c 'from virtualenvwrapper.hook_loader import main; main()' $HOOK_VERBOSE_OPTION \
97-
--source "$@" >>"$hook_script"
98-
source "$hook_script"
99-
rm -f "$hook_script"
100+
"$VIRTUALENVWRAPPER_PYTHON" -c 'from virtualenvwrapper.hook_loader import main; main()' $HOOK_VERBOSE_OPTION --run-hook-and-write-source "$hook_script" "$@"
101+
result=$?
102+
103+
if [ $result -eq 0 ]
104+
then
105+
source "$hook_script"
106+
fi
107+
rm -f "$hook_script" > /dev/null 2>&1
108+
return $result
100109
}
101110

102111
# Set up virtualenvwrapper properly
103112
virtualenvwrapper_initialize () {
104113
virtualenvwrapper_verify_workon_home -q || return 1
105-
# Test for the virtualenvwrapper package we need so we can report
106-
# an installation problem.
107-
"$VIRTUALENVWRAPPER_PYTHON" -c "import virtualenvwrapper.hook_loader" >/dev/null 2>&1
114+
virtualenvwrapper_run_hook "initialize"
108115
if [ $? -ne 0 ]
109116
then
110-
echo "virtualenvwrapper.sh: Could not find Python module virtualenvwrapper.hook_loader using VIRTUALENVWRAPPER_PYTHON=$VIRTUALENVWRAPPER_PYTHON. Is the PATH set properly?" 1>&2
117+
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
111118
return 1
112119
fi
113-
virtualenvwrapper_run_hook "initialize"
114120
}
115121

116122
# Verify that virtualenv is installed and visible

virtualenvwrapper/hook_loader.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import logging.handlers
1212
import optparse
1313
import os
14+
import sys
1415

1516
import pkg_resources
1617

@@ -20,6 +21,13 @@ def main():
2021
prog='virtualenvwrapper.hook_loader',
2122
description='Manage hooks for virtualenvwrapper',
2223
)
24+
25+
parser.add_option('-S', '--run-hook-and-write-source',
26+
help='Runs "hook" and runs "<hook>_source", writing the ' +
27+
'result to <file>',
28+
dest='source_filename',
29+
default=None,
30+
)
2331
parser.add_option('-s', '--source',
2432
help='Print the shell commands to be run in the current shell',
2533
action='store_true',
@@ -84,9 +92,30 @@ def main():
8492
if not args:
8593
parser.error('Please specify the hook to run')
8694
hook = args[0]
95+
96+
if options.sourcing and options.source_filename:
97+
parser.error('--source and --run-hook-and-write-source are mutually ' +
98+
'exclusive.')
99+
87100
if options.sourcing:
88101
hook += '_source'
89102

103+
run_hooks(hook, options, args)
104+
105+
if options.source_filename:
106+
options.sourcing = True
107+
output = open(options.source_filename, "w")
108+
try:
109+
run_hooks(hook + '_source', options, args, output)
110+
finally:
111+
output.close()
112+
113+
return 0
114+
115+
def run_hooks(hook, options, args, output=None):
116+
if output is None:
117+
output = sys.stdout
118+
90119
for ep in pkg_resources.iter_entry_points('virtualenvwrapper.%s' % hook):
91120
if options.names and ep.name not in options.names:
92121
continue
@@ -99,12 +128,11 @@ def main():
99128
# be run in the calling shell.
100129
contents = (plugin(args[1:]) or '').strip()
101130
if contents:
102-
print contents
103-
print
131+
output.write(contents)
132+
output.write("\n")
104133
else:
105134
# Just run the plugin ourselves
106135
plugin(args[1:])
107-
return 0
108136

109137
if __name__ == '__main__':
110138
main()

0 commit comments

Comments
 (0)