From 04f4cd15b3367d16da15997585c865c773d8f83b Mon Sep 17 00:00:00 2001 From: utahta Date: Sat, 6 Aug 2011 23:56:31 +0900 Subject: [PATCH] Improve venv command, log and bashrc --- pythonbrew/__init__.py | 2 +- pythonbrew/commands/buildout.py | 6 +- pythonbrew/commands/help.py | 8 +- pythonbrew/commands/install.py | 36 ++--- pythonbrew/commands/list.py | 19 +-- pythonbrew/commands/py.py | 6 +- pythonbrew/commands/switch.py | 8 +- pythonbrew/commands/symlink.py | 2 +- pythonbrew/commands/uninstall.py | 2 +- pythonbrew/commands/update.py | 2 +- pythonbrew/commands/use.py | 13 +- pythonbrew/commands/venv.py | 168 ++++++++++---------- pythonbrew/commands/version.py | 2 +- pythonbrew/curl.py | 2 +- pythonbrew/define.py | 27 +++- pythonbrew/etc/bashrc | 44 +++-- pythonbrew/etc/config.cfg | 3 + pythonbrew/installer/__init__.py | 4 +- pythonbrew/installer/pythonbrewinstaller.py | 3 +- pythonbrew/installer/pythoninstaller.py | 14 +- pythonbrew/log.py | 70 ++++---- pythonbrew/util.py | 19 ++- tests/test_10_venv.py | 10 ++ 23 files changed, 257 insertions(+), 213 deletions(-) diff --git a/pythonbrew/__init__.py b/pythonbrew/__init__.py index e09793c..d190d8c 100644 --- a/pythonbrew/__init__.py +++ b/pythonbrew/__init__.py @@ -15,7 +15,7 @@ def main(): if command not in command_dict: if command == 'clean': # note: for some time - logger.info('\nDEPRECATION WARNING: `pythonbrew clean` has been renamed. Please run `pythonbrew cleanup` instead.\n') + logger.log('\nDEPRECATION WARNING: `pythonbrew clean` has been renamed. Please run `pythonbrew cleanup` instead.\n') return parser.error("Unknown command: `%s`" % command) return diff --git a/pythonbrew/commands/buildout.py b/pythonbrew/commands/buildout.py index 81ef50a..5d08ffe 100644 --- a/pythonbrew/commands/buildout.py +++ b/pythonbrew/commands/buildout.py @@ -28,7 +28,7 @@ class BuildoutCommand(Command): else: pkgname = get_using_python_pkgname() if not is_installed(pkgname): - logger.info('%s is not installed.' % pkgname) + logger.error('`%s` is not installed.' % pkgname) sys.exit(1) logger.info('Using %s' % pkgname) @@ -46,12 +46,12 @@ class BuildoutCommand(Command): logger.error("Failed to download. `%s`" % download_url) sys.exit(1) - # Using bootstrap.py + # call bootstrap.py if subprocess.call([python, bootstrap, '-d']): logger.error('Failed to bootstrap.') sys.exit(1) - # Using buildout + # call buildout subprocess.call(['./bin/buildout']) BuildoutCommand() diff --git a/pythonbrew/commands/help.py b/pythonbrew/commands/help.py index 7256ae4..7e9d8a3 100644 --- a/pythonbrew/commands/help.py +++ b/pythonbrew/commands/help.py @@ -17,11 +17,11 @@ class HelpCommand(Command): command.parser.print_help() return parser.print_help() - logger.info("\nCommands available:") + logger.log("\nCommands available:") commands = [command_dict[key] for key in sorted(command_dict.keys())] for command in commands: - logger.info(" %s: %s" % (command.name, command.summary)) - logger.info("\nFurther Instructions:") - logger.info(" https://github.com/utahta/pythonbrew") + logger.log(" %s: %s" % (command.name, command.summary)) + logger.log("\nFurther Instructions:") + logger.log(" https://github.com/utahta/pythonbrew") HelpCommand() diff --git a/pythonbrew/commands/install.py b/pythonbrew/commands/install.py index 34e6877..2a67c2c 100644 --- a/pythonbrew/commands/install.py +++ b/pythonbrew/commands/install.py @@ -1,5 +1,5 @@ +import sys from pythonbrew.basecommand import Command -from pythonbrew.log import logger from pythonbrew.installer.pythoninstaller import PythonInstaller,\ PythonInstallerMacOSX from pythonbrew.util import is_macosx @@ -63,22 +63,22 @@ class InstallCommand(Command): ) def run_command(self, options, args): - if args: - # installing python - for arg in args: - try: - if is_macosx(): - p = PythonInstallerMacOSX(arg, options) - else: - p = PythonInstaller(arg, options) - p.install() - except UnknownVersionException: - continue - except AlreadyInstalledException: - continue - except NotSupportedVersionException: - continue - else: - logger.info("Unknown python version.") + if not args: + self.parser.print_help() + sys.exit(1) + # installing python + for arg in args: + try: + if is_macosx(): + p = PythonInstallerMacOSX(arg, options) + else: + p = PythonInstaller(arg, options) + p.install() + except UnknownVersionException: + continue + except AlreadyInstalledException: + continue + except NotSupportedVersionException: + continue InstallCommand() diff --git a/pythonbrew/commands/list.py b/pythonbrew/commands/list.py index d9fb902..ab4293d 100644 --- a/pythonbrew/commands/list.py +++ b/pythonbrew/commands/list.py @@ -3,8 +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_using_python_pkgname,\ - get_using_python_path +from pythonbrew.util import Package, get_using_python_pkgname from pythonbrew.log import logger class ListCommand(Command): @@ -36,18 +35,16 @@ class ListCommand(Command): self.installed(options, args) def installed(self, options, args): - logger.info('# installed pythons') + logger.log("# pythonbrew pythons") cur = get_using_python_pkgname() for d in sorted(os.listdir(PATH_PYTHONS)): if cur and cur == d: - logger.info('%s (*)' % d) + logger.log(' %s (*)' % d) else: - logger.info('%s' % d) - if not cur: - logger.info('%s (*)' % get_using_python_path()) + logger.log(' %s' % d) def available_install(self, options, args): - logger.info('# available install pythons') + logger.log('# Pythons') if args: pkg = Package(args[0]) _re = re.compile(r"%s" % pkg.name) @@ -57,12 +54,12 @@ class ListCommand(Command): pkgs.append(pkgname) if pkgs: for pkgname in pkgs: - logger.info("%s" % pkgname) + logger.log("%s" % pkgname) else: - logger.info("Python version not found. `%s`" % pkg.name) + logger.error("Python version not found. `%s`" % pkg.name) else: for pkgname in self._get_packages_name(options): - logger.info("%s" % pkgname) + logger.log("%s" % pkgname) def _get_packages_name(self, options): return ["Python-%s" % version for version in sorted(PYTHON_VERSION_URL.keys()) diff --git a/pythonbrew/commands/py.py b/pythonbrew/commands/py.py index 9390dca..102cb79 100644 --- a/pythonbrew/commands/py.py +++ b/pythonbrew/commands/py.py @@ -32,12 +32,12 @@ class PyCommand(Command): def run_command(self, options, args): if not args: - logger.info("Unrecognized command line argument: argument not found.") + self.parser.print_help() sys.exit(1) pythons = self._get_pythons(options.pythons) for d in pythons: if options.verbose: - logger.info('*** %s ***' % d) + logger.info('`%s` running...' % d) path = os.path.join(PATH_PYTHONS, d, 'bin', args[0]) if os.path.isfile(path) and os.access(path, os.X_OK): subprocess.call([path] + args[1:]) @@ -46,7 +46,7 @@ class PyCommand(Command): if os.path.isfile(path) and os.access(path, os.X_OK): subprocess.call([path] + args) else: - logger.info('%s: No such file or directory.' % path) + logger.error('%s: No such file or directory.' % path) def _get_pythons(self, _pythons): pythons = [Package(p).name for p in _pythons] diff --git a/pythonbrew/commands/switch.py b/pythonbrew/commands/switch.py index d25e5c5..34e25be 100644 --- a/pythonbrew/commands/switch.py +++ b/pythonbrew/commands/switch.py @@ -1,7 +1,7 @@ import os import sys from pythonbrew.basecommand import Command -from pythonbrew.define import PATH_PYTHONS, PATH_BIN +from pythonbrew.define import PATH_PYTHONS from pythonbrew.util import Package, set_current_path, is_installed from pythonbrew.log import logger @@ -12,16 +12,16 @@ class SwitchCommand(Command): def run_command(self, options, args): if not args: - logger.info("Unrecognized command line argument: argument not found.") + self.parser.print_help() sys.exit(1) pkg = Package(args[0]) pkgname = pkg.name if not is_installed(pkgname): - logger.info("`%s` is not installed." % pkgname) + logger.error("`%s` is not installed." % pkgname) sys.exit(1) pkgbin = os.path.join(PATH_PYTHONS,pkgname,'bin') - set_current_path('%s:%s' % (PATH_BIN, pkgbin)) + set_current_path(pkgbin) logger.info("Switched to %s" % pkgname) diff --git a/pythonbrew/commands/symlink.py b/pythonbrew/commands/symlink.py index 5e35d72..5d51193 100644 --- a/pythonbrew/commands/symlink.py +++ b/pythonbrew/commands/symlink.py @@ -75,7 +75,7 @@ class SymlinkCommand(Command): if os.path.isfile(src): symlink(src, dst) else: - logger.info("%s: File not found" % src) + logger.error("%s: File not found" % src) def _get_pythons(self, _pythons): """Get the installed python versions list. diff --git a/pythonbrew/commands/uninstall.py b/pythonbrew/commands/uninstall.py index d04e53c..0699224 100644 --- a/pythonbrew/commands/uninstall.py +++ b/pythonbrew/commands/uninstall.py @@ -19,7 +19,7 @@ class UninstallCommand(Command): pkgpath = os.path.join(PATH_PYTHONS, pkgname) venvpath = os.path.join(PATH_VENVS, pkgname) if not is_installed(pkgname): - logger.info("`%s` is not installed." % pkgname) + logger.error("`%s` is not installed." % pkgname) continue if get_using_python_pkgname() == pkgname: off() diff --git a/pythonbrew/commands/update.py b/pythonbrew/commands/update.py index f9d760a..b49d27d 100644 --- a/pythonbrew/commands/update.py +++ b/pythonbrew/commands/update.py @@ -65,7 +65,7 @@ class UpdateCommand(Command): except: logger.error("Failed to download. `%s`" % download_url) sys.exit(1) - logger.info("The config.cfg has been updated.") + logger.log("The config.cfg has been updated.") def _update_pythonbrew(self, options, args): if options.master: diff --git a/pythonbrew/commands/use.py b/pythonbrew/commands/use.py index 0b7c200..be1ea86 100644 --- a/pythonbrew/commands/use.py +++ b/pythonbrew/commands/use.py @@ -1,7 +1,7 @@ import os import sys from pythonbrew.basecommand import Command -from pythonbrew.define import PATH_PYTHONS, PATH_BIN, PATH_ETC_TEMP +from pythonbrew.define import PATH_PYTHONS, PATH_HOME_ETC_TEMP from pythonbrew.util import Package from pythonbrew.log import logger @@ -12,24 +12,23 @@ class UseCommand(Command): def run_command(self, options, args): if not args: - logger.info("Unrecognized command line argument: argument not found.") + self.parser.print_help() sys.exit(1) pkg = Package(args[0]) pkgname = pkg.name pkgdir = os.path.join(PATH_PYTHONS, pkgname) if not os.path.isdir(pkgdir): - logger.info("`%s` is not installed." % pkgname) + logger.error("`%s` is not installed." % pkgname) sys.exit(1) pkgbin = os.path.join(pkgdir,'bin') - self._set_temp('%s:%s' % (PATH_BIN, pkgbin)) + self._set_temp(pkgbin) logger.info("Using `%s`" % pkgname) def _set_temp(self, path): - fp = open(PATH_ETC_TEMP, 'w') - fp.write('PATH_PYTHONBREW="%s"\n' % (path)) + fp = open(PATH_HOME_ETC_TEMP, 'w') + fp.write('PATH_PYTHONBREW_TEMP="%s"\n' % (path)) fp.close() - UseCommand() diff --git a/pythonbrew/commands/venv.py b/pythonbrew/commands/venv.py index 8ac4e4f..c289936 100644 --- a/pythonbrew/commands/venv.py +++ b/pythonbrew/commands/venv.py @@ -1,10 +1,13 @@ import os import sys from pythonbrew.basecommand import Command -from pythonbrew.define import PATH_PYTHONS, PATH_VENVS, PATH_ETC_VENV -from pythonbrew.util import Subprocess, Package,\ - is_installed, get_installed_pythons_pkgname, get_using_python_pkgname +from pythonbrew.define import PATH_PYTHONS, PATH_VENVS, PATH_HOME_ETC_VENV,\ + PATH_ETC, VIRTUALENV_DLSITE, PATH_DISTS +from pythonbrew.util import Package, \ + is_installed, get_installed_pythons_pkgname, get_using_python_pkgname,\ + untar_file from pythonbrew.log import logger +from pythonbrew.downloader import Downloader class VenvCommand(Command): name = "venv" @@ -26,38 +29,30 @@ class VenvCommand(Command): action='store_true', default=False, help="Show the all python environments.", - metavar='VERSION' ) - self.template_env = """export VIRTUALENVWRAPPER_PYTHON=%(venv_py)s -export VIRTUALENVWRAPPER_VIRTUALENV=%(venv_venv)s -export WORKON_HOME=%(workon_home)s -export VIRTUALENVWRAPPER_HOOK_DIR=%(workon_home)s -export VIRTUALENVWRAPPER_LOG_DIR=%(workon_home)s -source %(venv_sh)s -""" - + self.parser.add_option( + "-n", "--no-site-packages", + dest="no_site_packages", + action='store_true', + default=False, + help="Don't give access to the global site-packages dir to the virtual environment.", + ) + self._venv_dir = os.path.join(PATH_ETC, 'virtualenv') + self._venv = os.path.join(self._venv_dir, 'virtualenv.py') + def run_command(self, options, args): if not args: - logger.error('Unrecognized command line argument: ( see: \'pythonbrew help venv\' )') + self.parser.print_help() sys.exit(1) cmd = args[0] - if not cmd in ('create', 'delete', 'use', 'list'): - logger.error('Unrecognized command line argument: ( see: \'pythonbrew help venv\' )') + if not cmd in ('init', 'create', 'delete', 'use', 'list'): + self.parser.print_help() sys.exit(1) - # find python2 - venv_pkgname = None - for pkgname in reversed(get_installed_pythons_pkgname()): - # virtualenvwrapper require Python2 - venv_pkgver = Package(pkgname).version - if venv_pkgver >= '2.4' and venv_pkgver < '3': - venv_pkgname = pkgname - break - if not venv_pkgname: - logger.error('Can not create virtual environment before installing a python2. Try \'pythonbrew install \'.') - sys.exit(1) - venv_dir = os.path.join(PATH_PYTHONS, venv_pkgname) - venv_bin = os.path.join(venv_dir, 'bin') + # initialize? + if cmd == 'init': + self.run_command_init() + return # target python interpreter if options.python: @@ -66,92 +61,97 @@ source %(venv_sh)s logger.error('%s is not installed.' % pkgname) sys.exit(1) else: + # check using python under pythonbrew pkgname = get_using_python_pkgname() if not pkgname: - logger.error('Can not use venv command before using a python. Try \'pythonbrew switch \'.') + logger.error('Can not use venv command before switching a python. Try \'pythonbrew switch \'.') sys.exit(1) self._pkgname = pkgname self._target_py = os.path.join(PATH_PYTHONS, pkgname, 'bin', 'python') self._workon_home = os.path.join(PATH_VENVS, pkgname) - self._venv_py = os.path.join(venv_bin, 'python') - self._venv_venv = os.path.join(venv_bin, 'virtualenv') - self._venv_sh = os.path.join(venv_bin, 'virtualenvwrapper.sh') + self._py = os.path.join(PATH_PYTHONS, pkgname, 'bin', 'python') - # has virtualenv & virtualenvwrapper? - if not self._venv_venv or not self._venv_sh: - logger.info('Installing virtualenv into %s' % venv_dir) - s = Subprocess(verbose=True) - s.shell('%s %s %s' % (os.path.join(venv_bin,'pip'), 'install', 'virtualenvwrapper')) + # is already installed virtualenv? + if not os.path.exists(self._venv): + self.run_command_init() # Create a shell script - try: - self.__getattribute__('run_command_%s' % cmd)(options, args) - except: - logger.error('`%s` command not found.' % cmd) + self.__getattribute__('run_command_%s' % cmd)(options, args) + + def run_command_init(self): + if os.path.exists(self._venv): + logger.info('venv command is already initialized.') + return + if not os.access(PATH_DISTS, os.W_OK): + logger.error("Can not write to %s: Permission denied." % PATH_DISTS) sys.exit(1) + d = Downloader() + download_file = os.path.join(PATH_DISTS, 'virtualenv.tar.gz') + d.download('virtualenv.tar.gz', VIRTUALENV_DLSITE, download_file) + logger.info('Extracting virtualenv into %s' % self._venv_dir) + untar_file(download_file, self._venv_dir) def run_command_create(self, options, args): - output = [self.template_env % {'venv_py': self._venv_py, - 'venv_venv': self._venv_venv, - 'workon_home': self._workon_home, - 'venv_sh': self._venv_sh}] + virtualenv_options = '' + if options.no_site_packages: + virtualenv_options += '--no-site-packages' + + print 'in create' + output = [] for arg in args[1:]: - output.append("""echo '# Create `%(arg)s` environment into %(workon_home)s' -mkvirtualenv -p '%(target_py)s' '%(arg)s' -""" % {'arg': arg, - 'workon_home': self._workon_home, - 'target_py': self._target_py}) + target_dir = os.path.join(self._workon_home, arg) + output.append("""\ +echo '# Create `%(arg)s` environment into %(workon_home)s' +%(py)s %(venv)s -p '%(target_py)s' %(options)s '%(target_dir)s' +""" % {'arg': arg, 'workon_home': self._workon_home, 'py': self._py, 'venv': self._venv, 'target_py': self._target_py, 'options': virtualenv_options, 'target_dir': target_dir}) self._write(''.join(output)) def run_command_delete(self, options, args): - output = [self.template_env % {'venv_py': self._venv_py, - 'venv_venv': self._venv_venv, - 'workon_home': self._workon_home, - 'venv_sh': self._venv_sh}] + output = [] for arg in args[1:]: - output.append("""echo '# Delete `%(arg)s` environment in %(workon_home)s' -rmvirtualenv '%(arg)s' -""" % {'arg': arg, - 'workon_home': self._workon_home}) - self._write(''.join(output)) + target_dir = os.path.join(self._workon_home, arg) + if not os.path.isdir(target_dir): + logger.error('%s already does not exist.' % target_dir) + else: + output.append("""\ +echo '# Delete `%(arg)s` environment in %(workon_home)s' +rm -rf '%(target_dir)s' +""" % {'arg': arg, 'workon_home': self._workon_home, 'target_dir': target_dir}) + if output: + self._write(''.join(output)) def run_command_use(self, options, args): if len(args) < 2: logger.error("Unrecognized command line argument: ( 'pythonbrew venv use ' )") sys.exit(1) - template = self.template_env + """echo '# Using `%(arg)s` environment (found in %(workon_home)s)' + + activate = os.path.join(self._workon_home, args[1], 'bin', 'activate') + if not os.path.exists(activate): + logger.error('`%s` environment already does not exist. Try `pythonbrew venv create %s`.' % (args[1], args[1])) + sys.exit(1) + + self._write("""\ +echo '# Using `%(arg)s` environment (found in %(workon_home)s)' echo '# To leave an environment, simply run `deactivate`' -workon '%(arg)s' -""" - self._write(template % {'venv_py': self._venv_py, - 'venv_venv': self._venv_venv, - 'workon_home': self._workon_home, - 'venv_sh': self._venv_sh, - 'arg': args[1]}) - +source '%(activate)s' +""" % {'arg': args[1], 'workon_home': self._workon_home, 'activate': activate}) + def run_command_list(self, options, args): - template = self.template_env + """echo '# virtualenv for %(pkgname)s (found in %(workon_home)s)' -workon -""" if options.all: - output = [] for pkgname in get_installed_pythons_pkgname(): workon_home = os.path.join(PATH_VENVS, pkgname) - output.append(template % {'venv_py': self._venv_py, - 'venv_venv': self._venv_venv, - 'workon_home': workon_home, - 'venv_sh': self._venv_sh, - 'pkgname': pkgname}) - self._write(''.join(output)) + logger.log("# virtualenv for %(pkgname)s (found in %(workon_home)s)" % {'pkgname': pkgname, 'workon_home': workon_home}) + if os.path.isdir(workon_home): + for d in sorted(os.listdir(workon_home)): + logger.log(d) else: - self._write(template % {'venv_py': self._venv_py, - 'venv_venv': self._venv_venv, - 'workon_home': self._workon_home, - 'venv_sh': self._venv_sh, - 'pkgname': self._pkgname}) + logger.log("# virtualenv for %(pkgname)s (found in %(workon_home)s)" % {'pkgname': self._pkgname, 'workon_home': self._workon_home}) + if os.path.isdir(self._workon_home): + for d in sorted(os.listdir(self._workon_home)): + logger.log(d) def _write(self, src): - fp = open(PATH_ETC_VENV, 'w') + fp = open(PATH_HOME_ETC_VENV, 'w') fp.write(src) fp.close() diff --git a/pythonbrew/commands/version.py b/pythonbrew/commands/version.py index 2144123..5be8a62 100644 --- a/pythonbrew/commands/version.py +++ b/pythonbrew/commands/version.py @@ -8,6 +8,6 @@ class VersionCommand(Command): summary = "Show version" def run_command(self, options, args): - logger.info(VERSION) + logger.log(VERSION) VersionCommand() diff --git a/pythonbrew/curl.py b/pythonbrew/curl.py index 719639c..14b05c3 100644 --- a/pythonbrew/curl.py +++ b/pythonbrew/curl.py @@ -9,7 +9,7 @@ class Curl(object): def __init__(self): returncode = subprocess.call("command -v curl > /dev/null", shell=True) if returncode: - logger.info("pythonbrew required curl. curl was not found in your path.") + logger.log("pythonbrew required curl. curl was not found in your path.") sys.exit(1) def read(self, url): diff --git a/pythonbrew/define.py b/pythonbrew/define.py index bf4dee5..5589615 100644 --- a/pythonbrew/define.py +++ b/pythonbrew/define.py @@ -8,14 +8,15 @@ except: # pythonbrew version VERSION = "0.9" +# pythonbrew installer root path +INSTALLER_ROOT = os.path.dirname(os.path.abspath(__file__)) + +# Root # pythonbrew root path ROOT = os.environ.get("PYTHONBREW_ROOT") if not ROOT: ROOT = os.path.join(os.environ["HOME"],".pythonbrew") -# pythonbrew installer root path -INSTALLER_ROOT = os.path.dirname(os.path.abspath(__file__)) - # directories PATH_PYTHONS = os.path.join(ROOT,"pythons") PATH_BUILD = os.path.join(ROOT,"build") @@ -38,10 +39,21 @@ PATH_PATCHES_MACOSX_PYTHON24 = os.path.join(PATH_PATCHES_MACOSX,"python24") # files PATH_BIN_PYTHONBREW = os.path.join(PATH_BIN,'pythonbrew') -PATH_ETC_CURRENT = os.path.join(PATH_ETC,'current') -PATH_ETC_TEMP = os.path.join(PATH_ETC,'temp') PATH_ETC_CONFIG = os.path.join(PATH_ETC,'config.cfg') -PATH_ETC_VENV = os.path.join(PATH_ETC, 'venv.run') + +# Home +# pythonbrew home path +PATH_HOME = os.environ.get('PYTHONBREW_HOME') +if not PATH_HOME: + PATH_HOME = os.path.join(os.environ["HOME"],".pythonbrew") + +# directories +PATH_HOME_ETC = os.path.join(PATH_HOME, 'etc') + +# files +PATH_HOME_ETC_VENV = os.path.join(PATH_HOME_ETC, 'venv.run') +PATH_HOME_ETC_CURRENT = os.path.join(PATH_HOME_ETC,'current') +PATH_HOME_ETC_TEMP = os.path.join(PATH_HOME_ETC,'temp') # read config.cfg config = ConfigParser.SafeConfigParser() @@ -58,6 +70,9 @@ DISTRIBUTE_SETUP_DLSITE = _get_or_default('distribute', 'url') # buildout bootstrap download BOOTSTRAP_DLSITE = _get_or_default('bootstrap', 'url') +# virtualenv download +VIRTUALENV_DLSITE = _get_or_default('virtualenv', 'url') + # pythonbrew download PYTHONBREW_UPDATE_URL_MASTER = _get_or_default('pythonbrew', 'master') PYTHONBREW_UPDATE_URL_DEVELOP = _get_or_default('pythonbrew', 'develop') diff --git a/pythonbrew/etc/bashrc b/pythonbrew/etc/bashrc index 82b73c4..e6e7e02 100644 --- a/pythonbrew/etc/bashrc +++ b/pythonbrew/etc/bashrc @@ -1,6 +1,20 @@ -PATH_ROOT="@ROOT@" +# settings +PATH_ROOT="$PYTHONBREW_ROOT" +if [ -z "${PATH_ROOT}" ] ; then + PATH_ROOT="$HOME/.pythonbrew" +fi PATH_ETC="$PATH_ROOT/etc" +PATH_HOME="$PYTHONBREW_HOME" +if [ -z "${PATH_HOME}" ] ; then + PATH_HOME="$HOME/.pythonbrew" +fi +PATH_HOME_ETC="$PATH_HOME/etc" + +# exec +pythonbrew="$PATH_ROOT/bin/pythonbrew" + +# functions __pythonbrew_set_default() { PATH_PYTHONBREW="$PATH_ROOT/bin" @@ -14,8 +28,9 @@ __pythonbrew_set_path() __pythonbrew_set_temp_path() { - if [[ -s "$PATH_ETC/temp" ]] ; then - source "$PATH_ETC/temp" + if [[ -s "$PATH_HOME_ETC/temp" ]] ; then + source "$PATH_HOME_ETC/temp" + PATH_PYTHONBREW="$PATH_ROOT/bin:$PATH_PYTHONBREW_TEMP" else __pythonbrew_set_default fi @@ -24,8 +39,9 @@ __pythonbrew_set_temp_path() __pythonbrew_set_current_path() { - if [[ -s "$PATH_ETC/current" ]] ; then - source "$PATH_ETC/current" + if [[ -s "$PATH_HOME_ETC/current" ]] ; then + source "$PATH_HOME_ETC/current" + PATH_PYTHONBREW="$PATH_ROOT/bin:$PATH_PYTHONBREW_CURRENT" else __pythonbrew_set_default fi @@ -39,35 +55,35 @@ __pythonbrew_reload() __pythonbrew_use() { - command pythonbrew "$@" + $pythonbrew "$@" [[ $? == 0 ]] && __pythonbrew_set_temp_path } __pythonbrew_switch() { - command pythonbrew "$@" + $pythonbrew "$@" [[ $? == 0 ]] && __pythonbrew_set_current_path } __pythonbrew_off() { - command pythonbrew "$@" + $pythonbrew "$@" [[ $? == 0 ]] && __pythonbrew_set_current_path } __pythonbrew_update() { - command pythonbrew "$@" + $pythonbrew "$@" [[ $? == 0 ]] && __pythonbrew_reload } __pythonbrew_venv() { - command pythonbrew "$@" + $pythonbrew "$@" if [[ $? == 0 ]] ; then - if [[ -s "$PATH_ETC/venv.run" ]] ; then - source "$PATH_ETC/venv.run" - cat /dev/null > "$PATH_ETC/venv.run" + if [[ -s "$PATH_HOME_ETC/venv.run" ]] ; then + source "$PATH_HOME_ETC/venv.run" + cat /dev/null > "$PATH_HOME_ETC/venv.run" fi fi } @@ -96,7 +112,7 @@ pythonbrew() off) __pythonbrew_off "$@" ;; update) __pythonbrew_update "$@" ;; venv) __pythonbrew_venv "$@" ;; - *) command pythonbrew "$@" ;; + *) $pythonbrew "$@" ;; esac builtin hash -r } diff --git a/pythonbrew/etc/config.cfg b/pythonbrew/etc/config.cfg index 1a16836..3f057a4 100644 --- a/pythonbrew/etc/config.cfg +++ b/pythonbrew/etc/config.cfg @@ -4,6 +4,9 @@ url = http://python-distribute.org/distribute_setup.py [bootstrap] url = http://svn.zope.org/*checkout*/zc.buildout/trunk/bootstrap/bootstrap.py +[virtualenv] +url = http://pypi.python.org/packages/source/v/virtualenv/virtualenv-1.6.4.tar.gz + [pythonbrew] master = https://github.com/utahta/pythonbrew/tarball/master develop = https://github.com/utahta/pythonbrew/tarball/develop diff --git a/pythonbrew/installer/__init__.py b/pythonbrew/installer/__init__.py index f4362e4..8ff349d 100644 --- a/pythonbrew/installer/__init__.py +++ b/pythonbrew/installer/__init__.py @@ -4,9 +4,9 @@ from pythonbrew.define import INSTALLER_ROOT, ROOT, PATH_ETC def install_pythonbrew(): PythonbrewInstaller().install(INSTALLER_ROOT) - # pythonbrew is only for bash + # for bash shrc = yourshrc = "bashrc" - logger.info(""" + logger.log(""" Well-done! Congratulations! The pythonbrew is installed as: diff --git a/pythonbrew/installer/pythonbrewinstaller.py b/pythonbrew/installer/pythonbrewinstaller.py index 14c23bc..f8dd398 100644 --- a/pythonbrew/installer/pythonbrewinstaller.py +++ b/pythonbrew/installer/pythonbrewinstaller.py @@ -7,7 +7,7 @@ from pythonbrew.define import PATH_BUILD, PATH_BIN, PATH_DISTS, PATH_PYTHONS,\ PATH_ETC, PATH_SCRIPTS, PATH_SCRIPTS_PYTHONBREW,\ PATH_SCRIPTS_PYTHONBREW_COMMANDS, PATH_BIN_PYTHONBREW,\ ROOT, PATH_LOG, PATH_PATCHES, PATH_ETC_CONFIG,\ - PATH_SCRIPTS_PYTHONBREW_INSTALLER, PATH_VENVS + PATH_SCRIPTS_PYTHONBREW_INSTALLER, PATH_VENVS, PATH_HOME_ETC import stat class PythonbrewInstaller(object): @@ -23,6 +23,7 @@ class PythonbrewInstaller(object): makedirs(PATH_BIN) makedirs(PATH_LOG) makedirs(PATH_VENVS) + makedirs(PATH_HOME_ETC) # create script directories rm_r(PATH_SCRIPTS) diff --git a/pythonbrew/installer/pythoninstaller.py b/pythonbrew/installer/pythoninstaller.py index 50a6a77..fbe89e8 100644 --- a/pythonbrew/installer/pythoninstaller.py +++ b/pythonbrew/installer/pythoninstaller.py @@ -38,7 +38,7 @@ class PythonInstaller(object): pkg = Package(name, options.alias) self.download_url = get_python_version_url(pkg.version) if not self.download_url: - logger.info("Unknown python version: `%s`" % pkg.name) + logger.error("Unknown python version: `%s`" % pkg.name) raise UnknownVersionException filename = Link(self.download_url).filename self.pkg = pkg @@ -83,11 +83,11 @@ class PythonInstaller(object): except: rm_r(self.install_dir) logger.error("Failed to install %s. See %s to see why." % (self.pkg.name, self.logfile)) - logger.info(" pythonbrew install --force %s" % self.pkg.version) + logger.log(" pythonbrew install --force %s" % self.pkg.version) sys.exit(1) self.symlink() self.install_setuptools() - logger.info("Installed %(pkgname)s successfully. Run the following command to switch to %(pkgname)s." + logger.info("\nInstalled %(pkgname)s successfully. Run the following command to switch to %(pkgname)s." % {"pkgname":self.pkg.name}) logger.info(" pythonbrew switch %s" % self.pkg.alias) @@ -107,7 +107,7 @@ class PythonInstaller(object): dl.download(base_url, self.download_url, self.download_file) except: unlink(self.download_file) - logger.info("\nInterrupt to abort. `%s`" % (self.download_url)) + logger.log("\nInterrupt to abort. `%s`" % (self.download_url)) sys.exit(1) # extracting if not extract_downloadfile(self.content_type, self.download_file, self.build_dir): @@ -206,7 +206,7 @@ class PythonInstaller(object): options = self.options pkgname = self.pkg.name if options.no_setuptools: - logger.info("Skip installation of setuptools.") + logger.log("Skip installation of setuptools.") return download_url = DISTRIBUTE_SETUP_DLSITE filename = Link(download_url).filename @@ -228,7 +228,7 @@ class PythonInstaller(object): s.check_call([easy_install, 'pip']) except: logger.error("Failed to install setuptools. See %s/build.log to see why." % (ROOT)) - logger.info("Skip installation of setuptools.") + logger.log("Skip installation of setuptools.") class PythonInstallerMacOSX(PythonInstaller): """Python installer for MacOSX @@ -239,7 +239,7 @@ class PythonInstallerMacOSX(PythonInstaller): # check for version version = self.pkg.version if version < '2.6' and (version != '2.4.6' and version < '2.5.5'): - logger.info("`%s` is not supported on MacOSX Snow Leopard" % self.pkg.name) + logger.error("`%s` is not supported on MacOSX Snow Leopard" % self.pkg.name) raise NotSupportedVersionException # set configure options target = get_macosx_deployment_target() diff --git a/pythonbrew/log.py b/pythonbrew/log.py index 3ddf3cd..8b55939 100644 --- a/pythonbrew/log.py +++ b/pythonbrew/log.py @@ -1,43 +1,43 @@ import sys -import logging -class LoggerInfo(object): - def log(self, level, msg, *arg, **keys): - sys.stdout.write("%s\n" % msg) - -class LoggerError(object): - def log(self, level, msg, *arg, **keys): - sys.stderr.write("ERROR: %s\n" % msg) - -class Logger(object): +class Color(object): + DEBUG = '\033[35m' + INFO = '\033[32m' + ERROR = '\033[31m' + ENDC = '\033[0m' - DEBUG = logging.DEBUG - INFO = logging.INFO - ERROR = logging.ERROR + @classmethod + def _deco(cls, msg, color): + return '%s%s%s' % (color, msg, cls.ENDC) - def __init__(self): - self._consumers = [] - consumer = LoggerInfo() - self.add_consumer(Logger.INFO, consumer) + @classmethod + def debug(cls, msg): + return cls._deco(msg, cls.DEBUG) + @classmethod + def info(cls, msg): + return cls._deco(msg, cls.INFO) + @classmethod + def error(cls, msg): + return cls._deco(msg, cls.ERROR) + +class Logger(object): + def debug(self, msg): + self._stdout(Color.debug("DEBUG: %s\n" % msg)) + + def log(self, msg): + self._stdout("%s\n" % (msg)) + + def info(self, msg): + self._stdout(Color.info('%s\n' % msg)) - consumer = LoggerError() - self.add_consumer(Logger.ERROR, consumer) - - def debug(self, msg, *args, **keys): - self._log(Logger.DEBUG, msg, *args, **keys) - - def info(self, msg, *args, **keys): - self._log(Logger.INFO, msg, *args, **keys) + def error(self, msg): + self._stderr(Color.error("ERROR: %s\n" % msg)) - def error(self, msg, *args, **keys): - self._log(Logger.ERROR, msg, *args, **keys) - - def _log(self, level, msg, *args, **keys): - for (consumer_level, consumer) in self._consumers: - if level == consumer_level: - consumer.log(level, msg, *args, **keys) - - def add_consumer(self, level, consumer): - self._consumers.append((level, consumer)) + def _stdout(self, msg): + sys.stdout.write(msg) + sys.stdout.flush() + def _stderr(self, msg): + sys.stderr.write(msg) + sys.stderr.flush() logger = Logger() diff --git a/pythonbrew/util.py b/pythonbrew/util.py index a29ae85..11f6e3d 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, PATH_PYTHONS +from pythonbrew.define import PATH_BIN, PATH_HOME_ETC_CURRENT, PATH_PYTHONS from pythonbrew.exceptions import ShellCommandException from pythonbrew.log import logger @@ -209,10 +209,13 @@ def extract_downloadfile(content_type, download_file, target_dir): return False return True -def get_using_python_path(): - p = subprocess.Popen('command -v python', stdout=subprocess.PIPE, shell=True) +def get_command_path(command): + p = subprocess.Popen('command -v %s' % command, stdout=subprocess.PIPE, shell=True) return to_str(p.communicate()[0].strip()) +def get_using_python_path(): + return get_command_path('python') + def get_using_python_pkgname(): """return: Python- or None""" path = get_using_python_path() @@ -233,8 +236,8 @@ def is_installed(name): return True def set_current_path(path): - fp = open(PATH_ETC_CURRENT, 'w') - fp.write('PATH_PYTHONBREW="%s"\n' % (path)) + fp = open(PATH_HOME_ETC_CURRENT, 'w') + fp.write('PATH_PYTHONBREW_CURRENT="%s"\n' % (path)) fp.close() def path_to_fileurl(path): @@ -290,7 +293,7 @@ class Subprocess(object): def shell(self, cmd): if self._debug: - logger.info(cmd) + logger.log(cmd) if self._log: if self._verbose: cmd = "(%s) 2>&1 | tee '%s'" % (cmd, self._log) @@ -304,7 +307,7 @@ class Subprocess(object): if is_str(cmd): cmd = shlex.split(cmd) if self._debug: - logger.info(cmd) + logger.log(cmd) fp = ((self._log and open(self._log, 'a')) or None) p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=self._cwd) @@ -314,7 +317,7 @@ class Subprocess(object): if not line: break if self._verbose: - logger.info(line.strip()) + logger.log(line.strip()) if fp: fp.write(line) fp.flush() diff --git a/tests/test_10_venv.py b/tests/test_10_venv.py index eb5f352..639ca11 100644 --- a/tests/test_10_venv.py +++ b/tests/test_10_venv.py @@ -1,11 +1,21 @@ class VenvOptions(object): python = '2.6.6' all = False + no_site_packages = False def test_venv(): + import os from pythonbrew.commands.venv import VenvCommand + from pythonbrew.util import Subprocess + from pythonbrew.define import PATH_HOME_ETC_VENV + s = Subprocess() c = VenvCommand() + c.run_command(VenvOptions(), ['init']) c.run_command(VenvOptions(), ['create', 'aaa']) + s.shell('source %s' % PATH_HOME_ETC_VENV) c.run_command(VenvOptions(), ['list']) c.run_command(VenvOptions(), ['use', 'aaa']) c.run_command(VenvOptions(), ['delete', 'aaa']) + s.shell('source %s' % PATH_HOME_ETC_VENV) + # finish + os.unlink(PATH_HOME_ETC_VENV)