22import sys
33from pythonbrew .basecommand import Command
44from pythonbrew .define import PATH_PYTHONS , PATH_VENVS , PATH_ETC_VENV
5- from pythonbrew .util import get_using_python_pkgname , Subprocess , Package ,\
6- is_installed
5+ from pythonbrew .util import Subprocess , Package ,\
6+ is_installed , get_installed_pythons_pkgname , get_using_python_pkgname
77from pythonbrew .log import logger
88
99class VenvCommand (Command ):
@@ -20,16 +20,46 @@ def __init__(self):
2020 help = "Use the specified version of python." ,
2121 metavar = 'VERSION'
2222 )
23+ self .parser .add_option (
24+ "-a" , "--all" ,
25+ dest = "all" ,
26+ action = 'store_true' ,
27+ default = False ,
28+ help = "Show the all python environments." ,
29+ metavar = 'VERSION'
30+ )
31+ self .template_env = """export VIRTUALENVWRAPPER_PYTHON=%(venv_py)s
32+ export VIRTUALENVWRAPPER_VIRTUALENV=%(venv_venv)s
33+ export WORKON_HOME=%(workon_home)s
34+ export VIRTUALENVWRAPPER_HOOK_DIR=%(workon_home)s
35+ export VIRTUALENVWRAPPER_LOG_DIR=%(workon_home)s
36+ source %(venv_sh)s
37+ """
2338
2439 def run_command (self , options , args ):
2540 if not args :
2641 logger .error ('Unrecognized command line argument: ( see: \' pythonbrew help venv\' )' )
2742 sys .exit (1 )
2843 cmd = args [0 ]
29- if not cmd in ('create' , 'use ' , 'delete ' , 'list' ):
44+ if not cmd in ('create' , 'delete ' , 'use ' , 'list' ):
3045 logger .error ('Unrecognized command line argument: ( see: \' pythonbrew help venv\' )' )
3146 sys .exit (1 )
3247
48+ # find python2
49+ venv_pkgname = None
50+ for pkgname in reversed (get_installed_pythons_pkgname ()):
51+ # virtualenvwrapper require Python2
52+ venv_pkgver = Package (pkgname ).version
53+ if venv_pkgver >= '2.4' and venv_pkgver < '3' :
54+ venv_pkgname = pkgname
55+ break
56+ if not venv_pkgname :
57+ logger .error ('Can not create virtual environment before installing a python2. Try \' pythonbrew install <python2.4 - 2.7>\' .' )
58+ sys .exit (1 )
59+ venv_dir = os .path .join (PATH_PYTHONS , venv_pkgname )
60+ venv_bin = os .path .join (venv_dir , 'bin' )
61+
62+ # target python interpreter
3363 if options .python :
3464 pkgname = Package (options .python ).name
3565 if not is_installed (pkgname ):
@@ -38,36 +68,91 @@ def run_command(self, options, args):
3868 else :
3969 pkgname = get_using_python_pkgname ()
4070 if not pkgname :
41- logger .error ('Can not create virtual environment before using a python. Try \' pythonbrew install <some python>\' .' )
71+ logger .error ('Can not use venv command before using a python. Try \' pythonbrew switch <some python>\' .' )
4272 sys .exit (1 )
43- pkg_dir = os .path .join (PATH_PYTHONS , pkgname )
44- pkg_bin_dir = os .path .join (pkg_dir , 'bin' )
45-
46- self ._pkg_bin_dir = pkg_bin_dir
47- self ._venv_dir = os .path .join (PATH_VENVS , pkgname )
73+ self ._pkgname = pkgname
74+ self ._target_py = os .path .join (PATH_PYTHONS , pkgname , 'bin' , 'python' )
75+ self ._workon_home = os .path .join (PATH_VENVS , pkgname )
76+ self ._venv_py = os .path .join (venv_bin , 'python' )
77+ self ._venv_venv = os .path .join (venv_bin , 'virtualenv' )
78+ self ._venv_sh = os .path .join (venv_bin , 'virtualenvwrapper.sh' )
4879
4980 # has virtualenv & virtualenvwrapper?
50- if (not os .path .exists (os .path .join (pkg_bin_dir , 'virtualenvwrapper.sh' )) or
51- not os .path .exists (os .path .join (pkg_bin_dir , 'virtualenv' ))):
52- logger .info ('Installing virtualenv into %s' % pkg_dir )
81+ if not self ._venv_venv or not self ._venv_sh :
82+ logger .info ('Installing virtualenv into %s' % venv_dir )
5383 s = Subprocess (verbose = True )
54- s .shell ('%s %s %s' % (os .path .join (pkg_bin_dir ,'pip' ), 'install' , 'virtualenvwrapper' ))
84+ s .shell ('%s %s %s' % (os .path .join (venv_bin ,'pip' ), 'install' , 'virtualenvwrapper' ))
5585
56- # Initialize virtualenv
57- self ._init ()
86+ # Create a shell script
87+ try :
88+ self .__getattribute__ ('run_command_%s' % cmd )(options , args )
89+ except :
90+ logger .error ('`%s` command not found.' % cmd )
91+ sys .exit (1 )
92+
93+ def run_command_create (self , options , args ):
94+ output = [self .template_env % {'venv_py' : self ._venv_py ,
95+ 'venv_venv' : self ._venv_venv ,
96+ 'workon_home' : self ._workon_home ,
97+ 'venv_sh' : self ._venv_sh }]
98+ for arg in args [1 :]:
99+ output .append ("""echo '# Create `%(arg)s` environment into %(workon_home)s'
100+ mkvirtualenv -p '%(target_py)s' '%(arg)s'
101+ """ % {'arg' : arg ,
102+ 'workon_home' : self ._workon_home ,
103+ 'target_py' : self ._target_py })
104+ self ._write ('' .join (output ))
58105
59- # check
60- if cmd == 'use' :
61- if len (args ) < 2 :
62- logger .error ("Unrecognized command line argument: ( 'pythonbrew venv use <project>' )" )
63- sys .exit (1 )
64- elif cmd == 'list' :
65- logger .info ('# virtualenv for %s (found in %s)' % (pkgname , self ._venv_dir ))
106+ def run_command_delete (self , options , args ):
107+ output = [self .template_env % {'venv_py' : self ._venv_py ,
108+ 'venv_venv' : self ._venv_venv ,
109+ 'workon_home' : self ._workon_home ,
110+ 'venv_sh' : self ._venv_sh }]
111+ for arg in args [1 :]:
112+ output .append ("""echo '# Delete `%(arg)s` environment in %(workon_home)s'
113+ rmvirtualenv '%(arg)s'
114+ """ % {'arg' : arg ,
115+ 'workon_home' : self ._workon_home })
116+ self ._write ('' .join (output ))
117+
118+ def run_command_use (self , options , args ):
119+ if len (args ) < 2 :
120+ logger .error ("Unrecognized command line argument: ( 'pythonbrew venv use <project>' )" )
121+ sys .exit (1 )
122+ template = self .template_env + """echo '# Using `%(arg)s` environment (found in %(workon_home)s)'
123+ echo '# To leave an environment, simply run `deactivate`'
124+ workon '%(arg)s'
125+ """
126+ self ._write (template % {'venv_py' : self ._venv_py ,
127+ 'venv_venv' : self ._venv_venv ,
128+ 'workon_home' : self ._workon_home ,
129+ 'venv_sh' : self ._venv_sh ,
130+ 'arg' : args [1 ]})
66131
67- def _init (self ):
132+ def run_command_list (self , options , args ):
133+ template = self .template_env + """echo '# virtualenv for %(pkgname)s (found in %(workon_home)s)'
134+ workon
135+ """
136+ if options .all :
137+ output = []
138+ for pkgname in get_installed_pythons_pkgname ():
139+ workon_home = os .path .join (PATH_VENVS , pkgname )
140+ output .append (template % {'venv_py' : self ._venv_py ,
141+ 'venv_venv' : self ._venv_venv ,
142+ 'workon_home' : workon_home ,
143+ 'venv_sh' : self ._venv_sh ,
144+ 'pkgname' : pkgname })
145+ self ._write ('' .join (output ))
146+ else :
147+ self ._write (template % {'venv_py' : self ._venv_py ,
148+ 'venv_venv' : self ._venv_venv ,
149+ 'workon_home' : self ._workon_home ,
150+ 'venv_sh' : self ._venv_sh ,
151+ 'pkgname' : self ._pkgname })
152+
153+ def _write (self , src ):
68154 fp = open (PATH_ETC_VENV , 'w' )
69- fp .write ("VIRTUALENVWRAPPER_PYTHON=%s\n " % os .path .join (self ._pkg_bin_dir , 'python' ))
70- fp .write ("WORKON_HOME=%s" % self ._venv_dir )
155+ fp .write (src )
71156 fp .close ()
72-
157+
73158VenvCommand ()
0 commit comments