release 0.9

This commit is contained in:
utahta
2011-07-22 19:09:59 +09:00
parent cfdd193ffe
commit e033edcda0
30 changed files with 403 additions and 48 deletions
+57
View File
@@ -0,0 +1,57 @@
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_using_python_pkgname, Link, is_installed
from pythonbrew.log import logger
from pythonbrew.downloader import Downloader
class BuildoutCommand(Command):
name = "buildout"
usage = "%prog"
summary = "Runs the buildout with specified or current using python"
def __init__(self):
super(BuildoutCommand, 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 options.python:
pkgname = Package(options.python).name
else:
pkgname = get_using_python_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
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'])
BuildoutCommand()
+6 -6
View File
@@ -3,7 +3,8 @@ 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_using_python_pkgname,\
get_using_python_path
from pythonbrew.log import logger
class ListCommand(Command):
@@ -36,15 +37,14 @@ class ListCommand(Command):
def installed(self, options, args):
logger.info('# installed pythons')
cur = get_current_python_path()
cur = get_using_python_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:
logger.info('%s' % d)
if cur:
logger.info('%s (*)' % cur)
if not cur:
logger.info('%s (*)' % get_using_python_path())
def available_install(self, options, args):
logger.info('# available install pythons')
+3 -4
View File
@@ -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))
+7 -4
View File
@@ -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.define import PATH_PYTHONS, PATH_BIN, PATH_VENVS
from pythonbrew.util import off, rm_r, Package, get_using_python_pkgname, unlink,\
is_installed
from pythonbrew.log import logger
class UninstallCommand(Command):
@@ -16,10 +17,11 @@ class UninstallCommand(Command):
pkg = Package(arg)
pkgname = pkg.name
pkgpath = os.path.join(PATH_PYTHONS, pkgname)
if not os.path.isdir(pkgpath):
venvpath = os.path.join(PATH_VENVS, pkgname)
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_using_python_pkgname() == pkgname:
off()
for d in os.listdir(PATH_BIN):
# remove symlink
@@ -30,6 +32,7 @@ class UninstallCommand(Command):
if os.path.isfile(tgtpath) and os.path.samefile(path, tgtpath):
unlink(path)
rm_r(pkgpath)
rm_r(venvpath)
else:
self.parser.print_help()
+158
View File
@@ -0,0 +1,158 @@
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.log import logger
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'
)
self.parser.add_option(
"-a", "--all",
dest="all",
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
"""
def run_command(self, options, args):
if not args:
logger.error('Unrecognized command line argument: ( see: \'pythonbrew help venv\' )')
sys.exit(1)
cmd = args[0]
if not cmd in ('create', 'delete', 'use', 'list'):
logger.error('Unrecognized command line argument: ( see: \'pythonbrew help venv\' )')
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 <python2.4 - 2.7>\'.')
sys.exit(1)
venv_dir = os.path.join(PATH_PYTHONS, venv_pkgname)
venv_bin = os.path.join(venv_dir, 'bin')
# target python interpreter
if options.python:
pkgname = Package(options.python).name
if not is_installed(pkgname):
logger.error('%s is not installed.' % pkgname)
sys.exit(1)
else:
pkgname = get_using_python_pkgname()
if not pkgname:
logger.error('Can not use venv command before using a python. Try \'pythonbrew switch <some python>\'.')
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')
# 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'))
# Create a shell script
try:
self.__getattribute__('run_command_%s' % cmd)(options, args)
except:
logger.error('`%s` command not found.' % cmd)
sys.exit(1)
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}]
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})
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}]
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))
def run_command_use(self, options, args):
if len(args) < 2:
logger.error("Unrecognized command line argument: ( 'pythonbrew venv use <project>' )")
sys.exit(1)
template = self.template_env + """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]})
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))
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})
def _write(self, src):
fp = open(PATH_ETC_VENV, 'w')
fp.write(src)
fp.close()
VenvCommand()
+6 -1
View File
@@ -6,7 +6,7 @@ except:
import configparser as ConfigParser
# pythonbrew version
VERSION = "0.8"
VERSION = "0.9"
# pythonbrew root path
ROOT = os.environ.get("PYTHONBREW_ROOT")
@@ -23,6 +23,7 @@ PATH_DISTS = os.path.join(ROOT,"dists")
PATH_ETC = os.path.join(ROOT,"etc")
PATH_BIN = os.path.join(ROOT,"bin")
PATH_LOG = os.path.join(ROOT,"log")
PATH_VENVS = os.path.join(ROOT, "venvs")
PATH_SCRIPTS = os.path.join(ROOT,"scripts")
PATH_SCRIPTS_PYTHONBREW = os.path.join(PATH_SCRIPTS,"pythonbrew")
PATH_SCRIPTS_PYTHONBREW_COMMANDS = os.path.join(PATH_SCRIPTS_PYTHONBREW,"commands")
@@ -40,6 +41,7 @@ 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')
# read config.cfg
config = ConfigParser.SafeConfigParser()
@@ -53,6 +55,9 @@ def _get_or_default(section, option, default=''):
# setuptools download
DISTRIBUTE_SETUP_DLSITE = _get_or_default('distribute', 'url')
# buildout bootstrap download
BOOTSTRAP_DLSITE = _get_or_default('bootstrap', 'url')
# pythonbrew download
PYTHONBREW_UPDATE_URL_MASTER = _get_or_default('pythonbrew', 'master')
PYTHONBREW_UPDATE_URL_DEVELOP = _get_or_default('pythonbrew', 'develop')
+12
View File
@@ -61,6 +61,17 @@ __pythonbrew_update()
[[ $? == 0 ]] && __pythonbrew_reload
}
__pythonbrew_venv()
{
command pythonbrew "$@"
if [[ $? == 0 ]] ; then
if [[ -s "$PATH_ETC/venv.run" ]] ; then
source "$PATH_ETC/venv.run"
cat /dev/null > "$PATH_ETC/venv.run"
fi
fi
}
__pythonbrew_find_command()
{
command_name=""
@@ -84,6 +95,7 @@ pythonbrew()
switch) __pythonbrew_switch "$@" ;;
off) __pythonbrew_off "$@" ;;
update) __pythonbrew_update "$@" ;;
venv) __pythonbrew_venv "$@" ;;
*) command pythonbrew "$@" ;;
esac
builtin hash -r
+3
View File
@@ -1,6 +1,9 @@
[distribute]
url = http://python-distribute.org/distribute_setup.py
[bootstrap]
url = http://svn.zope.org/*checkout*/zc.buildout/trunk/bootstrap/bootstrap.py
[pythonbrew]
master = https://github.com/utahta/pythonbrew/tarball/master
develop = https://github.com/utahta/pythonbrew/tarball/develop
+2 -1
View File
@@ -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_SCRIPTS_PYTHONBREW_INSTALLER, PATH_VENVS
import stat
class PythonbrewInstaller(object):
@@ -22,6 +22,7 @@ class PythonbrewInstaller(object):
makedirs(PATH_ETC)
makedirs(PATH_BIN)
makedirs(PATH_LOG)
makedirs(PATH_VENVS)
# create script directories
rm_r(PATH_SCRIPTS)
+42 -15
View File
@@ -9,7 +9,8 @@ import platform
import urllib
import subprocess
import shlex
from pythonbrew.define import PATH_BIN, PATH_ETC_CURRENT
import select
from pythonbrew.define import PATH_BIN, PATH_ETC_CURRENT, PATH_PYTHONS
from pythonbrew.exceptions import ShellCommandException
from pythonbrew.log import logger
@@ -93,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:
@@ -212,12 +209,29 @@ def extract_downloadfile(content_type, download_file, target_dir):
return False
return True
def get_current_python_path():
"""return: python path or ''
"""
def get_using_python_path():
p = subprocess.Popen('command -v python', stdout=subprocess.PIPE, shell=True)
return to_str(p.communicate()[0].strip())
def get_using_python_pkgname():
"""return: Python-<VERSION> or None"""
path = get_using_python_path()
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 get_installed_pythons_pkgname():
"""Get the installed python versions list."""
return [d for d in sorted(os.listdir(PATH_PYTHONS))]
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))
@@ -254,6 +268,16 @@ def is_str(val):
return isinstance(val, str)
return False
def bltin_any(iter):
try:
return any(iter)
except:
# python2.4
for it in iter:
if it:
return True
return False
class Subprocess(object):
def __init__(self, log=None, cwd=None, verbose=False, debug=False):
self._log = log
@@ -285,13 +309,16 @@ class Subprocess(object):
fp = ((self._log and open(self._log, 'a')) or None)
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=self._cwd)
while p.returncode is None:
while bltin_any(select.select([p.stdout], [], [])):
line = to_str(p.stdout.readline())
if not line:
break
if self._verbose:
logger.info(line.strip())
if fp:
fp.write(line)
fp.flush()
p.poll()
line = to_str(p.stdout.readline())
if self._verbose:
logger.info(line.strip())
if fp:
fp.write(line)
fp.flush()
if fp:
fp.close()
return p.returncode