88
99import logging
1010import os
11+ import re
1112import stat
1213import subprocess
14+ import sys
1315
1416import pkg_resources
1517
1618log = 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+ msys = True
24+ script_folder = 'Scripts'
25+ else :
26+ script_folder = 'bin'
27+
1828
1929def run_script (script_path , * args ):
2030 """Execute a script in a subshell.
2131 """
2232 if os .path .exists (script_path ):
2333 cmd = [script_path ] + list (args )
34+ if msys :
35+ cmd = [os .path .join (os .environ ['MSYS_HOME' ],'bin' ,'sh.exe' )] + cmd
2436 log .debug ('running %s' , str (cmd ))
2537 try :
2638 return_code = subprocess .call (cmd )
@@ -33,7 +45,7 @@ def run_script(script_path, *args):
3345def run_global (script_name , * args ):
3446 """Run a script from $VIRTUALENVWRAPPER_HOOK_DIR.
3547 """
36- script_path = os . path . expandvars ( os . path . join ( '$VIRTUALENVWRAPPER_HOOK_DIR' , script_name ) )
48+ script_path = get_path ( '$VIRTUALENVWRAPPER_HOOK_DIR' , script_name )
3749 run_script (script_path , * args )
3850 return
3951
@@ -101,7 +113,7 @@ def make_hook(filename, comment):
101113 :param filename: The name of the file to write.
102114 :param comment: The comment to insert into the file.
103115 """
104- filename = os . path . expanduser ( os . path . expandvars ( filename ) )
116+ filename = get_path ( filename )
105117 if not os .path .exists (filename ):
106118 log .info ('creating %s' , filename )
107119 f = open (filename , 'w' )
@@ -122,7 +134,7 @@ def make_hook(filename, comment):
122134
123135def initialize (args ):
124136 for filename , comment in GLOBAL_HOOKS :
125- make_hook (os . path . join ('$VIRTUALENVWRAPPER_HOOK_DIR' , filename ), comment )
137+ make_hook (get_path ('$VIRTUALENVWRAPPER_HOOK_DIR' , filename ), comment )
126138 return
127139
128140
@@ -138,7 +150,7 @@ def pre_mkvirtualenv(args):
138150 log .debug ('pre_mkvirtualenv %s' , str (args ))
139151 envname = args [0 ]
140152 for filename , comment in LOCAL_HOOKS :
141- make_hook (os . path . join ('$WORKON_HOME' , envname , 'bin' , filename ), comment )
153+ make_hook (get_path ('$WORKON_HOME' , envname , script_folder , filename ), comment )
142154 run_global ('premkvirtualenv' , * args )
143155 return
144156
@@ -155,7 +167,7 @@ def pre_cpvirtualenv(args):
155167 log .debug ('pre_cpvirtualenv %s' , str (args ))
156168 envname = args [0 ]
157169 for filename , comment in LOCAL_HOOKS :
158- make_hook (os . path . join ('$WORKON_HOME' , envname , 'bin' , filename ), comment )
170+ make_hook (get_path ('$WORKON_HOME' , envname , script_folder , filename ), comment )
159171 run_global ('precpvirtualenv' , * args )
160172 return
161173
@@ -184,7 +196,7 @@ def post_rmvirtualenv(args):
184196def pre_activate (args ):
185197 log .debug ('pre_activate' )
186198 run_global ('preactivate' , * args )
187- script_path = os . path . expandvars ( os . path . join ( '$WORKON_HOME' , args [0 ], 'bin' , 'preactivate' ) )
199+ script_path = get_path ( '$WORKON_HOME' , args [0 ], script_folder , 'preactivate' )
188200 run_script (script_path , * args )
189201 return
190202
@@ -227,6 +239,22 @@ def post_deactivate_source(args):
227239def get_env_details (args ):
228240 log .debug ('get_env_details' )
229241 run_global ('get_env_details' , * args )
230- script_path = os . path . expandvars ( os . path . join ( '$WORKON_HOME' , args [0 ], 'bin' , 'get_env_details' ) )
242+ script_path = get_path ( '$WORKON_HOME' , args [0 ], script_folder , 'get_env_details' )
231243 run_script (script_path , * args )
232244 return
245+
246+ def get_path (* args ):
247+ '''
248+ Get a full path from args.
249+ Path separator is determined according to the os and the shell and allow to use msys.
250+ Variables and user are expanded during the process.
251+ '''
252+ path = os .path .expanduser (os .path .expandvars (os .path .join (* args )))
253+ if msys :
254+ # MSYS accept unix or Win32 and sometimes it conduce to mixed style paths
255+ if re .match (r'^/[a-zA-Z](/|^)' , path ):
256+ # msys path could starts with '/c/'-form drive letter
257+ path = '' .join ((path [1 ],':' ,path [2 :]))
258+ path = path .replace ('/' , os .sep )
259+
260+ return os .path .abspath (path )
0 commit comments