diff --git a/PKG-INFO b/PKG-INFO index 684b6f9..453420f 100644 --- a/PKG-INFO +++ b/PKG-INFO @@ -31,9 +31,9 @@ pythonbrew command [options] Install some Pythons:: pythonbrew install 2.6.6 - pythonbrew install Python-2.5.5 - pythonbrew install --configure="CC=gcc_4.1" Python-2.6.6 - pythonbrew install --no-setuptools Python-2.6.6 + pythonbrew install --force 2.5.5 + pythonbrew install --configure="CC=gcc_4.1" 2.6.6 + pythonbrew install --no-setuptools 2.6.6 pythonbrew install http://www.python.org/ftp/python/2.7/Python-2.7.tgz Switch python in the $PATH:: @@ -41,10 +41,17 @@ Switch python in the $PATH:: pythonbrew switch 2.6.6 pythonbrew switch Python-2.5.5 +Using python in the PATH:: + + pythonbrew use 2.6.6 + +List the installed versions of Python:: + + pythonbrew list + List the available install versions of Python:: - pythonbrew list 2.6 - pythonbrew list 3.0 + pythonbrew list -k Uninstall some Pythons:: @@ -80,12 +87,18 @@ installed List the installed versions of python. switch - Switch to the given version. + Switch to the given version of python. -list +use + Using the given version of python. + +list + List the installed versions of Python. + +list -k List the available install version of python. -uninstall Python- +uninstall Uninstall the given version of python. clean diff --git a/README.rst b/README.rst index 7c099aa..04c1b7d 100644 --- a/README.rst +++ b/README.rst @@ -30,20 +30,27 @@ pythonbrew command [options] Install some Pythons:: pythonbrew install 2.6.6 - pythonbrew install Python-2.5.5 - pythonbrew install --configure="CC=gcc_4.1" Python-2.6.6 - pythonbrew install --no-setuptools Python-2.6.6 + pythonbrew install --force 2.5.5 + pythonbrew install --configure="CC=gcc_4.1" 2.6.6 + pythonbrew install --no-setuptools 2.6.6 pythonbrew install http://www.python.org/ftp/python/2.7/Python-2.7.tgz Switch python in the $PATH:: pythonbrew switch 2.6.6 - pythonbrew switch Python-2.5.5 + pythonbrew switch 2.5.5 + +Using python in the PATH:: + + pythonbrew use 2.6.6 + +List the installed versions of Python:: + + pythonbrew list List the available install versions of Python:: - pythonbrew list 2.6 - pythonbrew list 3.0 + pythonbrew list -k Uninstall some Pythons:: @@ -79,12 +86,18 @@ installed List the installed versions of python. switch - Switch to the given version. + Switch to the given version of python. -list +use + Using the given version of python. + +list + List the installed versions of Python. + +list -k List the available install version of python. -uninstall Python- +uninstall Uninstall the given version of python. clean diff --git a/pythonbrew-install b/pythonbrew-install index b138d0c..a761572 100755 --- a/pythonbrew-install +++ b/pythonbrew-install @@ -1,6 +1,6 @@ #!/usr/bin/env bash -PYTHON=`command -v python` +PYTHONS="/usr/bin/python /usr/bin/python2 `command -v python`" CURL=`command -v curl` usage() @@ -22,7 +22,7 @@ parse_arguments() for arg do val=`echo "$arg" | sed -e "s;--[^=]*=;;"` case "$arg" in - --python=*) PYTHON="$val" ;; + --python=*) PYTHONS="$val $PYTHONS" ;; --help) usage ;; *) echo "Can't find the option. :$arg";; esac @@ -31,22 +31,28 @@ parse_arguments() parse_arguments $@ -if [[ ! -x $PYTHON ]] ; then - echo "pythonbrew required Python (2.4, 2.5 or 2.6)." - exit -fi if [[ ! -x $CURL ]] ; then echo "pythonbrew required curl. curl was not found in your path." + exit fi -PYTHON_VERSION=`$PYTHON -V 2>&1` -PYTHON_VERSION=${PYTHON_VERSION/"Python "/""} -PYTHON_VERSION_S=`echo $PYTHON_VERSION | sed -e "s/\(^[[:digit:]]\{1,\}.[[:digit:]]\{1,\}\).*/\1/"` - -if [[ $PYTHON_VERSION_S != "2.4" ]] && [[ $PYTHON_VERSION_S != "2.5" ]] && [[ $PYTHON_VERSION_S != "2.6" ]] ; then - printf "Python's version is $PYTHON_VERSION_S: - 2.4 <= python < 3.0 is required. -" +for PYTHON in $PYTHONS ; do + if [[ ! -x $PYTHON ]] ; then + continue + fi + + PYTHON_VERSION=`$PYTHON -V 2>&1` + PYTHON_VERSION=${PYTHON_VERSION/"Python "/""} + PYTHON_VERSION_S=`echo $PYTHON_VERSION | sed -e "s/\(^[[:digit:]]\{1,\}.[[:digit:]]\{1,\}\).*/\1/"` + + if [[ $PYTHON_VERSION_S = "2.4" ]] || [[ $PYTHON_VERSION_S = "2.5" ]] || [[ $PYTHON_VERSION_S = "2.6" ]] ; then + PYTHON_FOUND='1' + break + fi +done +if [[ $PYTHON_FOUND != '1' ]] ; then + echo "pythonbrew required Python (2.4, 2.5 or 2.6)." + #TODO Installing python. exit fi diff --git a/pythonbrew/commands/clean.py b/pythonbrew/commands/clean.py index 76c3ce7..99aed07 100644 --- a/pythonbrew/commands/clean.py +++ b/pythonbrew/commands/clean.py @@ -14,6 +14,6 @@ class CleanCommand(Command): def _clean(self, root): for dir in os.listdir(root): - rm_r("%s/%s" % (root, dir)) + rm_r(os.path.join(root, dir)) CleanCommand() diff --git a/pythonbrew/commands/installed.py b/pythonbrew/commands/installed.py index b8ba035..2524f13 100644 --- a/pythonbrew/commands/installed.py +++ b/pythonbrew/commands/installed.py @@ -1,9 +1,9 @@ import os -import sys from subprocess import Popen, PIPE from pythonbrew.basecommand import Command from pythonbrew.define import PATH_PYTHONS from pythonbrew.log import logger +from pythonbrew.util import get_current_python_path class InstalledCommand(Command): name = "installed" @@ -11,20 +11,14 @@ class InstalledCommand(Command): summary = "List the installed versions of python" def run_command(self, options, args): - cur = None - if not os.path.islink("%s/current" % PATH_PYTHONS): - p = Popen('command -v python', stdout=PIPE, shell=True) - p.wait() - if p.returncode == 0: - logger.info("%s (*)" % p.stdout.read().strip()) - elif os.path.islink("%s/current" % PATH_PYTHONS): - cur = os.path.basename(os.path.realpath("%s/current" % PATH_PYTHONS)) - for d in sorted(os.listdir("%s/" % PATH_PYTHONS)): - if d == "current": - continue - if cur == d: - logger.info("%s (*)" % cur) + cur = get_current_python_path() + for d in sorted(os.listdir('%s/' % PATH_PYTHONS)): + if cur == os.path.join(PATH_PYTHONS, d, 'bin','python'): + logger.info('%s (*)' % d) + cur = None else: - logger.info("%s" % (d)) - + logger.info(d) + if cur: + logger.info('%s (*)' % cur) + InstalledCommand() diff --git a/pythonbrew/commands/list.py b/pythonbrew/commands/list.py index 42b4153..3952ec5 100644 --- a/pythonbrew/commands/list.py +++ b/pythonbrew/commands/list.py @@ -1,25 +1,53 @@ +import os import re from pythonbrew.basecommand import Command -from pythonbrew.define import PYTHON_VERSION_URL, LATEST_VERSIONS_OF_PYTHON -from pythonbrew.util import Package +from pythonbrew.define import PYTHON_VERSION_URL, LATEST_VERSIONS_OF_PYTHON,\ + PATH_PYTHONS +from pythonbrew.util import Package, get_current_python_path from pythonbrew.log import logger class ListCommand(Command): name = "list" usage = "%prog [VERSION]" - summary = "List the available install version of python" - + summary = "List the installed versions of Python" + def __init__(self): super(ListCommand, self).__init__() self.parser.add_option( - "--all-versions", - dest="all_versions", - action="store_true", + '-a', '--all-versions', + dest='all_versions', + action='store_true', default=False, - help="All versions of Python are visible." + help='All versions of Python are visible' + ) + self.parser.add_option( + '-k', '--known', + dest='known', + action='store_true', + default=False, + help='List the available install versions of Python' ) def run_command(self, options, args): + if options.known: + self.available_install(options, args) + else: + self.installed(options, args) + + def installed(self, options, args): + logger.info('# installed pythons') + cur = get_current_python_path() + for d in sorted(os.listdir('%s/' % PATH_PYTHONS)): + if cur == os.path.join(PATH_PYTHONS, d, 'bin','python'): + logger.info('%s (*)' % d) + cur = None + else: + logger.info('%s' % d) + if cur: + logger.info('%s (*)' % cur) + + def available_install(self, options, args): + logger.info('# available install pythons') if args: pkg = Package(args[0]) _re = re.compile(r"%s" % pkg.name) @@ -31,7 +59,7 @@ class ListCommand(Command): for pkgname in pkgs: logger.info("%s" % pkgname) else: - print "Python version not found. `%s`" % pkg.name + logger.info("Python version not found. `%s`" % pkg.name) else: for pkgname in self._get_packages_name(options): logger.info("%s" % pkgname) diff --git a/pythonbrew/commands/switch.py b/pythonbrew/commands/switch.py index c5630bf..b4fc0b9 100644 --- a/pythonbrew/commands/switch.py +++ b/pythonbrew/commands/switch.py @@ -2,13 +2,13 @@ import os import sys from pythonbrew.basecommand import Command from pythonbrew.define import PATH_PYTHONS, PATH_BIN -from pythonbrew.util import off, symlink, Package +from pythonbrew.util import Package, write_current from pythonbrew.log import logger class SwitchCommand(Command): name = "switch" usage = "%prog VERSION" - summary = "Switch to the given version" + summary = "Switch to the given version of python" def run_command(self, options, args): if not args: @@ -20,19 +20,10 @@ class SwitchCommand(Command): if not os.path.isdir(pkgdir): logger.info("`%s` is not installed." % pkgname) sys.exit(1) - self._switch_dir(pkgdir) - logger.info("Switched to %s" % pkgname) - - def _switch_dir(self, pkgdir): - off() - symlink(pkgdir, "%s/current" % PATH_PYTHONS) + pkgbin = os.path.join(pkgdir,'bin') - # I want better code... - current_bin = os.path.join(PATH_PYTHONS,'current','bin') - if not os.path.isfile(os.path.join(current_bin,"python")): - if os.path.isfile(os.path.join(current_bin,"python3")): - symlink(os.path.realpath("%s/python3" % current_bin), os.path.join(PATH_BIN,"python")) - elif os.path.isfile(os.path.join(current_bin,"python3.0")): - symlink(os.path.realpath("%s/python3.0" % current_bin), os.path.join(PATH_BIN,"python")) + write_current('%s:%s' % (PATH_BIN, pkgbin)) + + logger.info("Switched to %s" % pkgname) SwitchCommand() diff --git a/pythonbrew/commands/uninstall.py b/pythonbrew/commands/uninstall.py index 35bcc74..90a3562 100644 --- a/pythonbrew/commands/uninstall.py +++ b/pythonbrew/commands/uninstall.py @@ -2,7 +2,7 @@ import os import sys from pythonbrew.basecommand import Command from pythonbrew.define import PATH_PYTHONS -from pythonbrew.util import off, rm_r, Package +from pythonbrew.util import off, rm_r, Package, get_current_python_path from pythonbrew.log import logger class UninstallCommand(Command): @@ -14,14 +14,12 @@ class UninstallCommand(Command): if args: pkg = Package(args[0]) pkgname = pkg.name - pkgpath = "%s/%s" % (PATH_PYTHONS, pkgname) + pkgpath = os.path.join(PATH_PYTHONS, pkgname) if not os.path.isdir(pkgpath): logger.info("`%s` is not installed." % pkgname) sys.exit(1) - if os.path.islink("%s/current" % PATH_PYTHONS): - curpath = os.path.realpath("%s/current" % PATH_PYTHONS) - if pkgpath == curpath: - off() + if get_current_python_path() == os.path.join(pkgpath,'bin','python'): + off() rm_r(pkgpath) else: self.parser.print_help() diff --git a/pythonbrew/commands/update.py b/pythonbrew/commands/update.py index 1e455c0..b17eb00 100644 --- a/pythonbrew/commands/update.py +++ b/pythonbrew/commands/update.py @@ -55,7 +55,6 @@ class UpdateCommand(Command): s.check_call('%s %s/pythonbrew_install.py --upgrade' % (sys.executable, extract_dir)) except: logger.error("Failed to update pythonbrew.") - raise sys.exit(1) logger.info("The pythonbrew has been updated.") diff --git a/pythonbrew/commands/use.py b/pythonbrew/commands/use.py new file mode 100644 index 0000000..36268b9 --- /dev/null +++ b/pythonbrew/commands/use.py @@ -0,0 +1,29 @@ +import os +import sys +from pythonbrew.basecommand import Command +from pythonbrew.define import PATH_PYTHONS, PATH_BIN +from pythonbrew.util import Package, write_temp +from pythonbrew.log import logger + +class UseCommand(Command): + name = "use" + usage = "%prog VERSION" + summary = "Using the given version of python" + + def run_command(self, options, args): + if not args: + logger.info("Unrecognized command line argument: argument not found.") + 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) + sys.exit(1) + pkgbin = os.path.join(pkgdir,'bin') + + write_temp('%s:%s' % (PATH_BIN, pkgbin)) + + logger.info("Using `%s`" % pkgname) + +UseCommand() diff --git a/pythonbrew/define.py b/pythonbrew/define.py index 6936fd3..12f5bc3 100644 --- a/pythonbrew/define.py +++ b/pythonbrew/define.py @@ -1,6 +1,6 @@ import os -VERSION = "0.6.2" +VERSION = "0.6.3" if os.environ.has_key("PYTHONBREW_ROOT"): ROOT = os.environ["PYTHONBREW_ROOT"] @@ -24,8 +24,10 @@ PATH_PATCHES_MACOSX_PYTHON25 = os.path.join(PATH_PATCHES_MACOSX,"python25") PATH_PATCHES_MACOSX_PYTHON24 = os.path.join(PATH_PATCHES_MACOSX,"python24") # file path -PATH_BIN_PYTHONBREW = os.path.join(PATH_BIN,"pythonbrew") -PATH_BIN_PYBREW = os.path.join(PATH_BIN,"pybrew") # pybrew is symlink as pythonbrew +PATH_BIN_PYTHONBREW = os.path.join(PATH_BIN,'pythonbrew') +PATH_BIN_PYBREW = os.path.join(PATH_BIN,'pybrew') # pybrew is symlink as pythonbrew +PATH_ETC_CURRENT = os.path.join(PATH_ETC,'current') +PATH_ETC_TEMP = os.path.join(PATH_ETC,'temp') # download setuptools url DISTRIBUTE_SETUP_DLSITE = "http://python-distribute.org/distribute_setup.py" diff --git a/pythonbrew/installer.py b/pythonbrew/installer.py index 6d6a834..4277c03 100644 --- a/pythonbrew/installer.py +++ b/pythonbrew/installer.py @@ -142,6 +142,7 @@ class PythonInstaller(object): 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) sys.exit(1) + self.symlink() self.install_setuptools() logger.info("Installed %(pkgname)s successfully. Run the following command to switch to %(pkgname)s." % {"pkgname":self.pkg.name}) @@ -239,7 +240,18 @@ class PythonInstaller(object): makedirs(self.install_dir) s = Subprocess(log=self.logfile, cwd=self.build_dir) s.check_call("make install") - + + def symlink(self): + install_dir = os.path.realpath(self.install_dir) + path_python = os.path.join(install_dir,'bin','python') + if not os.path.isfile(path_python): + path_python3 = os.path.join(install_dir,'bin','python3') + path_python3_0 = os.path.join(install_dir,'bin','python3.0') + if os.path.isfile(path_python3): + symlink(path_python3, path_python) + elif os.path.isfile(path_python3_0): + symlink(path_python3_0, path_python) + def install_setuptools(self): options = self.options pkgname = self.pkg.name diff --git a/pythonbrew/scripts/bashrc b/pythonbrew/scripts/bashrc index f4f2ed6..e4adb61 100644 --- a/pythonbrew/scripts/bashrc +++ b/pythonbrew/scripts/bashrc @@ -1,7 +1,36 @@ PYTHONBREW_ROOT="@ROOT@" PYTHONBREW_ETC="$PYTHONBREW_ROOT/etc" -export PATH=$PYTHONBREW_ROOT/bin:$PYTHONBREW_ROOT/pythons/current/bin:${PATH} +__pythonbrew_set_default() +{ + PATH_PYTHONBREW="$PYTHONBREW_ROOT/bin" +} + +__pythonbrew_set_path() +{ + PATH_WITHOUT_PYTHONBREW=$(printf $PATH | awk -v RS=: -v ORS=: "/${PYTHONBREW_ROOT//\//\/}/ {next} {print}" | sed -e 's#:$##') + export PATH=$PATH_PYTHONBREW:$PATH_WITHOUT_PYTHONBREW +} + +__pythonbrew_set_temp_path() +{ + if [[ -s "$PYTHONBREW_ETC/temp" ]] ; then + source "$PYTHONBREW_ETC/temp" + else + __pythonbrew_set_default + fi + __pythonbrew_set_path +} + +__pythonbrew_set_current_path() +{ + if [[ -s "$PYTHONBREW_ETC/current" ]] ; then + source "$PYTHONBREW_ETC/current" + else + __pythonbrew_set_default + fi + __pythonbrew_set_path +} __pythonbrew_reload() { @@ -10,11 +39,41 @@ __pythonbrew_reload() fi } -pythonbrew() +__pythonbrew_use() { command pythonbrew "$@" - case $1 in - update) __pythonbrew_reload ;; - esac - hash -r + __pythonbrew_set_temp_path } + +__pythonbrew_switch() +{ + command pythonbrew "$@" + __pythonbrew_set_current_path +} + +__pythonbrew_off() +{ + command pythonbrew "$@" + __pythonbrew_set_current_path +} + +__pythonbrew_update() +{ + command pythonbrew "$@" + __pythonbrew_reload +} + +pythonbrew() +{ + case $1 in + use) __pythonbrew_use "$@";; + switch) __pythonbrew_switch "$@" ;; + off) __pythonbrew_off "$@" ;; + update) __pythonbrew_update "$@" ;; + *) command pythonbrew "$@" ;; + esac + builtin hash -r +} + +# main +__pythonbrew_set_current_path diff --git a/pythonbrew/util.py b/pythonbrew/util.py index 62299fb..0ccda5b 100644 --- a/pythonbrew/util.py +++ b/pythonbrew/util.py @@ -4,11 +4,13 @@ import shutil import subprocess import re import posixpath -from pythonbrew.define import PATH_BIN, PATH_PYTHONS -from pythonbrew.exceptions import ShellCommandException -from pythonbrew.log import logger import tarfile import platform +from pythonbrew.define import PATH_BIN, PATH_PYTHONS, PATH_ETC_CURRENT,\ + PATH_ETC_TEMP +from pythonbrew.exceptions import ShellCommandException +from pythonbrew.log import logger +from subprocess import PIPE, Popen def size_format(b): kb = 1000 @@ -99,6 +101,7 @@ def off(): continue unlink("%s/%s" % (root, f)) unlink("%s/current" % PATH_PYTHONS) + write_current(PATH_BIN) def split_leading_dir(path): path = str(path) @@ -183,7 +186,25 @@ def unpack_downloadfile(content_type, download_file, target_dir): logger.error("Cannot determine archive format of %s" % download_file) return False return True - + +def get_current_python_path(): + p = Popen('command -v python', stdout=PIPE, shell=True) + p.wait() + if p.returncode == 0: + return p.stdout.read().strip() + else: + return None + +def write_current(path): + fp = open(PATH_ETC_CURRENT, 'w') + fp.write('PATH_PYTHONBREW="%s"\n' % (path)) + fp.close() + +def write_temp(path): + fp = open(PATH_ETC_TEMP, 'w') + fp.write('PATH_PYTHONBREW="%s"\n' % (path)) + fp.close() + class Subprocess(object): def __init__(self, log=None, shell=True, cwd=None, print_cmd=False): self._log = log