diff --git a/pythonbrew/commands/buildout.py b/pythonbrew/commands/buildout.py index bf81a40..879db36 100644 --- a/pythonbrew/commands/buildout.py +++ b/pythonbrew/commands/buildout.py @@ -3,7 +3,7 @@ import sys import subprocess from pythonbrew.basecommand import Command from pythonbrew.define import PATH_PYTHONS, BOOTSTRAP_DLSITE, PATH_DISTS -from pythonbrew.util import Package, get_current_python_path, Link +from pythonbrew.util import Package, get_current_use_pkgname, Link, is_installed from pythonbrew.log import logger from pythonbrew.downloader import Downloader @@ -21,18 +21,19 @@ class BuildoutCommand(Command): help="Use the specified version of python.", metavar='VERSION' ) - self.parser.disable_interspersed_args() def run_command(self, options, args): if options.python: - python = Package(options.python).name - python = os.path.join(PATH_PYTHONS, python, 'bin', 'python') - if not os.path.isfile(python): - logger.info('%s is not installed.' % options.python) - sys.exit(1) + pkgname = Package(options.python).name else: - python = get_current_python_path() - logger.info('Using %s' % python) + pkgname = get_current_use_pkgname() + if not is_installed(pkgname): + logger.info('%s is not installed.' % pkgname) + sys.exit(1) + logger.info('Using %s' % pkgname) + + # build a path + python = os.path.join(PATH_PYTHONS, pkgname, 'bin', 'python') # Download bootstrap.py download_url = BOOTSTRAP_DLSITE diff --git a/pythonbrew/commands/list.py b/pythonbrew/commands/list.py index 1c9f76d..f0e3ccc 100644 --- a/pythonbrew/commands/list.py +++ b/pythonbrew/commands/list.py @@ -3,7 +3,7 @@ import re from pythonbrew.basecommand import Command from pythonbrew.define import PYTHON_VERSION_URL, LATEST_VERSIONS_OF_PYTHON,\ PATH_PYTHONS -from pythonbrew.util import Package, get_current_python_path +from pythonbrew.util import Package, get_current_use_pkgname from pythonbrew.log import logger class ListCommand(Command): @@ -36,9 +36,9 @@ class ListCommand(Command): def installed(self, options, args): logger.info('# installed pythons') - cur = get_current_python_path() + cur = get_current_use_pkgname() for d in sorted(os.listdir(PATH_PYTHONS)): - if cur and os.path.samefile(cur, os.path.join(PATH_PYTHONS, d, 'bin','python')): + if cur and cur == d: logger.info('%s (*)' % d) cur = None else: diff --git a/pythonbrew/commands/switch.py b/pythonbrew/commands/switch.py index 2fcfc29..d25e5c5 100644 --- a/pythonbrew/commands/switch.py +++ b/pythonbrew/commands/switch.py @@ -2,7 +2,7 @@ import os import sys from pythonbrew.basecommand import Command from pythonbrew.define import PATH_PYTHONS, PATH_BIN -from pythonbrew.util import Package, set_current_path +from pythonbrew.util import Package, set_current_path, is_installed from pythonbrew.log import logger class SwitchCommand(Command): @@ -16,11 +16,10 @@ class SwitchCommand(Command): sys.exit(1) pkg = Package(args[0]) pkgname = pkg.name - pkgdir = os.path.join(PATH_PYTHONS, pkgname) - if not os.path.isdir(pkgdir): + if not is_installed(pkgname): logger.info("`%s` is not installed." % pkgname) sys.exit(1) - pkgbin = os.path.join(pkgdir,'bin') + pkgbin = os.path.join(PATH_PYTHONS,pkgname,'bin') set_current_path('%s:%s' % (PATH_BIN, pkgbin)) diff --git a/pythonbrew/commands/uninstall.py b/pythonbrew/commands/uninstall.py index 19f506d..2659bec 100644 --- a/pythonbrew/commands/uninstall.py +++ b/pythonbrew/commands/uninstall.py @@ -1,7 +1,8 @@ import os from pythonbrew.basecommand import Command from pythonbrew.define import PATH_PYTHONS, PATH_BIN -from pythonbrew.util import off, rm_r, Package, get_current_python_path, unlink +from pythonbrew.util import off, rm_r, Package, get_current_use_pkgname, unlink,\ + is_installed from pythonbrew.log import logger class UninstallCommand(Command): @@ -16,10 +17,10 @@ class UninstallCommand(Command): pkg = Package(arg) pkgname = pkg.name pkgpath = os.path.join(PATH_PYTHONS, pkgname) - if not os.path.isdir(pkgpath): + if not is_installed(pkgname): logger.info("`%s` is not installed." % pkgname) continue - if get_current_python_path() == os.path.join(pkgpath,'bin','python'): + if get_current_use_pkgname() == pkgname: off() for d in os.listdir(PATH_BIN): # remove symlink diff --git a/pythonbrew/commands/venv.py b/pythonbrew/commands/venv.py new file mode 100644 index 0000000..df174b3 --- /dev/null +++ b/pythonbrew/commands/venv.py @@ -0,0 +1,84 @@ +import os +import sys +import subprocess +from pythonbrew.basecommand import Command +from pythonbrew.define import PATH_PYTHONS, BOOTSTRAP_DLSITE, PATH_DISTS +from pythonbrew.util import Package, get_current_use_pkgname, Link +from pythonbrew.log import logger +from pythonbrew.downloader import Downloader + +class VenvCommand(Command): + name = "venv" + usage = "%prog [create|use|delete|list] [project]" + summary = "Create isolated python environments" + + def __init__(self): + super(VenvCommand, self).__init__() + self.parser.add_option( + "-p", "--python", + dest="python", + default=None, + help="Use the specified version of python.", + metavar='VERSION' + ) + + def run_command(self, options, args): + if not args: + logger.error('Unrecognized command line argument: argument not found.') + sys.exit(1) + cmd = args[0] + if not cmd in ('create', 'use', 'delete', 'list'): + logger.error('%s command not found.' % cmd) + sys.exit(1) + + # Decide which version of python to use. + if options.python: + pkgname = Package(options.python).name + else: + pkgname = get_current_use_pkgname() + logger.info('Using %s' % pkgname) + + if cmd == 'create': + self._create(args[1:]) + elif cmd == 'use': + self._use(args[1]) + elif cmd == 'delete': + self._delete(args[1:]) + elif cmd == 'list': + self._list() + + # Download bootstrap.py +# download_url = BOOTSTRAP_DLSITE +# filename = Link(download_url).filename +# bootstrap = os.path.join(PATH_DISTS, filename) +# try: +# d = Downloader() +# d.download(filename, download_url, bootstrap) +# except: +# logger.error("Failed to download. `%s`" % download_url) +# sys.exit(1) +# +# # Using bootstrap.py +# if subprocess.call([python, bootstrap, '-d']): +# logger.error('Failed to bootstrap.') +# sys.exit(1) +# +# # Using buildout +# subprocess.call(['./bin/buildout']) + + def _create(self, projects): + """Create python environment""" + for proj in projects: + print proj + + def _use(self, project): + print project + + def _delete(self, projects): + for proj in projects: + print proj + + def _list(self): + print 'list' + +VenvCommand() diff --git a/pythonbrew/util.py b/pythonbrew/util.py index 1530777..ab6b661 100644 --- a/pythonbrew/util.py +++ b/pythonbrew/util.py @@ -10,7 +10,7 @@ import urllib import subprocess import shlex import select -from pythonbrew.define import PATH_BIN, PATH_ETC_CURRENT +from pythonbrew.define import PATH_BIN, PATH_ETC_CURRENT, PATH_PYTHONS from pythonbrew.exceptions import ShellCommandException from pythonbrew.log import logger @@ -94,12 +94,8 @@ def is_python32(version): return version >= '3.2' and version < '3.3' def makedirs(path): - try: + if not os.path.exists(path): os.makedirs(path) - except OSError: - e = sys.exc_info()[1] - if errno.EEXIST != e.errno: - raise def symlink(src, dst): try: @@ -213,12 +209,22 @@ def extract_downloadfile(content_type, download_file, target_dir): return False return True -def get_current_python_path(): - """return: python path or '' - """ +def get_current_use_pkgname(): + """return: Python- or None""" p = subprocess.Popen('command -v python', stdout=subprocess.PIPE, shell=True) - return to_str(p.communicate()[0].strip()) + path = to_str(p.communicate()[0].strip()) + for d in sorted(os.listdir(PATH_PYTHONS)): + if path and os.path.samefile(path, os.path.join(PATH_PYTHONS, d, 'bin','python')): + return d + return None +def is_installed(name): + pkgname = Package(name).name + pkgdir = os.path.join(PATH_PYTHONS, pkgname) + if not os.path.isdir(pkgdir): + return False + return True + def set_current_path(path): fp = open(PATH_ETC_CURRENT, 'w') fp.write('PATH_PYTHONBREW="%s"\n' % (path)) diff --git a/tests/__init__.py b/tests/__init__.py index e6eeae9..2e311ed 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -2,17 +2,16 @@ import os import shutil PYTHONBREW_ROOT = '/tmp/pythonbrew.test' -TESTPY_FILE = '/tmp/pythonbrew_test.py' TESTPY_VERSION = ['2.4.6', '2.5.5', '2.6.6', '3.2'] def cleanall(): if os.path.isdir(PYTHONBREW_ROOT): shutil.rmtree(PYTHONBREW_ROOT) - if os.path.isfile(TESTPY_FILE): - os.remove(TESTPY_FILE) def setup(): os.environ['PYTHONBREW_ROOT'] = PYTHONBREW_ROOT cleanall() + from pythonbrew.installer import install_pythonbrew + install_pythonbrew() def teardown(): cleanall() diff --git a/tests/test_00_install_pythonbrew.py b/tests/test_00_install_pythonbrew.py deleted file mode 100644 index 30d0471..0000000 --- a/tests/test_00_install_pythonbrew.py +++ /dev/null @@ -1,3 +0,0 @@ -def test_install_pythonbrew(): - from pythonbrew.installer import install_pythonbrew - install_pythonbrew() \ No newline at end of file diff --git a/tests/test_01_update.py b/tests/test_00_update.py similarity index 100% rename from tests/test_01_update.py rename to tests/test_00_update.py diff --git a/tests/test_02_help.py b/tests/test_01_help.py similarity index 100% rename from tests/test_02_help.py rename to tests/test_01_help.py diff --git a/tests/test_03_version.py b/tests/test_02_version.py similarity index 100% rename from tests/test_03_version.py rename to tests/test_02_version.py diff --git a/tests/test_04_install.py b/tests/test_03_install.py similarity index 100% rename from tests/test_04_install.py rename to tests/test_03_install.py diff --git a/tests/test_05_switch.py b/tests/test_04_switch.py similarity index 100% rename from tests/test_05_switch.py rename to tests/test_04_switch.py diff --git a/tests/test_06_use.py b/tests/test_05_use.py similarity index 100% rename from tests/test_06_use.py rename to tests/test_05_use.py diff --git a/tests/test_07_off.py b/tests/test_06_off.py similarity index 100% rename from tests/test_07_off.py rename to tests/test_06_off.py diff --git a/tests/test_08_list.py b/tests/test_07_list.py similarity index 100% rename from tests/test_08_list.py rename to tests/test_07_list.py diff --git a/tests/test_09_py.py b/tests/test_08_py.py similarity index 76% rename from tests/test_09_py.py rename to tests/test_08_py.py index 77a0705..07031e6 100644 --- a/tests/test_09_py.py +++ b/tests/test_08_py.py @@ -1,4 +1,7 @@ -from tests import TESTPY_FILE +from tests import PYTHONBREW_ROOT +import os + +TESTPY_FILE = os.path.join(PYTHONBREW_ROOT, 'etc', 'testfile.py') class PyOptions(object): pythons = [] diff --git a/tests/test_09_buildout.py b/tests/test_09_buildout.py new file mode 100644 index 0000000..221757a --- /dev/null +++ b/tests/test_09_buildout.py @@ -0,0 +1,31 @@ +from tests import PYTHONBREW_ROOT +import os + +BUILDOUT_DIR = os.path.join(PYTHONBREW_ROOT, 'etc', 'buildout') +BUILDOUT_CONF = os.path.join(BUILDOUT_DIR, 'buildout.cfg') + +def _create_buildout_cfg(): + if not os.path.isdir(BUILDOUT_DIR): + os.makedirs(BUILDOUT_DIR) + fp = open(BUILDOUT_CONF, 'w') + fp.write("""[buildout] +parts = test +develop = + +[test] +recipe = +eggs =""") + fp.close() + +class BuildoutOptions(object): + python = '2.6.6' + +def test_buildout(): + from pythonbrew.commands.buildout import BuildoutCommand + + # Runs the buildout + _create_buildout_cfg() + os.chdir(BUILDOUT_DIR) + c = BuildoutCommand() + c.run_command(BuildoutOptions(), []) + \ No newline at end of file