Skip to content

Commit 9fbc327

Browse files
committed
update venv command
1 parent 4aa6220 commit 9fbc327

8 files changed

Lines changed: 134 additions & 57 deletions

File tree

pythonbrew/commands/uninstall.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import os
22
from pythonbrew.basecommand import Command
3-
from pythonbrew.define import PATH_PYTHONS, PATH_BIN
3+
from pythonbrew.define import PATH_PYTHONS, PATH_BIN, PATH_VENVS
44
from pythonbrew.util import off, rm_r, Package, get_using_python_pkgname, unlink,\
55
is_installed
66
from pythonbrew.log import logger
@@ -17,6 +17,7 @@ def run_command(self, options, args):
1717
pkg = Package(arg)
1818
pkgname = pkg.name
1919
pkgpath = os.path.join(PATH_PYTHONS, pkgname)
20+
venvpath = os.path.join(PATH_VENVS, pkgname)
2021
if not is_installed(pkgname):
2122
logger.info("`%s` is not installed." % pkgname)
2223
continue
@@ -31,6 +32,7 @@ def run_command(self, options, args):
3132
if os.path.isfile(tgtpath) and os.path.samefile(path, tgtpath):
3233
unlink(path)
3334
rm_r(pkgpath)
35+
rm_r(venvpath)
3436
else:
3537
self.parser.print_help()
3638

pythonbrew/commands/venv.py

Lines changed: 111 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
import sys
33
from pythonbrew.basecommand import Command
44
from 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
77
from pythonbrew.log import logger
88

99
class 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+
73158
VenvCommand()

pythonbrew/define.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
PATH_ETC_CURRENT = os.path.join(PATH_ETC,'current')
4242
PATH_ETC_TEMP = os.path.join(PATH_ETC,'temp')
4343
PATH_ETC_CONFIG = os.path.join(PATH_ETC,'config.cfg')
44-
PATH_ETC_VENV = os.path.join(PATH_ETC, 'venv')
44+
PATH_ETC_VENV = os.path.join(PATH_ETC, 'venv.run')
4545

4646
# read config.cfg
4747
config = ConfigParser.SafeConfigParser()

pythonbrew/etc/bashrc

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -65,35 +65,10 @@ __pythonbrew_venv()
6565
{
6666
command pythonbrew "$@"
6767
if [[ $? == 0 ]] ; then
68-
source "$PATH_ETC/venv"
69-
args=()
70-
for arg in "$@" ; do
71-
if [[ $param_skip = 1 ]] ; then
72-
param_skip=0
73-
continue
74-
fi
75-
case $arg in
76-
-p) param_skip=1 ; continue ;;
77-
--python) param_skip=1 ; continue ;;
78-
esac
79-
args=("${args[@]}" $arg)
80-
done
81-
for arg in ${args[@]} ; do
82-
case $arg in
83-
create)
84-
for proj in ${args[@]:2} ; do
85-
mkvirtualenv $proj
86-
done
87-
;;
88-
delete)
89-
for proj in ${args[@]:2} ; do
90-
rmvirtualenv $proj
91-
done
92-
;;
93-
use) workon ${args[2]} ;;
94-
list) workon ;;
95-
esac
96-
done
68+
if [[ -s "$PATH_ETC/venv.run" ]] ; then
69+
source "$PATH_ETC/venv.run"
70+
cat /dev/null > "$PATH_ETC/venv.run"
71+
fi
9772
fi
9873
}
9974

pythonbrew/util.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,10 @@ def get_using_python_pkgname():
221221
return d
222222
return None
223223

224+
def get_installed_pythons_pkgname():
225+
"""Get the installed python versions list."""
226+
return [d for d in sorted(os.listdir(PATH_PYTHONS))]
227+
224228
def is_installed(name):
225229
pkgname = Package(name).name
226230
pkgdir = os.path.join(PATH_PYTHONS, pkgname)

tests/test_10_venv.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class VenvOptions(object):
2+
python = '2.6.6'
3+
all = False
4+
5+
def test_venv():
6+
from pythonbrew.commands.venv import VenvCommand
7+
c = VenvCommand()
8+
c.run_command(VenvOptions(), ['create', 'aaa'])
9+
c.run_command(VenvOptions(), ['list'])
10+
c.run_command(VenvOptions(), ['use', 'aaa'])
11+
c.run_command(VenvOptions(), ['delete', 'aaa'])

0 commit comments

Comments
 (0)