Skip to content

Commit 4b0dfdb

Browse files
committed
merge in patches from noirbizarre to add support for MSYS environment; clean up doc addition; fix resulting problem is lsvirtualenv
2 parents daf7a3c + c25649b commit 4b0dfdb

File tree

4 files changed

+117
-30
lines changed

4 files changed

+117
-30
lines changed

docs/en/history.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ Release History
55
dev
66

77
- Use VIRTUALENVWRAPPER_VIRTUALENV in `cpvirtualenv` (:bbissue:`104`).
8+
- Add support for `MSYS <http://www.mingw.org/wiki/MSYS>`_
9+
environment under Windows. Contributed by Axel
10+
H. (:bbuser:`noirbizarre`).
811

912
2.7.2
1013

docs/en/install.rst

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,3 +196,29 @@ supported. In your startup file, change ``source
196196
/usr/local/bin/virtualenvwrapper.sh``.
197197

198198
.. _pip: http://pypi.python.org/pypi/pip
199+
200+
Using virtualenvwrapper Under MSys
201+
==================================
202+
203+
It is possible to use virtualenv wrapper under `MSYS
204+
<http://www.mingw.org/wiki/MSYS>`_ with a native Windows Python
205+
installation. In order to make it work, you need to define an extra
206+
environment variable named ``MSYS_HOME`` containing the root path to
207+
the MSYS installation.
208+
209+
::
210+
211+
export WORKON_HOME=$HOME/.virtualenvs
212+
export MSYS_HOME=/c/msys/1.0
213+
source /usr/local/bin/virtualenvwrapper.sh
214+
215+
or::
216+
217+
export WORKON_HOME=$HOME/.virtualenvs
218+
export MSYS_HOME=C:\msys\1.0
219+
source /usr/local/bin/virtualenvwrapper.sh
220+
221+
Depending on your MSYS setup, you may need to install the `MSYS mktemp
222+
binary`_ in the ``MSYS_HOME/bin`` folder.
223+
224+
.. _MSYS mktemp binary: http://sourceforge.net/projects/mingw/files/MSYS/mktemp/

virtualenvwrapper.sh

Lines changed: 50 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,15 @@ then
5656
VIRTUALENVWRAPPER_VIRTUALENV="virtualenv"
5757
fi
5858

59+
# Define script folder depending on the platorm (Win32/Unix)
60+
VIRTUALENVWRAPPER_ENV_BIN_DIR="bin"
61+
if [ "$OS" = "Windows_NT" ] && [ "$MSYSTEM" = "MINGW32" ]
62+
then
63+
# Only assign this for msys, cygwin use standard Unix paths
64+
# and its own python installation
65+
VIRTUALENVWRAPPER_ENV_BIN_DIR="Scripts"
66+
fi
67+
5968
virtualenvwrapper_derive_workon_home() {
6069
typeset workon_home_dir="$WORKON_HOME"
6170

@@ -326,8 +335,8 @@ virtualenvwrapper_show_workon_options () {
326335
# NOTE: DO NOT use ls here because colorized versions spew control characters
327336
# into the output list.
328337
# echo seems a little faster than find, even with -depth 3.
329-
(\cd "$WORKON_HOME"; for f in */bin/activate; do echo $f; done) 2>/dev/null | \sed 's|^\./||' | \sed 's|/bin/activate||' | \sort | (unset GREP_OPTIONS; \egrep -v '^\*$')
330-
338+
(\cd "$WORKON_HOME"; for f in */$VIRTUALENVWRAPPER_ENV_BIN_DIR/activate; do echo $f; done) 2>/dev/null | \sed 's|^\./||' | \sed "s|/$VIRTUALENVWRAPPER_ENV_BIN_DIR/activate||" | \sort | (unset GREP_OPTIONS; \egrep -v '^\*$')
339+
331340
# (\cd "$WORKON_HOME"; find -L . -depth 3 -path '*/bin/activate') | sed 's|^\./||' | sed 's|/bin/activate||' | sort
332341
}
333342

@@ -342,23 +351,43 @@ _lsvirtualenv_usage () {
342351
#
343352
# Usage: lsvirtualenv [-l]
344353
lsvirtualenv () {
345-
typeset -a args
346-
args=($(getopt blh "$@"))
347-
if [ $? != 0 ]
354+
355+
typeset long_mode=true
356+
if command -v "getopts" &> /dev/null
348357
then
349-
_lsvirtualenv_usage
350-
return 1
358+
# Use getopts when possible
359+
OPTIND=1
360+
while getopts ":blh" opt "$@"
361+
do
362+
case "$opt" in
363+
l) long_mode=true;;
364+
b) long_mode=false;;
365+
h) _lsvirtualenv_usage;
366+
return 1;;
367+
?) echo "Invalid option: -$OPTARG" >&2;
368+
_lsvirtualenv_usage;
369+
return 1;;
370+
esac
371+
done
372+
else
373+
# fallback on getopt for other shell
374+
typeset -a args
375+
args=($(getopt blh "$@"))
376+
if [ $? != 0 ]
377+
then
378+
_lsvirtualenv_usage
379+
return 1
380+
fi
381+
for opt in $args
382+
do
383+
case "$opt" in
384+
-l) long_mode=true;;
385+
-b) long_mode=false;;
386+
-h) _lsvirtualenv_usage;
387+
return 1;;
388+
esac
389+
done
351390
fi
352-
typeset long_mode=true
353-
for opt in $args
354-
do
355-
case "$opt" in
356-
-l) long_mode=true;;
357-
-b) long_mode=false;;
358-
-h) _lsvirtualenv_usage;
359-
return 1;;
360-
esac
361-
done
362391

363392
if $long_mode
364393
then
@@ -406,7 +435,7 @@ workon () {
406435
virtualenvwrapper_verify_workon_home || return 1
407436
virtualenvwrapper_verify_workon_environment $env_name || return 1
408437

409-
activate="$WORKON_HOME/$env_name/bin/activate"
438+
activate="$WORKON_HOME/$env_name/$VIRTUALENVWRAPPER_ENV_BIN_DIR/activate"
410439
if [ ! -f "$activate" ]
411440
then
412441
echo "ERROR: Environment '$WORKON_HOME/$env_name' does not contain an activate script." >&2
@@ -439,7 +468,7 @@ workon () {
439468
# any settings made by the local postactivate first.
440469
virtualenvwrapper_run_hook "pre_deactivate"
441470
442-
env_postdeactivate_hook="$VIRTUAL_ENV/bin/postdeactivate"
471+
env_postdeactivate_hook="$VIRTUAL_ENV/$VIRTUALENVWRAPPER_ENV_BIN_DIR/postdeactivate"
443472
old_env=$(basename "$VIRTUAL_ENV")
444473
445474
# Call the original function.
@@ -604,7 +633,7 @@ cpvirtualenv() {
604633
fi
605634

606635
\cp -r "$source_env" "$target_env"
607-
for script in $( \ls $target_env/bin/* )
636+
for script in $( \ls $target_env/$VIRTUALENVWRAPPER_ENV_BIN_DIR/* )
608637
do
609638
newscript="$script-new"
610639
\sed "s|$source_env|$target_env|g" < "$script" > "$newscript"
@@ -613,7 +642,7 @@ cpvirtualenv() {
613642
done
614643

615644
"$VIRTUALENVWRAPPER_VIRTUALENV" "$target_env" --relocatable
616-
\sed "s/VIRTUAL_ENV\(.*\)$env_name/VIRTUAL_ENV\1$new_env/g" < "$source_env/bin/activate" > "$target_env/bin/activate"
645+
\sed "s/VIRTUAL_ENV\(.*\)$env_name/VIRTUAL_ENV\1$new_env/g" < "$source_env/$VIRTUALENVWRAPPER_ENV_BIN_DIR/activate" > "$target_env/$VIRTUALENVWRAPPER_ENV_BIN_DIR/activate"
617646

618647
(\cd "$WORKON_HOME" && (
619648
virtualenvwrapper_run_hook "pre_cpvirtualenv" "$env_name" "$new_env";

virtualenvwrapper/user_scripts.py

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,32 @@
88

99
import logging
1010
import os
11+
import re
1112
import stat
1213
import subprocess
14+
import sys
1315

1416
import pkg_resources
1517

1618
log = logging.getLogger(__name__)
1719

20+
21+
# Are we running under msys
22+
if sys.platform == 'win32' and os.environ.get('OS') == 'Windows_NT' and os.environ.get('MSYSTEM') == 'MINGW32':
23+
is_msys = True
24+
script_folder = 'Scripts'
25+
else:
26+
is_msys = False
27+
script_folder = 'bin'
28+
1829

1930
def run_script(script_path, *args):
2031
"""Execute a script in a subshell.
2132
"""
2233
if os.path.exists(script_path):
2334
cmd = [script_path] + list(args)
35+
if is_msys:
36+
cmd = [get_path(os.environ['MSYS_HOME'],'bin','sh.exe')] + cmd
2437
log.debug('running %s', str(cmd))
2538
try:
2639
return_code = subprocess.call(cmd)
@@ -33,7 +46,7 @@ def run_script(script_path, *args):
3346
def run_global(script_name, *args):
3447
"""Run a script from $VIRTUALENVWRAPPER_HOOK_DIR.
3548
"""
36-
script_path = os.path.expandvars(os.path.join('$VIRTUALENVWRAPPER_HOOK_DIR', script_name))
49+
script_path = get_path('$VIRTUALENVWRAPPER_HOOK_DIR', script_name)
3750
run_script(script_path, *args)
3851
return
3952

@@ -101,7 +114,7 @@ def make_hook(filename, comment):
101114
:param filename: The name of the file to write.
102115
:param comment: The comment to insert into the file.
103116
"""
104-
filename = os.path.expanduser(os.path.expandvars(filename))
117+
filename = get_path(filename)
105118
if not os.path.exists(filename):
106119
log.info('creating %s', filename)
107120
f = open(filename, 'w')
@@ -122,7 +135,7 @@ def make_hook(filename, comment):
122135

123136
def initialize(args):
124137
for filename, comment in GLOBAL_HOOKS:
125-
make_hook(os.path.join('$VIRTUALENVWRAPPER_HOOK_DIR', filename), comment)
138+
make_hook(get_path('$VIRTUALENVWRAPPER_HOOK_DIR', filename), comment)
126139
return
127140

128141

@@ -138,7 +151,7 @@ def pre_mkvirtualenv(args):
138151
log.debug('pre_mkvirtualenv %s', str(args))
139152
envname=args[0]
140153
for filename, comment in LOCAL_HOOKS:
141-
make_hook(os.path.join('$WORKON_HOME', envname, 'bin', filename), comment)
154+
make_hook(get_path('$WORKON_HOME', envname, script_folder, filename), comment)
142155
run_global('premkvirtualenv', *args)
143156
return
144157

@@ -155,7 +168,7 @@ def pre_cpvirtualenv(args):
155168
log.debug('pre_cpvirtualenv %s', str(args))
156169
envname=args[0]
157170
for filename, comment in LOCAL_HOOKS:
158-
make_hook(os.path.join('$WORKON_HOME', envname, 'bin', filename), comment)
171+
make_hook(get_path('$WORKON_HOME', envname, script_folder, filename), comment)
159172
run_global('precpvirtualenv', *args)
160173
return
161174

@@ -184,7 +197,7 @@ def post_rmvirtualenv(args):
184197
def pre_activate(args):
185198
log.debug('pre_activate')
186199
run_global('preactivate', *args)
187-
script_path = os.path.expandvars(os.path.join('$WORKON_HOME', args[0], 'bin', 'preactivate'))
200+
script_path = get_path('$WORKON_HOME', args[0], script_folder, 'preactivate')
188201
run_script(script_path, *args)
189202
return
190203

@@ -196,7 +209,7 @@ def post_activate_source(args):
196209
# Run user-provided scripts
197210
#
198211
[ -f "$VIRTUALENVWRAPPER_HOOK_DIR/postactivate" ] && source "$VIRTUALENVWRAPPER_HOOK_DIR/postactivate"
199-
[ -f "$VIRTUAL_ENV/bin/postactivate" ] && source "$VIRTUAL_ENV/bin/postactivate"
212+
[ -f "$VIRTUAL_ENV/$VIRTUALENVWRAPPER_ENV_BIN_DIR/postactivate" ] && source "$VIRTUAL_ENV/$VIRTUALENVWRAPPER_ENV_BIN_DIR/postactivate"
200213
"""
201214

202215

@@ -206,7 +219,7 @@ def pre_deactivate_source(args):
206219
#
207220
# Run user-provided scripts
208221
#
209-
[ -f "$VIRTUAL_ENV/bin/predeactivate" ] && source "$VIRTUAL_ENV/bin/predeactivate"
222+
[ -f "$VIRTUAL_ENV/$VIRTUALENVWRAPPER_ENV_BIN_DIR/predeactivate" ] && source "$VIRTUAL_ENV/$VIRTUALENVWRAPPER_ENV_BIN_DIR/predeactivate"
210223
[ -f "$VIRTUALENVWRAPPER_HOOK_DIR/predeactivate" ] && source "$VIRTUALENVWRAPPER_HOOK_DIR/predeactivate"
211224
"""
212225

@@ -227,6 +240,22 @@ def post_deactivate_source(args):
227240
def get_env_details(args):
228241
log.debug('get_env_details')
229242
run_global('get_env_details', *args)
230-
script_path = os.path.expandvars(os.path.join('$WORKON_HOME', args[0], 'bin', 'get_env_details'))
243+
script_path = get_path('$WORKON_HOME', args[0], script_folder, 'get_env_details')
231244
run_script(script_path, *args)
232245
return
246+
247+
def get_path(*args):
248+
'''
249+
Get a full path from args.
250+
Path separator is determined according to the os and the shell and allow to use is_msys.
251+
Variables and user are expanded during the process.
252+
'''
253+
path = os.path.expanduser(os.path.expandvars(os.path.join(*args)))
254+
if is_msys:
255+
# MSYS accept unix or Win32 and sometimes it drives to mixed style paths
256+
if re.match(r'^/[a-zA-Z](/|^)', path):
257+
# msys path could starts with '/c/'-form drive letter
258+
path = ''.join((path[1],':',path[2:]))
259+
path = path.replace('/', os.sep)
260+
261+
return os.path.abspath(path)

0 commit comments

Comments
 (0)