mirror of
https://github.com/kennethreitz-archive/python-build.git
synced 2026-06-05 23:30:18 +00:00
update 0.5
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
* 0.5
|
||||
- This version is incompatible with the 0.4 or less.
|
||||
- Split the file.
|
||||
- Added pythonbrew-install script.
|
||||
- Added pybrew script. This is a symbolic pythonbrew.
|
||||
- Rename `search` to `list`.
|
||||
- Removed `init`.
|
||||
- Added syntax that `pythonbrew command <VERSION>`
|
||||
+17
-31
@@ -13,48 +13,42 @@ Following python version is required to use pythonbrew:
|
||||
|
||||
The recommended way to download and install pythonbrew is to run these statements in your shell.::
|
||||
|
||||
curl -LO http://github.com/utahta/pythonbrew/raw/master/pythonbrew
|
||||
chmod +x pythonbrew
|
||||
./pythonbrew install
|
||||
curl -LO http://github.com/utahta/pythonbrew/raw/master/pythonbrew-install
|
||||
chmod +x pythonbrew-install
|
||||
./pythonbrew-install
|
||||
|
||||
After that, pythonbrew installs itself to ~/python/pythonbrew/bin, and you should follow the instruction on screen to setup your .bashrc or .cshrc to put it in your PATH.
|
||||
After that, pythonbrew installs itself to ~/.pythonbrew/bin, and you should follow the instruction on screen to setup your .bashrc or .cshrc to put it in your PATH.
|
||||
|
||||
If you need to install pythonbrew into somewhere else, you can do that by setting a PYTHONBREW_ROOT environment variable.::
|
||||
|
||||
export PYTHONBREW_ROOT=/path/to/pythonbrew
|
||||
./pythonbrew install
|
||||
./pythonbrew-install
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
pythonbrew command [options]
|
||||
|
||||
Initialize::
|
||||
|
||||
pythonbrew init
|
||||
|
||||
Install some Pythons::
|
||||
|
||||
pythonbrew install Python-3.1.2
|
||||
pythonbrew install Python-2.6.6
|
||||
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 http://www.python.org/ftp/python/2.6.6/Python-2.6.6.tgz
|
||||
pythonbrew install /path/to/Python-2.6.6.tgz
|
||||
|
||||
Switch python in the $PATH::
|
||||
|
||||
pythonbrew switch Python-2.6.6
|
||||
pythonbrew switch /path/to/python
|
||||
pythonbrew switch 2.6.6
|
||||
pythonbrew switch Python-2.5.5
|
||||
|
||||
Search python packages::
|
||||
List the available install versions of Python::
|
||||
|
||||
pythonbrew search Python-2.6
|
||||
pythonbrew search Python-3
|
||||
pythonbrew list 2.6
|
||||
pythonbrew list 3.0
|
||||
|
||||
Uninstall some Pythons::
|
||||
|
||||
pythonbrew uninstall Python-2.6.6
|
||||
pythonbrew uninstall 2.6.6
|
||||
|
||||
Remove stale source folders and archives::
|
||||
|
||||
@@ -75,12 +69,7 @@ Show version::
|
||||
COMMANDS
|
||||
========
|
||||
|
||||
init
|
||||
Run this once to setup the pythonbrew directory ready for installing.
|
||||
|
||||
pythons into. Run it again if you decide to change PYTHONBREW_ROOT.
|
||||
|
||||
install Python-<version>
|
||||
install <version>
|
||||
Build and install the given version of Python.
|
||||
|
||||
Setuptools and pip is automatically installed.
|
||||
@@ -90,14 +79,11 @@ install Python-<version>
|
||||
installed
|
||||
List the installed versions of python.
|
||||
|
||||
switch Python-<version>
|
||||
switch <version>
|
||||
Switch to the given version.
|
||||
|
||||
switch /path/to/python
|
||||
Switch to the given version of python.
|
||||
|
||||
search Python-<version>
|
||||
Search Python packages.
|
||||
list <version>
|
||||
List the available install version of python.
|
||||
|
||||
uninstall Python-<version>
|
||||
Uninstall the given version of python.
|
||||
|
||||
-696
@@ -1,696 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
|
||||
import os
|
||||
import sys
|
||||
import urllib
|
||||
import errno
|
||||
import re
|
||||
import shutil
|
||||
import filecmp
|
||||
import subprocess
|
||||
import tempfile
|
||||
from HTMLParser import HTMLParser
|
||||
from optparse import OptionParser
|
||||
|
||||
VERSION = "0.4"
|
||||
if os.environ.has_key("PYTHONBREW_ROOT"):
|
||||
ROOT = os.environ["PYTHONBREW_ROOT"]
|
||||
else:
|
||||
ROOT = "%s/python/pythonbrew" % os.environ["HOME"]
|
||||
PYTHONDLSITE = "http://www.python.org/ftp/python/%s/%s"
|
||||
DISTRIBUTE_SETUP_DLSITE = "http://python-distribute.org/distribute_setup.py"
|
||||
PYTHONBREW_DLSITE = "http://github.com/utahta/pythonbrew/raw/master/pythonbrew"
|
||||
|
||||
PATH_PYTHONS = "%s/pythons" % ROOT
|
||||
PATH_BUILD = "%s/build" % ROOT
|
||||
PATH_DISTS = "%s/dists" % ROOT
|
||||
PATH_ETC = "%s/etc" % ROOT
|
||||
PATH_BIN = "%s/bin" % ROOT
|
||||
|
||||
parser = OptionParser(usage="%prog COMMAND [OPTIONS]",
|
||||
version=VERSION,
|
||||
add_help_option=False)
|
||||
parser.add_option(
|
||||
'-h', '--help',
|
||||
dest='help',
|
||||
action='store_true',
|
||||
help='Show help')
|
||||
parser.disable_interspersed_args()
|
||||
|
||||
command_dict = {}
|
||||
def add_command(command):
|
||||
command_dict[command.name] = command
|
||||
|
||||
#----------------------------------------------------
|
||||
# exception
|
||||
#----------------------------------------------------
|
||||
class BuildingException(Exception):
|
||||
"""General exception during building"""
|
||||
|
||||
#----------------------------------------------------
|
||||
# util
|
||||
#----------------------------------------------------
|
||||
def size_format(b):
|
||||
kb = 1000
|
||||
mb = kb*kb
|
||||
b = float(b)
|
||||
if b >= mb:
|
||||
return "%.1fMb" % (b/mb)
|
||||
if b >= kb:
|
||||
return "%.1fKb" % (b/kb)
|
||||
return "%.0fbytes" % (b)
|
||||
|
||||
def is_url(name):
|
||||
if ':' not in name:
|
||||
return False
|
||||
scheme = name.split(':', 1)[0].lower()
|
||||
return scheme in ['http', 'https', 'file', 'ftp']
|
||||
|
||||
def splitext(name):
|
||||
base, ext = os.path.splitext(name)
|
||||
if base.lower().endswith('.tar'):
|
||||
ext = base[-4:] + ext
|
||||
base = base[:-4]
|
||||
return base, ext
|
||||
|
||||
def is_archive_file(name):
|
||||
ext = splitext(name)[1].lower()
|
||||
archives = ('.zip', '.tar.gz', '.tar.bz2', '.tgz', '.tar')
|
||||
if ext in archives:
|
||||
return True
|
||||
return False
|
||||
|
||||
def makedirs(path):
|
||||
try:
|
||||
os.makedirs(path)
|
||||
except OSError, (e, es):
|
||||
if errno.EEXIST != e:
|
||||
raise
|
||||
|
||||
def symlink(src, dst):
|
||||
try:
|
||||
os.symlink(src, dst)
|
||||
except:
|
||||
pass
|
||||
|
||||
def unlink(path):
|
||||
try:
|
||||
os.unlink(path)
|
||||
except OSError, (e, es):
|
||||
if errno.ENOENT != e:
|
||||
raise
|
||||
|
||||
def rm_r(path):
|
||||
"""like rm -r command."""
|
||||
if os.path.isdir(path):
|
||||
shutil.rmtree(path)
|
||||
else:
|
||||
unlink(path)
|
||||
|
||||
def off():
|
||||
for root, dirs, files in os.walk(PATH_BIN):
|
||||
for f in files:
|
||||
if f == "pythonbrew":
|
||||
continue
|
||||
unlink("%s/%s" % (root, f))
|
||||
unlink("%s/current" % PATH_PYTHONS)
|
||||
|
||||
def copy_myself(path):
|
||||
(fd, src) = tempfile.mkstemp()
|
||||
fp = file(path, "r")
|
||||
line = fp.readline()
|
||||
if line.startswith("#!"):
|
||||
os.write(fd, "#!%s\n" % os.path.realpath(sys.executable))
|
||||
else:
|
||||
os.write(fd, line)
|
||||
os.write(fd, fp.read())
|
||||
os.close(fd)
|
||||
fp.close()
|
||||
|
||||
dist = "%s/pythonbrew" % PATH_BIN
|
||||
if os.path.isfile(src) and os.path.isfile(dist):
|
||||
if filecmp.cmp(src, dist):
|
||||
unlink(src)
|
||||
return (False, dist)
|
||||
makedirs(PATH_BIN)
|
||||
shutil.copy(src, dist)
|
||||
os.chmod(dist, 0755)
|
||||
unlink(src)
|
||||
return (True, dist)
|
||||
|
||||
#----------------------------------------------------
|
||||
# classes
|
||||
#----------------------------------------------------
|
||||
class Downloader(object):
|
||||
def __init__(self):
|
||||
self._msg = ""
|
||||
self._last_msg = ""
|
||||
self._bytes = 0.0
|
||||
|
||||
def download(self, msg, url, path):
|
||||
self._msg = msg
|
||||
self._bytes = 0
|
||||
urllib.urlretrieve(url, path, self._download_progress)
|
||||
print " downloaded."
|
||||
|
||||
def _download_progress(self, block, blockbytes, maxbytes):
|
||||
self._bytes += float(blockbytes)
|
||||
if self._bytes >= maxbytes:
|
||||
self._bytes = maxbytes
|
||||
percent = (self._bytes / maxbytes) * 100
|
||||
max_size = size_format(maxbytes)
|
||||
now_size = size_format(self._bytes)
|
||||
now_msg = "\rDownloading %s (%s): %3i%% %s" % (self._msg, max_size, percent, now_size)
|
||||
padding = " " * (len(self._last_msg) - len(now_msg))
|
||||
sys.stdout.write("%s%s" % (now_msg, padding))
|
||||
sys.stdout.flush()
|
||||
self._last_msg = now_msg
|
||||
|
||||
class Subprocess(object):
|
||||
def __init__(self, log=None, shell=False, cwd=None, print_cmd=True):
|
||||
self._log = log
|
||||
self._shell = shell
|
||||
self._cwd = cwd
|
||||
self._print_cmd = print_cmd
|
||||
|
||||
def chdir(self, cwd):
|
||||
self._cwd = cwd
|
||||
|
||||
def check_call(self, cmd, shell=None, cwd=None):
|
||||
if shell:
|
||||
self._shell = shell
|
||||
if cwd:
|
||||
self._cwd = cwd
|
||||
if self._print_cmd:
|
||||
print cmd
|
||||
if self._log:
|
||||
cmd = "(%s) >> '%s' 2>&1" % (cmd, self._log)
|
||||
retcode = subprocess.call(cmd, shell=self._shell, cwd=self._cwd)
|
||||
if retcode != 0:
|
||||
raise BuildingException()
|
||||
|
||||
class PythonVersionParser(HTMLParser):
|
||||
def __init__(self):
|
||||
HTMLParser.__init__(self)
|
||||
self._versions = []
|
||||
self._re = re.compile("^(\d+\.\d+(\..*)?)/$")
|
||||
|
||||
def handle_starttag(self, tag, attrs):
|
||||
if tag == "a":
|
||||
attrs = dict(attrs)
|
||||
if "href" in attrs:
|
||||
m = self._re.search(attrs["href"])
|
||||
if m:
|
||||
self._versions.append(m.group(1))
|
||||
|
||||
def get_sorted_versions(self):
|
||||
return sorted(self._versions)
|
||||
|
||||
class PythonPackages(object):
|
||||
def __init__(self):
|
||||
parser = PythonVersionParser()
|
||||
fp = urllib.urlopen("http://www.python.org/ftp/python/")
|
||||
parser.feed(fp.read())
|
||||
fp.close()
|
||||
parser.close()
|
||||
self._versions = parser.get_sorted_versions()
|
||||
|
||||
def has_version(self, version):
|
||||
return version in self._versions
|
||||
|
||||
def get_packages(self):
|
||||
return ["Python-%s" % v for v in self._versions]
|
||||
|
||||
#----------------------------------------------------
|
||||
# commands
|
||||
#----------------------------------------------------
|
||||
class Command(object):
|
||||
name = None
|
||||
usage = None
|
||||
summary = ""
|
||||
|
||||
def __init__(self):
|
||||
self.parser = OptionParser(usage=self.usage,
|
||||
prog='%s %s' % (os.path.basename(sys.argv[0]), self.name))
|
||||
|
||||
def run(self, args):
|
||||
options, args = self.parser.parse_args(args)
|
||||
self.run_command(options, args[1:])
|
||||
|
||||
class HelpCommand(Command):
|
||||
name = "help"
|
||||
usage = "%prog [COMMAND]"
|
||||
summary = "Show available commands"
|
||||
|
||||
def run_command(self, options, args):
|
||||
if args:
|
||||
command = args[0]
|
||||
if command not in command_dict:
|
||||
parser.error("Unknown command: `%s`" % command)
|
||||
return
|
||||
command = command_dict[command]
|
||||
command.parser.print_help()
|
||||
return
|
||||
parser.print_help()
|
||||
print
|
||||
print "Commands available:"
|
||||
commands = [command_dict[key] for key in sorted(command_dict.keys())]
|
||||
for command in commands:
|
||||
print " %s: %s" % (command.name, command.summary)
|
||||
print
|
||||
print "Further Instructions:"
|
||||
print " http://github.com/utahta/pythonbrew"
|
||||
|
||||
class InitCommand(Command):
|
||||
name = "init"
|
||||
usage = "%prog"
|
||||
summary = "Run this once to setup the pythonbrew directory ready for installing pythons into"
|
||||
|
||||
def run_command(self, options, args):
|
||||
makedirs(PATH_PYTHONS)
|
||||
makedirs(PATH_BUILD)
|
||||
makedirs(PATH_DISTS)
|
||||
makedirs(PATH_ETC)
|
||||
|
||||
os.system("echo 'export PATH=%s/bin:%s/current/bin:${PATH}' > %s/bashrc" % (ROOT, PATH_PYTHONS, PATH_ETC))
|
||||
os.system("echo 'setenv PATH %s/bin:%s/current/bin:$PATH' > %s/cshrc" % (ROOT, PATH_PYTHONS, PATH_ETC))
|
||||
m = re.search("(t?csh)", os.environ.get("SHELL"))
|
||||
if m:
|
||||
shrc = "cshrc"
|
||||
yourshrc = m.group(1)+"rc"
|
||||
else:
|
||||
shrc = yourshrc = "bashrc"
|
||||
print """
|
||||
Pythonbrew environment initiated, required directories are created under
|
||||
|
||||
"""+ROOT+"""
|
||||
|
||||
Well-done! Congratulations! Please add the following line to the end
|
||||
of your ~/."""+yourshrc+"""
|
||||
|
||||
source """+PATH_ETC+"""/"""+shrc+"""
|
||||
|
||||
After that, exit this shell, start a new one, and install some fresh
|
||||
pythons:
|
||||
|
||||
pythonbrew install Python-2.6.6
|
||||
pythonbrew install Python-2.5.5
|
||||
|
||||
For further instructions, simply run:
|
||||
|
||||
pythonbrew
|
||||
|
||||
The default help messages will popup and tell you what to do!
|
||||
|
||||
Enjoy pythonbrew at $HOME!!
|
||||
INSTRUCTION"""
|
||||
|
||||
class InstallCommand(Command):
|
||||
name = "install"
|
||||
usage = "%prog [OPTIONS] PACKAGE_NAMES"
|
||||
summary = "Build and install the given version of python"
|
||||
|
||||
def __init__(self):
|
||||
super(InstallCommand, self).__init__()
|
||||
self.parser.add_option(
|
||||
"-f", "--force",
|
||||
dest="force",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Force installation of a Python."
|
||||
)
|
||||
self.parser.add_option(
|
||||
"-C", "--configure",
|
||||
dest="configure",
|
||||
default="",
|
||||
metavar="CONFIGURE_OPTIONS",
|
||||
help="Custom configure options."
|
||||
)
|
||||
self.parser.add_option(
|
||||
"-n", "--no-setuptools",
|
||||
dest="no_setuptools",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Skip installation of setuptools."
|
||||
)
|
||||
self._logfile = "%s/build.log" % ROOT
|
||||
|
||||
def run_command(self, options, args):
|
||||
if args:
|
||||
# Install Python
|
||||
self._install_python(args[0], options)
|
||||
else:
|
||||
# Install pythonbrew
|
||||
self._install_myself()
|
||||
|
||||
def _install_myself(self):
|
||||
executable = os.path.abspath(sys.argv[0])
|
||||
(retval, dist) = copy_myself(executable)
|
||||
if not retval:
|
||||
print "You are already running the installed latest version of pythonbrew."
|
||||
print "\n%s" % dist
|
||||
sys.exit()
|
||||
print """The pythonbrew is installed as:
|
||||
|
||||
"""+dist+"""
|
||||
|
||||
You may trash the downloaded """+executable+""" from now on.
|
||||
|
||||
Next, if this is the first time you've run pythonbrew installation, run:
|
||||
|
||||
"""+dist+""" init
|
||||
|
||||
And follow the instruction on screen."""
|
||||
|
||||
def _get_package(self, name):
|
||||
if not os.path.isfile(name) and not os.path.isdir(name):
|
||||
if is_url(name):
|
||||
basename = os.path.basename(name)
|
||||
download_url = name
|
||||
download_path = "%s/%s" % (PATH_DISTS, basename)
|
||||
else:
|
||||
m = re.search("^Python-(\d+\.\d+(\..*)?)$", name)
|
||||
if not m:
|
||||
print "Unknown package: `%s`" % name
|
||||
sys.exit(1)
|
||||
if os.path.isdir("%s/%s" % (PATH_PYTHONS, name)):
|
||||
print "You are already installed `%s`." % name
|
||||
sys.exit()
|
||||
dist_version = m.group(1)
|
||||
pkgs = PythonPackages()
|
||||
if not pkgs.has_version(dist_version):
|
||||
print "Package not found: `%s`" % name
|
||||
sys.exit(1)
|
||||
basename = "%s.tgz" % name
|
||||
download_url = PYTHONDLSITE % (dist_version, basename)
|
||||
download_path = "%s/%s" % (PATH_DISTS, basename)
|
||||
|
||||
if os.path.isfile(download_path):
|
||||
print "Use the previously fetched %s" % (download_path)
|
||||
else:
|
||||
try:
|
||||
dl = Downloader()
|
||||
dl.download(
|
||||
basename,
|
||||
download_url,
|
||||
download_path
|
||||
)
|
||||
except:
|
||||
unlink(download_path)
|
||||
print "\nInterrupt to abort. `%s`" % (download_url)
|
||||
sys.exit(1)
|
||||
# iffy
|
||||
if os.path.getsize(download_path) < 1000000:
|
||||
print "Failed to download. (maybe not stable version of python) `%s`" % (download_url)
|
||||
unlink(download_path)
|
||||
sys.exit(1)
|
||||
else:
|
||||
if is_archive_file(name):
|
||||
basename = os.path.basename(name)
|
||||
print "Copy the archive file %s to %s/%s" % (name, PATH_DISTS, basename)
|
||||
shutil.copy(name, "%s/%s" % (PATH_DISTS, basename))
|
||||
else:
|
||||
print "Invalid file. `%s`" % name
|
||||
sys.exit(1)
|
||||
return basename
|
||||
|
||||
def _get_uncompress_command(self, basename):
|
||||
distpath = "%s/%s" % (PATH_DISTS, basename)
|
||||
if os.path.isfile(distpath):
|
||||
ext = splitext(basename)[1]
|
||||
if ext == ".tar.gz" or ext == ".tgz":
|
||||
return "tar zxf %s" % (distpath)
|
||||
elif ext == ".tar.bz2":
|
||||
return "tar jxf %s" % (distpath)
|
||||
elif ext == ".tar":
|
||||
return "tar xf %s" % (distpath)
|
||||
elif ext == ".zip":
|
||||
return "unzip %s" % (distpath)
|
||||
elif os.path.isdir(distpath):
|
||||
return "mv %s %s/%s" % (distpath, PATH_BUILD, basename)
|
||||
else:
|
||||
print "File not found. `%s`" % (basename)
|
||||
return ""
|
||||
|
||||
def _install_python(self, dist, options):
|
||||
basename = self._get_package(dist)
|
||||
pkgname = splitext(basename)[0]
|
||||
|
||||
install_dir = "%s/%s" % (PATH_PYTHONS, pkgname)
|
||||
configure = "--prefix=%s %s" % (install_dir, options.configure)
|
||||
print "Installing %s into %s" % (pkgname, install_dir);
|
||||
print """This could take a while. You can run the following command on another shell to track the status:
|
||||
|
||||
tail -f %s
|
||||
""" % (self._logfile)
|
||||
try:
|
||||
s = Subprocess(log=self._logfile, shell=True, cwd=PATH_BUILD)
|
||||
s.check_call(self._get_uncompress_command(basename))
|
||||
|
||||
s.chdir("%s/%s" % (PATH_BUILD, pkgname))
|
||||
s.check_call("./configure %s" % (configure))
|
||||
if options.force:
|
||||
s.check_call("make")
|
||||
s.check_call("make install")
|
||||
else:
|
||||
s.check_call("make")
|
||||
s.check_call("make test")
|
||||
s.check_call("make install")
|
||||
except:
|
||||
print """Installing %(pkgname)s failed. See %(ROOT)s/build.log to see why.
|
||||
|
||||
pythonbrew install --force %(pkgname)s""" % {"pkgname":pkgname, "ROOT":ROOT}
|
||||
sys.exit(1)
|
||||
|
||||
# install setuptools
|
||||
self._install_setuptools(pkgname, options.no_setuptools)
|
||||
print """
|
||||
Installed %(pkgname)s successfully. Run the following command to switch to it.
|
||||
|
||||
pythonbrew switch %(pkgname)s""" % {"pkgname":pkgname}
|
||||
|
||||
def _install_setuptools(self, pkgname, no_setuptools):
|
||||
if no_setuptools:
|
||||
print "Skip installation setuptools."
|
||||
return
|
||||
if re.match("^Python-3.*", pkgname):
|
||||
is_python3 = True
|
||||
else:
|
||||
is_python3 = False
|
||||
download_url = DISTRIBUTE_SETUP_DLSITE
|
||||
basename = os.path.basename(download_url)
|
||||
|
||||
dl = Downloader()
|
||||
dl.download(basename, download_url, "%s/%s" % (PATH_DISTS, basename))
|
||||
|
||||
if is_python3:
|
||||
if os.path.isfile("%s/%s/bin/python3" % (PATH_PYTHONS, pkgname)):
|
||||
pyexec = "%s/%s/bin/python3" % (PATH_PYTHONS, pkgname)
|
||||
elif os.path.isfile("%s/%s/bin/python3.0" % (PATH_PYTHONS, pkgname)):
|
||||
pyexec = "%s/%s/bin/python3.0" % (PATH_PYTHONS, pkgname)
|
||||
else:
|
||||
print "Python3 binary not found. `%s/%s`" % (PATH_PYTHONS, pkgname)
|
||||
return
|
||||
else:
|
||||
pyexec = "%s/%s/bin/python" % (PATH_PYTHONS, pkgname)
|
||||
|
||||
try:
|
||||
s = Subprocess(log=self._logfile, shell=True, cwd=PATH_DISTS)
|
||||
s.check_call("%s %s" % (pyexec, basename))
|
||||
if os.path.isfile("%s/%s/bin/easy_install" % (PATH_PYTHONS, pkgname)) and not is_python3:
|
||||
s.check_call("%s/%s/bin/easy_install pip" % (PATH_PYTHONS, pkgname), cwd=None)
|
||||
except:
|
||||
print "Installing setuptools failed. See %s/build.log to see why." % (ROOT)
|
||||
sys.exit(1)
|
||||
|
||||
class InstalledCommand(Command):
|
||||
name = "installed"
|
||||
usage = "%prog"
|
||||
summary = "List the installed versions of python"
|
||||
|
||||
def run_command(self, options, args):
|
||||
if not os.path.islink("%s/current" % PATH_PYTHONS):
|
||||
cur = os.path.realpath("%s/bin/python" % ROOT)
|
||||
print "%s (*)" % cur
|
||||
elif os.path.islink("%s/current" % PATH_PYTHONS):
|
||||
cur = os.path.basename(os.path.realpath("%s/current" % PATH_PYTHONS))
|
||||
else:
|
||||
cur = ""
|
||||
for d in sorted(os.listdir("%s/" % PATH_PYTHONS)):
|
||||
if d == "current":
|
||||
continue
|
||||
if cur == d:
|
||||
print "%s (*)" % cur
|
||||
else:
|
||||
print "%s" % (d)
|
||||
|
||||
class SwitchCommand(Command):
|
||||
name = "switch"
|
||||
usage = "%prog PACKAGE"
|
||||
summary = "Switch to the given version"
|
||||
|
||||
def run_command(self, options, args):
|
||||
if args:
|
||||
dist = args[0]
|
||||
distdir = dist
|
||||
if os.path.isfile( dist ) and os.access( dist, os.X_OK ):
|
||||
if re.search( ".*python(\d(\.\d)?)?$", dist ):
|
||||
self._switch_file(dist)
|
||||
else:
|
||||
print "`%s` is not python binary." % dist
|
||||
return
|
||||
elif not os.path.isdir( "%s/%s" % (PATH_PYTHONS, dist) ):
|
||||
print "`%s` is not installed." % dist
|
||||
return
|
||||
self._switch_dir( distdir )
|
||||
|
||||
def _switch_file(self, dist):
|
||||
off()
|
||||
symlink(dist, "%s/python" % PATH_BIN)
|
||||
print "Switched to "+dist
|
||||
|
||||
def _switch_dir(self, dist):
|
||||
off()
|
||||
symlink(dist, "%s/current" % PATH_PYTHONS)
|
||||
for root, dirs, files in os.walk("%s/current/bin/" % PATH_PYTHONS):
|
||||
for f in files:
|
||||
symlink("%s%s" % (root, f), "%s/%s" % (PATH_BIN, f))
|
||||
break
|
||||
# I want better code
|
||||
if not os.path.isfile("%s/python" % PATH_BIN):
|
||||
if os.path.isfile("%s/python3" % PATH_BIN):
|
||||
symlink(os.path.realpath("%s/python3" % PATH_BIN), "%s/python" % PATH_BIN)
|
||||
elif os.path.isfile("%s/python3.0" % PATH_BIN):
|
||||
symlink(os.path.realpath("%s/python3.0" % PATH_BIN), "%s/python" % PATH_BIN)
|
||||
print "Switched to "+dist
|
||||
|
||||
class OffCommand(Command):
|
||||
name = "off"
|
||||
usage = "%prog"
|
||||
summary = "Disable pythonbrew"
|
||||
|
||||
def run_command(self, options, args):
|
||||
off()
|
||||
|
||||
class VersionCommand(Command):
|
||||
name = "version"
|
||||
usage = "%prog"
|
||||
summary = "Show version"
|
||||
|
||||
def run_command(self, options, args):
|
||||
print VERSION
|
||||
|
||||
class SearchCommand(Command):
|
||||
name = "search"
|
||||
usage = "%prog Python-<VERSION>"
|
||||
summary = "Search Python packages"
|
||||
|
||||
def run_command(self, options, args):
|
||||
pkgs = PythonPackages()
|
||||
if args:
|
||||
pattern = args[0]
|
||||
_re = re.compile(r"%s" % pattern)
|
||||
pkgnames = []
|
||||
for pkgname in pkgs.get_packages():
|
||||
if _re.match(pkgname):
|
||||
pkgnames.append(pkgname)
|
||||
if pkgnames:
|
||||
for pkgname in pkgnames:
|
||||
print pkgname
|
||||
else:
|
||||
print "Package not found. `%s`" % pattern
|
||||
else:
|
||||
for pkgname in pkgs.get_packages():
|
||||
print pkgname
|
||||
|
||||
class UninstallCommand(Command):
|
||||
name = "uninstall"
|
||||
usage = "%prog Python-<VERSION>"
|
||||
summary = "Uninstall the given version of python"
|
||||
|
||||
def run_command(self, options, args):
|
||||
if args:
|
||||
pkgname = args[0]
|
||||
pkgpath = "%s/%s" % (PATH_PYTHONS, pkgname)
|
||||
if not os.path.isdir(pkgpath):
|
||||
print "%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()
|
||||
rm_r(pkgpath)
|
||||
else:
|
||||
self.parser.print_help()
|
||||
|
||||
class CleanCommand(Command):
|
||||
name = "clean"
|
||||
usage = "%prog"
|
||||
summary = "Remove stale source folders and archives"
|
||||
|
||||
def run_command(self, options, args):
|
||||
self._clean(PATH_BUILD)
|
||||
self._clean(PATH_DISTS)
|
||||
|
||||
def _clean(self, root):
|
||||
for dir in os.listdir(root):
|
||||
rm_r("%s/%s" % (root, dir))
|
||||
|
||||
class UpdateCommand(Command):
|
||||
name = "update"
|
||||
usage = "%prog"
|
||||
summary = "Upgrades pythonbrew to the latest version"
|
||||
|
||||
def run_command(self, options, args):
|
||||
download_url = PYTHONBREW_DLSITE
|
||||
basename = os.path.basename(download_url)
|
||||
download_path = "%s/%s" % (PATH_DISTS, basename)
|
||||
|
||||
try:
|
||||
d = Downloader()
|
||||
d.download(basename, download_url, download_path)
|
||||
except:
|
||||
print "Failed to download. `%s`" % download_url
|
||||
sys.exit(1)
|
||||
|
||||
(retval, dist) = copy_myself(download_path)
|
||||
if not retval:
|
||||
print "You are already running the installed latest version of pythonbrew."
|
||||
print "\n%s" % dist
|
||||
sys.exit()
|
||||
print "The pythonbrew has been updated."
|
||||
|
||||
class Pythonbrew(object):
|
||||
def run(self):
|
||||
options, args = parser.parse_args(sys.argv[1:])
|
||||
if options.help and not args:
|
||||
args = ["help"]
|
||||
if not args:
|
||||
parser.error('You must give a command (use "pythonbrew help" to see a list of commands)')
|
||||
return
|
||||
add_command(HelpCommand())
|
||||
add_command(InitCommand())
|
||||
add_command(InstallCommand())
|
||||
add_command(InstalledCommand())
|
||||
add_command(SwitchCommand())
|
||||
add_command(OffCommand())
|
||||
add_command(VersionCommand())
|
||||
add_command(SearchCommand())
|
||||
add_command(UninstallCommand())
|
||||
add_command(CleanCommand())
|
||||
add_command(UpdateCommand())
|
||||
|
||||
command = args[0].lower()
|
||||
if command not in command_dict:
|
||||
parser.error("Unknown command: `%s`" % command)
|
||||
return
|
||||
command = command_dict[command]
|
||||
command.run(args)
|
||||
|
||||
def main():
|
||||
p = Pythonbrew()
|
||||
p.run()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Executable
+124
@@ -0,0 +1,124 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
PYTHON=`command -v python`
|
||||
|
||||
usage()
|
||||
{
|
||||
printf "
|
||||
Usage:
|
||||
|
||||
${0} [options]
|
||||
|
||||
options:
|
||||
|
||||
--python : Python interpreter.
|
||||
|
||||
"
|
||||
}
|
||||
|
||||
parse_arguments()
|
||||
{
|
||||
for arg do
|
||||
val=`echo "$arg" | sed -e "s;--[^=]*=;;"`
|
||||
case "$arg" in
|
||||
--python=*) PYTHON="$val" ;;
|
||||
--help) usage ;;
|
||||
*) echo "Can't find the option. :$arg";;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
parse_arguments $@
|
||||
|
||||
if [[ ! -x $PYTHON ]] ; then
|
||||
echo "I think $PYTHON is not Python interpreter."
|
||||
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.
|
||||
"
|
||||
exit
|
||||
fi
|
||||
|
||||
ROOT="$HOME/.pythonbrew"
|
||||
if [[ -n $PYTHONBREW_ROOT ]] ; then
|
||||
ROOT=$PYTHONBREW_ROOT
|
||||
fi
|
||||
PATH_DISTS="$ROOT/dists"
|
||||
PATH_ETC="$ROOT/etc"
|
||||
|
||||
mkdir -p $PATH_DISTS
|
||||
rm -rf $PATH_DISTS/pythonbrew.tar.gz
|
||||
rm -rf $PATH_DISTS/utahta-pythonbrew*
|
||||
|
||||
TEMP_TARBALL="pythonbrew.tar.gz"
|
||||
DOWNLOAD_URL="http://github.com/utahta/pythonbrew/tarball/master"
|
||||
|
||||
echo "Downloading $DOWNLOAD_URL"
|
||||
builtin cd $PATH_DISTS ; curl -L $DOWNLOAD_URL -o "$TEMP_TARBALL" > /dev/null 2>&1
|
||||
|
||||
echo "Extracting $PATH_DISTS/$TEMP_TARBALL"
|
||||
builtin cd $PATH_DISTS ; tar zxf $TEMP_TARBALL
|
||||
|
||||
TEMP_FILE=`ls $PATH_DISTS | grep utahta-pythonbrew`
|
||||
|
||||
echo "Installing pythonbrew into $ROOT"
|
||||
$PYTHON $PATH_DISTS/$TEMP_FILE/pythonbrew_install.py
|
||||
if [[ $? == 1 ]] ; then
|
||||
echo "Failed to install pythonbrew."
|
||||
exit
|
||||
fi
|
||||
|
||||
case $SHELL in
|
||||
*tcsh)
|
||||
shrc="cshrc"
|
||||
yourshrc="tcshrc"
|
||||
;;
|
||||
|
||||
*csh)
|
||||
shrc="cshrc"
|
||||
yourshrc=$shrc
|
||||
;;
|
||||
|
||||
*)
|
||||
shrc="bashrc"
|
||||
yourshrc=$shrc
|
||||
;;
|
||||
esac
|
||||
|
||||
printf "
|
||||
The pythonbrew is installed as:
|
||||
|
||||
$ROOT/bin/pythonbrew
|
||||
|
||||
You may trash the downloaded $0 from now on.
|
||||
|
||||
Pythonbrew environment initiated, required directories are created under
|
||||
|
||||
$ROOT
|
||||
|
||||
Well-done! Congratulations! Please add the following line to the end
|
||||
of your ~/.$yourshrc
|
||||
|
||||
source $PATH_ETC/$shrc
|
||||
|
||||
After that, exit this shell, start a new one, and install some fresh
|
||||
pythons:
|
||||
|
||||
pythonbrew install 2.6.6
|
||||
pythonbrew install 2.5.5
|
||||
|
||||
For further instructions, run:
|
||||
|
||||
pythonbrew help
|
||||
|
||||
The default help messages will popup and tell you what to do!
|
||||
|
||||
Enjoy pythonbrew at $ROOT!!
|
||||
"
|
||||
-696
@@ -1,696 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
|
||||
import os
|
||||
import sys
|
||||
import urllib
|
||||
import errno
|
||||
import re
|
||||
import shutil
|
||||
import filecmp
|
||||
import subprocess
|
||||
import tempfile
|
||||
from HTMLParser import HTMLParser
|
||||
from optparse import OptionParser
|
||||
|
||||
VERSION = "0.4"
|
||||
if os.environ.has_key("PYTHONBREW_ROOT"):
|
||||
ROOT = os.environ["PYTHONBREW_ROOT"]
|
||||
else:
|
||||
ROOT = "%s/python/pythonbrew" % os.environ["HOME"]
|
||||
PYTHONDLSITE = "http://www.python.org/ftp/python/%s/%s"
|
||||
DISTRIBUTE_SETUP_DLSITE = "http://python-distribute.org/distribute_setup.py"
|
||||
PYTHONBREW_DLSITE = "http://github.com/utahta/pythonbrew/raw/master/pythonbrew"
|
||||
|
||||
PATH_PYTHONS = "%s/pythons" % ROOT
|
||||
PATH_BUILD = "%s/build" % ROOT
|
||||
PATH_DISTS = "%s/dists" % ROOT
|
||||
PATH_ETC = "%s/etc" % ROOT
|
||||
PATH_BIN = "%s/bin" % ROOT
|
||||
|
||||
parser = OptionParser(usage="%prog COMMAND [OPTIONS]",
|
||||
version=VERSION,
|
||||
add_help_option=False)
|
||||
parser.add_option(
|
||||
'-h', '--help',
|
||||
dest='help',
|
||||
action='store_true',
|
||||
help='Show help')
|
||||
parser.disable_interspersed_args()
|
||||
|
||||
command_dict = {}
|
||||
def add_command(command):
|
||||
command_dict[command.name] = command
|
||||
|
||||
#----------------------------------------------------
|
||||
# exception
|
||||
#----------------------------------------------------
|
||||
class BuildingException(Exception):
|
||||
"""General exception during building"""
|
||||
|
||||
#----------------------------------------------------
|
||||
# util
|
||||
#----------------------------------------------------
|
||||
def size_format(b):
|
||||
kb = 1000
|
||||
mb = kb*kb
|
||||
b = float(b)
|
||||
if b >= mb:
|
||||
return "%.1fMb" % (b/mb)
|
||||
if b >= kb:
|
||||
return "%.1fKb" % (b/kb)
|
||||
return "%.0fbytes" % (b)
|
||||
|
||||
def is_url(name):
|
||||
if ':' not in name:
|
||||
return False
|
||||
scheme = name.split(':', 1)[0].lower()
|
||||
return scheme in ['http', 'https', 'file', 'ftp']
|
||||
|
||||
def splitext(name):
|
||||
base, ext = os.path.splitext(name)
|
||||
if base.lower().endswith('.tar'):
|
||||
ext = base[-4:] + ext
|
||||
base = base[:-4]
|
||||
return base, ext
|
||||
|
||||
def is_archive_file(name):
|
||||
ext = splitext(name)[1].lower()
|
||||
archives = ('.zip', '.tar.gz', '.tar.bz2', '.tgz', '.tar')
|
||||
if ext in archives:
|
||||
return True
|
||||
return False
|
||||
|
||||
def makedirs(path):
|
||||
try:
|
||||
os.makedirs(path)
|
||||
except OSError, (e, es):
|
||||
if errno.EEXIST != e:
|
||||
raise
|
||||
|
||||
def symlink(src, dst):
|
||||
try:
|
||||
os.symlink(src, dst)
|
||||
except:
|
||||
pass
|
||||
|
||||
def unlink(path):
|
||||
try:
|
||||
os.unlink(path)
|
||||
except OSError, (e, es):
|
||||
if errno.ENOENT != e:
|
||||
raise
|
||||
|
||||
def rm_r(path):
|
||||
"""like rm -r command."""
|
||||
if os.path.isdir(path):
|
||||
shutil.rmtree(path)
|
||||
else:
|
||||
unlink(path)
|
||||
|
||||
def off():
|
||||
for root, dirs, files in os.walk(PATH_BIN):
|
||||
for f in files:
|
||||
if f == "pythonbrew":
|
||||
continue
|
||||
unlink("%s/%s" % (root, f))
|
||||
unlink("%s/current" % PATH_PYTHONS)
|
||||
|
||||
def copy_myself(path):
|
||||
(fd, src) = tempfile.mkstemp()
|
||||
fp = file(path, "r")
|
||||
line = fp.readline()
|
||||
if line.startswith("#!"):
|
||||
os.write(fd, "#!%s\n" % os.path.realpath(sys.executable))
|
||||
else:
|
||||
os.write(fd, line)
|
||||
os.write(fd, fp.read())
|
||||
os.close(fd)
|
||||
fp.close()
|
||||
|
||||
dist = "%s/pythonbrew" % PATH_BIN
|
||||
if os.path.isfile(src) and os.path.isfile(dist):
|
||||
if filecmp.cmp(src, dist):
|
||||
unlink(src)
|
||||
return (False, dist)
|
||||
makedirs(PATH_BIN)
|
||||
shutil.copy(src, dist)
|
||||
os.chmod(dist, 0755)
|
||||
unlink(src)
|
||||
return (True, dist)
|
||||
|
||||
#----------------------------------------------------
|
||||
# classes
|
||||
#----------------------------------------------------
|
||||
class Downloader(object):
|
||||
def __init__(self):
|
||||
self._msg = ""
|
||||
self._last_msg = ""
|
||||
self._bytes = 0.0
|
||||
|
||||
def download(self, msg, url, path):
|
||||
self._msg = msg
|
||||
self._bytes = 0
|
||||
urllib.urlretrieve(url, path, self._download_progress)
|
||||
print " downloaded."
|
||||
|
||||
def _download_progress(self, block, blockbytes, maxbytes):
|
||||
self._bytes += float(blockbytes)
|
||||
if self._bytes >= maxbytes:
|
||||
self._bytes = maxbytes
|
||||
percent = (self._bytes / maxbytes) * 100
|
||||
max_size = size_format(maxbytes)
|
||||
now_size = size_format(self._bytes)
|
||||
now_msg = "\rDownloading %s (%s): %3i%% %s" % (self._msg, max_size, percent, now_size)
|
||||
padding = " " * (len(self._last_msg) - len(now_msg))
|
||||
sys.stdout.write("%s%s" % (now_msg, padding))
|
||||
sys.stdout.flush()
|
||||
self._last_msg = now_msg
|
||||
|
||||
class Subprocess(object):
|
||||
def __init__(self, log=None, shell=False, cwd=None, print_cmd=True):
|
||||
self._log = log
|
||||
self._shell = shell
|
||||
self._cwd = cwd
|
||||
self._print_cmd = print_cmd
|
||||
|
||||
def chdir(self, cwd):
|
||||
self._cwd = cwd
|
||||
|
||||
def check_call(self, cmd, shell=None, cwd=None):
|
||||
if shell:
|
||||
self._shell = shell
|
||||
if cwd:
|
||||
self._cwd = cwd
|
||||
if self._print_cmd:
|
||||
print cmd
|
||||
if self._log:
|
||||
cmd = "(%s) >> '%s' 2>&1" % (cmd, self._log)
|
||||
retcode = subprocess.call(cmd, shell=self._shell, cwd=self._cwd)
|
||||
if retcode != 0:
|
||||
raise BuildingException()
|
||||
|
||||
class PythonVersionParser(HTMLParser):
|
||||
def __init__(self):
|
||||
HTMLParser.__init__(self)
|
||||
self._versions = []
|
||||
self._re = re.compile("^(\d+\.\d+(\..*)?)/$")
|
||||
|
||||
def handle_starttag(self, tag, attrs):
|
||||
if tag == "a":
|
||||
attrs = dict(attrs)
|
||||
if "href" in attrs:
|
||||
m = self._re.search(attrs["href"])
|
||||
if m:
|
||||
self._versions.append(m.group(1))
|
||||
|
||||
def get_sorted_versions(self):
|
||||
return sorted(self._versions)
|
||||
|
||||
class PythonPackages(object):
|
||||
def __init__(self):
|
||||
parser = PythonVersionParser()
|
||||
fp = urllib.urlopen("http://www.python.org/ftp/python/")
|
||||
parser.feed(fp.read())
|
||||
fp.close()
|
||||
parser.close()
|
||||
self._versions = parser.get_sorted_versions()
|
||||
|
||||
def has_version(self, version):
|
||||
return version in self._versions
|
||||
|
||||
def get_packages(self):
|
||||
return ["Python-%s" % v for v in self._versions]
|
||||
|
||||
#----------------------------------------------------
|
||||
# commands
|
||||
#----------------------------------------------------
|
||||
class Command(object):
|
||||
name = None
|
||||
usage = None
|
||||
summary = ""
|
||||
|
||||
def __init__(self):
|
||||
self.parser = OptionParser(usage=self.usage,
|
||||
prog='%s %s' % (os.path.basename(sys.argv[0]), self.name))
|
||||
|
||||
def run(self, args):
|
||||
options, args = self.parser.parse_args(args)
|
||||
self.run_command(options, args[1:])
|
||||
|
||||
class HelpCommand(Command):
|
||||
name = "help"
|
||||
usage = "%prog [COMMAND]"
|
||||
summary = "Show available commands"
|
||||
|
||||
def run_command(self, options, args):
|
||||
if args:
|
||||
command = args[0]
|
||||
if command not in command_dict:
|
||||
parser.error("Unknown command: `%s`" % command)
|
||||
return
|
||||
command = command_dict[command]
|
||||
command.parser.print_help()
|
||||
return
|
||||
parser.print_help()
|
||||
print
|
||||
print "Commands available:"
|
||||
commands = [command_dict[key] for key in sorted(command_dict.keys())]
|
||||
for command in commands:
|
||||
print " %s: %s" % (command.name, command.summary)
|
||||
print
|
||||
print "Further Instructions:"
|
||||
print " http://github.com/utahta/pythonbrew"
|
||||
|
||||
class InitCommand(Command):
|
||||
name = "init"
|
||||
usage = "%prog"
|
||||
summary = "Run this once to setup the pythonbrew directory ready for installing pythons into"
|
||||
|
||||
def run_command(self, options, args):
|
||||
makedirs(PATH_PYTHONS)
|
||||
makedirs(PATH_BUILD)
|
||||
makedirs(PATH_DISTS)
|
||||
makedirs(PATH_ETC)
|
||||
|
||||
os.system("echo 'export PATH=%s/bin:%s/current/bin:${PATH}' > %s/bashrc" % (ROOT, PATH_PYTHONS, PATH_ETC))
|
||||
os.system("echo 'setenv PATH %s/bin:%s/current/bin:$PATH' > %s/cshrc" % (ROOT, PATH_PYTHONS, PATH_ETC))
|
||||
m = re.search("(t?csh)", os.environ.get("SHELL"))
|
||||
if m:
|
||||
shrc = "cshrc"
|
||||
yourshrc = m.group(1)+"rc"
|
||||
else:
|
||||
shrc = yourshrc = "bashrc"
|
||||
print """
|
||||
Pythonbrew environment initiated, required directories are created under
|
||||
|
||||
"""+ROOT+"""
|
||||
|
||||
Well-done! Congratulations! Please add the following line to the end
|
||||
of your ~/."""+yourshrc+"""
|
||||
|
||||
source """+PATH_ETC+"""/"""+shrc+"""
|
||||
|
||||
After that, exit this shell, start a new one, and install some fresh
|
||||
pythons:
|
||||
|
||||
pythonbrew install Python-2.6.6
|
||||
pythonbrew install Python-2.5.5
|
||||
|
||||
For further instructions, simply run:
|
||||
|
||||
pythonbrew
|
||||
|
||||
The default help messages will popup and tell you what to do!
|
||||
|
||||
Enjoy pythonbrew at $HOME!!
|
||||
INSTRUCTION"""
|
||||
|
||||
class InstallCommand(Command):
|
||||
name = "install"
|
||||
usage = "%prog [OPTIONS] PACKAGE_NAMES"
|
||||
summary = "Build and install the given version of python"
|
||||
|
||||
def __init__(self):
|
||||
super(InstallCommand, self).__init__()
|
||||
self.parser.add_option(
|
||||
"-f", "--force",
|
||||
dest="force",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Force installation of a Python."
|
||||
)
|
||||
self.parser.add_option(
|
||||
"-C", "--configure",
|
||||
dest="configure",
|
||||
default="",
|
||||
metavar="CONFIGURE_OPTIONS",
|
||||
help="Custom configure options."
|
||||
)
|
||||
self.parser.add_option(
|
||||
"-n", "--no-setuptools",
|
||||
dest="no_setuptools",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Skip installation of setuptools."
|
||||
)
|
||||
self._logfile = "%s/build.log" % ROOT
|
||||
|
||||
def run_command(self, options, args):
|
||||
if args:
|
||||
# Install Python
|
||||
self._install_python(args[0], options)
|
||||
else:
|
||||
# Install pythonbrew
|
||||
self._install_myself()
|
||||
|
||||
def _install_myself(self):
|
||||
executable = os.path.abspath(sys.argv[0])
|
||||
(retval, dist) = copy_myself(executable)
|
||||
if not retval:
|
||||
print "You are already running the installed latest version of pythonbrew."
|
||||
print "\n%s" % dist
|
||||
sys.exit()
|
||||
print """The pythonbrew is installed as:
|
||||
|
||||
"""+dist+"""
|
||||
|
||||
You may trash the downloaded """+executable+""" from now on.
|
||||
|
||||
Next, if this is the first time you've run pythonbrew installation, run:
|
||||
|
||||
"""+dist+""" init
|
||||
|
||||
And follow the instruction on screen."""
|
||||
|
||||
def _get_package(self, name):
|
||||
if not os.path.isfile(name) and not os.path.isdir(name):
|
||||
if is_url(name):
|
||||
basename = os.path.basename(name)
|
||||
download_url = name
|
||||
download_path = "%s/%s" % (PATH_DISTS, basename)
|
||||
else:
|
||||
m = re.search("^Python-(\d+\.\d+(\..*)?)$", name)
|
||||
if not m:
|
||||
print "Unknown package: `%s`" % name
|
||||
sys.exit(1)
|
||||
if os.path.isdir("%s/%s" % (PATH_PYTHONS, name)):
|
||||
print "You are already installed `%s`." % name
|
||||
sys.exit()
|
||||
dist_version = m.group(1)
|
||||
pkgs = PythonPackages()
|
||||
if not pkgs.has_version(dist_version):
|
||||
print "Package not found: `%s`" % name
|
||||
sys.exit(1)
|
||||
basename = "%s.tgz" % name
|
||||
download_url = PYTHONDLSITE % (dist_version, basename)
|
||||
download_path = "%s/%s" % (PATH_DISTS, basename)
|
||||
|
||||
if os.path.isfile(download_path):
|
||||
print "Use the previously fetched %s" % (download_path)
|
||||
else:
|
||||
try:
|
||||
dl = Downloader()
|
||||
dl.download(
|
||||
basename,
|
||||
download_url,
|
||||
download_path
|
||||
)
|
||||
except:
|
||||
unlink(download_path)
|
||||
print "\nInterrupt to abort. `%s`" % (download_url)
|
||||
sys.exit(1)
|
||||
# iffy
|
||||
if os.path.getsize(download_path) < 1000000:
|
||||
print "Failed to download. (maybe not stable version of python) `%s`" % (download_url)
|
||||
unlink(download_path)
|
||||
sys.exit(1)
|
||||
else:
|
||||
if is_archive_file(name):
|
||||
basename = os.path.basename(name)
|
||||
print "Copy the archive file %s to %s/%s" % (name, PATH_DISTS, basename)
|
||||
shutil.copy(name, "%s/%s" % (PATH_DISTS, basename))
|
||||
else:
|
||||
print "Invalid file. `%s`" % name
|
||||
sys.exit(1)
|
||||
return basename
|
||||
|
||||
def _get_uncompress_command(self, basename):
|
||||
distpath = "%s/%s" % (PATH_DISTS, basename)
|
||||
if os.path.isfile(distpath):
|
||||
ext = splitext(basename)[1]
|
||||
if ext == ".tar.gz" or ext == ".tgz":
|
||||
return "tar zxf %s" % (distpath)
|
||||
elif ext == ".tar.bz2":
|
||||
return "tar jxf %s" % (distpath)
|
||||
elif ext == ".tar":
|
||||
return "tar xf %s" % (distpath)
|
||||
elif ext == ".zip":
|
||||
return "unzip %s" % (distpath)
|
||||
elif os.path.isdir(distpath):
|
||||
return "mv %s %s/%s" % (distpath, PATH_BUILD, basename)
|
||||
else:
|
||||
print "File not found. `%s`" % (basename)
|
||||
return ""
|
||||
|
||||
def _install_python(self, dist, options):
|
||||
basename = self._get_package(dist)
|
||||
pkgname = splitext(basename)[0]
|
||||
|
||||
install_dir = "%s/%s" % (PATH_PYTHONS, pkgname)
|
||||
configure = "--prefix=%s %s" % (install_dir, options.configure)
|
||||
print "Installing %s into %s" % (pkgname, install_dir);
|
||||
print """This could take a while. You can run the following command on another shell to track the status:
|
||||
|
||||
tail -f %s
|
||||
""" % (self._logfile)
|
||||
try:
|
||||
s = Subprocess(log=self._logfile, shell=True, cwd=PATH_BUILD)
|
||||
s.check_call(self._get_uncompress_command(basename))
|
||||
|
||||
s.chdir("%s/%s" % (PATH_BUILD, pkgname))
|
||||
s.check_call("./configure %s" % (configure))
|
||||
if options.force:
|
||||
s.check_call("make")
|
||||
s.check_call("make install")
|
||||
else:
|
||||
s.check_call("make")
|
||||
s.check_call("make test")
|
||||
s.check_call("make install")
|
||||
except:
|
||||
print """Installing %(pkgname)s failed. See %(ROOT)s/build.log to see why.
|
||||
|
||||
pythonbrew install --force %(pkgname)s""" % {"pkgname":pkgname, "ROOT":ROOT}
|
||||
sys.exit(1)
|
||||
|
||||
# install setuptools
|
||||
self._install_setuptools(pkgname, options.no_setuptools)
|
||||
print """
|
||||
Installed %(pkgname)s successfully. Run the following command to switch to it.
|
||||
|
||||
pythonbrew switch %(pkgname)s""" % {"pkgname":pkgname}
|
||||
|
||||
def _install_setuptools(self, pkgname, no_setuptools):
|
||||
if no_setuptools:
|
||||
print "Skip installation setuptools."
|
||||
return
|
||||
if re.match("^Python-3.*", pkgname):
|
||||
is_python3 = True
|
||||
else:
|
||||
is_python3 = False
|
||||
download_url = DISTRIBUTE_SETUP_DLSITE
|
||||
basename = os.path.basename(download_url)
|
||||
|
||||
dl = Downloader()
|
||||
dl.download(basename, download_url, "%s/%s" % (PATH_DISTS, basename))
|
||||
|
||||
if is_python3:
|
||||
if os.path.isfile("%s/%s/bin/python3" % (PATH_PYTHONS, pkgname)):
|
||||
pyexec = "%s/%s/bin/python3" % (PATH_PYTHONS, pkgname)
|
||||
elif os.path.isfile("%s/%s/bin/python3.0" % (PATH_PYTHONS, pkgname)):
|
||||
pyexec = "%s/%s/bin/python3.0" % (PATH_PYTHONS, pkgname)
|
||||
else:
|
||||
print "Python3 binary not found. `%s/%s`" % (PATH_PYTHONS, pkgname)
|
||||
return
|
||||
else:
|
||||
pyexec = "%s/%s/bin/python" % (PATH_PYTHONS, pkgname)
|
||||
|
||||
try:
|
||||
s = Subprocess(log=self._logfile, shell=True, cwd=PATH_DISTS)
|
||||
s.check_call("%s %s" % (pyexec, basename))
|
||||
if os.path.isfile("%s/%s/bin/easy_install" % (PATH_PYTHONS, pkgname)) and not is_python3:
|
||||
s.check_call("%s/%s/bin/easy_install pip" % (PATH_PYTHONS, pkgname), cwd=None)
|
||||
except:
|
||||
print "Installing setuptools failed. See %s/build.log to see why." % (ROOT)
|
||||
sys.exit(1)
|
||||
|
||||
class InstalledCommand(Command):
|
||||
name = "installed"
|
||||
usage = "%prog"
|
||||
summary = "List the installed versions of python"
|
||||
|
||||
def run_command(self, options, args):
|
||||
if not os.path.islink("%s/current" % PATH_PYTHONS):
|
||||
cur = os.path.realpath("%s/bin/python" % ROOT)
|
||||
print "%s (*)" % cur
|
||||
elif os.path.islink("%s/current" % PATH_PYTHONS):
|
||||
cur = os.path.basename(os.path.realpath("%s/current" % PATH_PYTHONS))
|
||||
else:
|
||||
cur = ""
|
||||
for d in sorted(os.listdir("%s/" % PATH_PYTHONS)):
|
||||
if d == "current":
|
||||
continue
|
||||
if cur == d:
|
||||
print "%s (*)" % cur
|
||||
else:
|
||||
print "%s" % (d)
|
||||
|
||||
class SwitchCommand(Command):
|
||||
name = "switch"
|
||||
usage = "%prog PACKAGE"
|
||||
summary = "Switch to the given version"
|
||||
|
||||
def run_command(self, options, args):
|
||||
if args:
|
||||
dist = args[0]
|
||||
distdir = dist
|
||||
if os.path.isfile( dist ) and os.access( dist, os.X_OK ):
|
||||
if re.search( ".*python(\d(\.\d)?)?$", dist ):
|
||||
self._switch_file(dist)
|
||||
else:
|
||||
print "`%s` is not python binary." % dist
|
||||
return
|
||||
elif not os.path.isdir( "%s/%s" % (PATH_PYTHONS, dist) ):
|
||||
print "`%s` is not installed." % dist
|
||||
return
|
||||
self._switch_dir( distdir )
|
||||
|
||||
def _switch_file(self, dist):
|
||||
off()
|
||||
symlink(dist, "%s/python" % PATH_BIN)
|
||||
print "Switched to "+dist
|
||||
|
||||
def _switch_dir(self, dist):
|
||||
off()
|
||||
symlink(dist, "%s/current" % PATH_PYTHONS)
|
||||
for root, dirs, files in os.walk("%s/current/bin/" % PATH_PYTHONS):
|
||||
for f in files:
|
||||
symlink("%s%s" % (root, f), "%s/%s" % (PATH_BIN, f))
|
||||
break
|
||||
# I want better code
|
||||
if not os.path.isfile("%s/python" % PATH_BIN):
|
||||
if os.path.isfile("%s/python3" % PATH_BIN):
|
||||
symlink(os.path.realpath("%s/python3" % PATH_BIN), "%s/python" % PATH_BIN)
|
||||
elif os.path.isfile("%s/python3.0" % PATH_BIN):
|
||||
symlink(os.path.realpath("%s/python3.0" % PATH_BIN), "%s/python" % PATH_BIN)
|
||||
print "Switched to "+dist
|
||||
|
||||
class OffCommand(Command):
|
||||
name = "off"
|
||||
usage = "%prog"
|
||||
summary = "Disable pythonbrew"
|
||||
|
||||
def run_command(self, options, args):
|
||||
off()
|
||||
|
||||
class VersionCommand(Command):
|
||||
name = "version"
|
||||
usage = "%prog"
|
||||
summary = "Show version"
|
||||
|
||||
def run_command(self, options, args):
|
||||
print VERSION
|
||||
|
||||
class SearchCommand(Command):
|
||||
name = "search"
|
||||
usage = "%prog Python-<VERSION>"
|
||||
summary = "Search Python packages"
|
||||
|
||||
def run_command(self, options, args):
|
||||
pkgs = PythonPackages()
|
||||
if args:
|
||||
pattern = args[0]
|
||||
_re = re.compile(r"%s" % pattern)
|
||||
pkgnames = []
|
||||
for pkgname in pkgs.get_packages():
|
||||
if _re.match(pkgname):
|
||||
pkgnames.append(pkgname)
|
||||
if pkgnames:
|
||||
for pkgname in pkgnames:
|
||||
print pkgname
|
||||
else:
|
||||
print "Package not found. `%s`" % pattern
|
||||
else:
|
||||
for pkgname in pkgs.get_packages():
|
||||
print pkgname
|
||||
|
||||
class UninstallCommand(Command):
|
||||
name = "uninstall"
|
||||
usage = "%prog Python-<VERSION>"
|
||||
summary = "Uninstall the given version of python"
|
||||
|
||||
def run_command(self, options, args):
|
||||
if args:
|
||||
pkgname = args[0]
|
||||
pkgpath = "%s/%s" % (PATH_PYTHONS, pkgname)
|
||||
if not os.path.isdir(pkgpath):
|
||||
print "%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()
|
||||
rm_r(pkgpath)
|
||||
else:
|
||||
self.parser.print_help()
|
||||
|
||||
class CleanCommand(Command):
|
||||
name = "clean"
|
||||
usage = "%prog"
|
||||
summary = "Remove stale source folders and archives"
|
||||
|
||||
def run_command(self, options, args):
|
||||
self._clean(PATH_BUILD)
|
||||
self._clean(PATH_DISTS)
|
||||
|
||||
def _clean(self, root):
|
||||
for dir in os.listdir(root):
|
||||
rm_r("%s/%s" % (root, dir))
|
||||
|
||||
class UpdateCommand(Command):
|
||||
name = "update"
|
||||
usage = "%prog"
|
||||
summary = "Upgrades pythonbrew to the latest version"
|
||||
|
||||
def run_command(self, options, args):
|
||||
download_url = PYTHONBREW_DLSITE
|
||||
basename = os.path.basename(download_url)
|
||||
download_path = "%s/%s" % (PATH_DISTS, basename)
|
||||
|
||||
try:
|
||||
d = Downloader()
|
||||
d.download(basename, download_url, download_path)
|
||||
except:
|
||||
print "Failed to download. `%s`" % download_url
|
||||
sys.exit(1)
|
||||
|
||||
(retval, dist) = copy_myself(download_path)
|
||||
if not retval:
|
||||
print "You are already running the installed latest version of pythonbrew."
|
||||
print "\n%s" % dist
|
||||
sys.exit()
|
||||
print "The pythonbrew has been updated."
|
||||
|
||||
class Pythonbrew(object):
|
||||
def run(self):
|
||||
options, args = parser.parse_args(sys.argv[1:])
|
||||
if options.help and not args:
|
||||
args = ["help"]
|
||||
if not args:
|
||||
parser.error('You must give a command (use "pythonbrew help" to see a list of commands)')
|
||||
return
|
||||
add_command(HelpCommand())
|
||||
add_command(InitCommand())
|
||||
add_command(InstallCommand())
|
||||
add_command(InstalledCommand())
|
||||
add_command(SwitchCommand())
|
||||
add_command(OffCommand())
|
||||
add_command(VersionCommand())
|
||||
add_command(SearchCommand())
|
||||
add_command(UninstallCommand())
|
||||
add_command(CleanCommand())
|
||||
add_command(UpdateCommand())
|
||||
|
||||
command = args[0].lower()
|
||||
if command not in command_dict:
|
||||
parser.error("Unknown command: `%s`" % command)
|
||||
return
|
||||
command = command_dict[command]
|
||||
command.run(args)
|
||||
|
||||
def main():
|
||||
p = Pythonbrew()
|
||||
p.run()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,19 @@
|
||||
import sys
|
||||
from pythonbrew.basecommand import command_dict, load_all_commands
|
||||
from pythonbrew.baseparser import parser
|
||||
|
||||
def main():
|
||||
options, args = parser.parse_args(sys.argv[1:])
|
||||
if options.help and not args:
|
||||
args = ["help"]
|
||||
if not args:
|
||||
parser.error('You must give a command (use "pythonbrew help" to see a list of commands)')
|
||||
return
|
||||
|
||||
load_all_commands()
|
||||
command = args[0].lower()
|
||||
if command not in command_dict:
|
||||
parser.error("Unknown command: `%s`" % command)
|
||||
return
|
||||
command = command_dict[command]
|
||||
command.run(args)
|
||||
@@ -0,0 +1,38 @@
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
from optparse import OptionParser
|
||||
from pythonbrew import commands
|
||||
from pythonbrew.define import PATH_BIN_PYTHONBREW
|
||||
|
||||
command_dict = {}
|
||||
|
||||
class Command(object):
|
||||
name = None
|
||||
usage = None
|
||||
summary = ""
|
||||
|
||||
def __init__(self):
|
||||
self.parser = OptionParser(usage=self.usage,
|
||||
prog='%s %s' % (PATH_BIN_PYTHONBREW, self.name))
|
||||
command_dict[self.name] = self
|
||||
|
||||
def run(self, args):
|
||||
options, args = self.parser.parse_args(args)
|
||||
self.run_command(options, args[1:])
|
||||
|
||||
def load_command(name):
|
||||
full_name = 'pythonbrew.commands.%s' % name
|
||||
if full_name in sys.modules:
|
||||
return
|
||||
try:
|
||||
__import__(full_name)
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
def load_all_commands():
|
||||
for name in command_names():
|
||||
load_command(name)
|
||||
|
||||
def command_names():
|
||||
return [path[:-3] for path in os.listdir(commands.__path__[0]) if not re.match("(__init__\.py$|.*\.pyc$)", path)]
|
||||
@@ -0,0 +1,13 @@
|
||||
from optparse import OptionParser
|
||||
from pythonbrew.define import VERSION, PATH_BIN_PYTHONBREW
|
||||
|
||||
parser = OptionParser(usage="%prog COMMAND [OPTIONS]",
|
||||
prog=PATH_BIN_PYTHONBREW,
|
||||
version=VERSION,
|
||||
add_help_option=False)
|
||||
parser.add_option(
|
||||
'-h', '--help',
|
||||
dest='help',
|
||||
action='store_true',
|
||||
help='Show help')
|
||||
parser.disable_interspersed_args()
|
||||
@@ -0,0 +1,19 @@
|
||||
import os
|
||||
from pythonbrew.basecommand import Command
|
||||
from pythonbrew.define import PATH_BUILD, PATH_DISTS
|
||||
from pythonbrew.util import rm_r
|
||||
|
||||
class CleanCommand(Command):
|
||||
name = "clean"
|
||||
usage = "%prog"
|
||||
summary = "Remove stale source folders and archives"
|
||||
|
||||
def run_command(self, options, args):
|
||||
self._clean(PATH_BUILD)
|
||||
self._clean(PATH_DISTS)
|
||||
|
||||
def _clean(self, root):
|
||||
for dir in os.listdir(root):
|
||||
rm_r("%s/%s" % (root, dir))
|
||||
|
||||
CleanCommand()
|
||||
@@ -0,0 +1,27 @@
|
||||
from pythonbrew.basecommand import Command, command_dict
|
||||
from pythonbrew.baseparser import parser
|
||||
from pythonbrew.log import logger
|
||||
|
||||
class HelpCommand(Command):
|
||||
name = "help"
|
||||
usage = "%prog [COMMAND]"
|
||||
summary = "Show available commands"
|
||||
|
||||
def run_command(self, options, args):
|
||||
if args:
|
||||
command = args[0]
|
||||
if command not in command_dict:
|
||||
parser.error("Unknown command: `%s`" % command)
|
||||
return
|
||||
command = command_dict[command]
|
||||
command.parser.print_help()
|
||||
return
|
||||
parser.print_help()
|
||||
logger.info("\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(" http://github.com/utahta/pythonbrew")
|
||||
|
||||
HelpCommand()
|
||||
@@ -0,0 +1,184 @@
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import shutil
|
||||
from pythonbrew.basecommand import Command
|
||||
from pythonbrew.util import unlink, splitext, Subprocess, Package, makedirs,\
|
||||
rm_r
|
||||
from pythonbrew.define import ROOT, PATH_PYTHONS, PATH_DISTS, PATH_BUILD, PATH_LOG, DISTRIBUTE_SETUP_DLSITE
|
||||
from pythonbrew.log import logger
|
||||
from pythonbrew.downloader import get_python_package_url, Downloader
|
||||
|
||||
class InstallCommand(Command):
|
||||
name = "install"
|
||||
usage = "%prog [OPTIONS] VERSION"
|
||||
summary = "Build and install the given version of python"
|
||||
|
||||
def __init__(self):
|
||||
super(InstallCommand, self).__init__()
|
||||
self.parser.add_option(
|
||||
"-f", "--force",
|
||||
dest="force",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Force installation of a Python."
|
||||
)
|
||||
self.parser.add_option(
|
||||
"-C", "--configure",
|
||||
dest="configure",
|
||||
default="",
|
||||
metavar="CONFIGURE_OPTIONS",
|
||||
help="Custom configure options."
|
||||
)
|
||||
self.parser.add_option(
|
||||
"-n", "--no-setuptools",
|
||||
dest="no_setuptools",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Skip installation of setuptools."
|
||||
)
|
||||
self._logfile = "%s/build.log" % PATH_LOG
|
||||
|
||||
def run_command(self, options, args):
|
||||
if args:
|
||||
# Install Python
|
||||
self._install_python(args[0], options)
|
||||
else:
|
||||
logger.error("Package not found.")
|
||||
|
||||
def _install_python(self, dist, options):
|
||||
pkg = Package(dist)
|
||||
distname = self._download_package(pkg)
|
||||
pkgname = pkg.name
|
||||
version = pkg.version
|
||||
|
||||
install_dir = "%s/%s" % (PATH_PYTHONS, pkgname)
|
||||
configure = "--prefix=%s %s" % (install_dir, options.configure)
|
||||
logger.info("")
|
||||
logger.info("This could take a while. You can run the following command on another shell to track the status:")
|
||||
logger.info(" tail -f %s" % self._logfile)
|
||||
logger.info("")
|
||||
|
||||
try:
|
||||
s = Subprocess(log=self._logfile, shell=True, cwd=PATH_BUILD, print_cmd=False)
|
||||
|
||||
logger.info("Extracting %s" % distname)
|
||||
s.check_call(self._get_uncompress_command(distname))
|
||||
|
||||
logger.info("Installing %s into %s" % (pkgname, install_dir))
|
||||
s.chdir("%s/%s" % (PATH_BUILD, pkgname))
|
||||
s.check_call("./configure %s" % (configure))
|
||||
if options.force:
|
||||
s.check_call("make")
|
||||
else:
|
||||
s.check_call("make")
|
||||
s.check_call("make test")
|
||||
if version == "1.5.2" or version == "1.6.1":
|
||||
makedirs(install_dir)
|
||||
s.check_call("make install")
|
||||
except:
|
||||
rm_r(install_dir)
|
||||
logger.error("""Failed to install %(pkgname)s. See %(ROOT)s/build.log to see why.
|
||||
|
||||
pythonbrew install --force %(version)s""" % {"pkgname":pkgname, "ROOT":ROOT, "version":version})
|
||||
sys.exit(1)
|
||||
|
||||
# install setuptools
|
||||
self._install_setuptools(pkgname, options.no_setuptools)
|
||||
logger.info("""
|
||||
Installed %(pkgname)s successfully. Run the following command to switch to %(pkgname)s.
|
||||
|
||||
pythonbrew switch %(version)s""" % {"pkgname":pkgname, "version":version})
|
||||
|
||||
def _download_package(self, pkg):
|
||||
pkgname = pkg.name
|
||||
version = pkg.version
|
||||
|
||||
if os.path.isdir("%s/%s" % (PATH_PYTHONS, pkgname)):
|
||||
logger.error("You are already installed `%s`." % pkgname)
|
||||
sys.exit(1)
|
||||
|
||||
download_url = get_python_package_url(version)
|
||||
if not download_url:
|
||||
logger.error("Unknown package: `%s`" % pkgname)
|
||||
sys.exit(1)
|
||||
distname = os.path.basename(download_url)
|
||||
download_path = "%s/%s" % (PATH_DISTS, distname)
|
||||
|
||||
if os.path.isfile(download_path):
|
||||
logger.info("Use the previously fetched %s" % (download_path))
|
||||
else:
|
||||
try:
|
||||
dl = Downloader()
|
||||
dl.download(
|
||||
distname,
|
||||
download_url,
|
||||
download_path
|
||||
)
|
||||
except:
|
||||
unlink(download_path)
|
||||
logger.info("\nInterrupt to abort. `%s`" % (download_url))
|
||||
sys.exit(1)
|
||||
# iffy
|
||||
if os.path.getsize(download_path) < 1000000:
|
||||
logger.error("Failed to download. `%s`" % (download_url))
|
||||
unlink(download_path)
|
||||
sys.exit(1)
|
||||
return distname
|
||||
|
||||
def _get_uncompress_command(self, basename):
|
||||
distpath = "%s/%s" % (PATH_DISTS, basename)
|
||||
if os.path.isfile(distpath):
|
||||
ext = splitext(basename)[1]
|
||||
if ext == ".tar.gz" or ext == ".tgz":
|
||||
return "tar zxf %s" % (distpath)
|
||||
elif ext == ".tar.bz2":
|
||||
return "tar jxf %s" % (distpath)
|
||||
elif ext == ".tar":
|
||||
return "tar xf %s" % (distpath)
|
||||
elif ext == ".zip":
|
||||
return "unzip %s" % (distpath)
|
||||
elif os.path.isdir(distpath):
|
||||
return "mv %s %s/%s" % (distpath, PATH_BUILD, basename)
|
||||
else:
|
||||
logger.error("File not found. `%s`" % (basename))
|
||||
return ""
|
||||
|
||||
def _install_setuptools(self, pkgname, no_setuptools):
|
||||
if no_setuptools:
|
||||
logger.info("Skip installation setuptools.")
|
||||
return
|
||||
if re.match("^Python-3.*", pkgname):
|
||||
is_python3 = True
|
||||
else:
|
||||
is_python3 = False
|
||||
download_url = DISTRIBUTE_SETUP_DLSITE
|
||||
basename = os.path.basename(download_url)
|
||||
|
||||
dl = Downloader()
|
||||
dl.download(basename, download_url, "%s/%s" % (PATH_DISTS, basename))
|
||||
|
||||
install_dir = "%s/%s" % (PATH_PYTHONS, pkgname)
|
||||
if is_python3:
|
||||
if os.path.isfile("%s/bin/python3" % (install_dir)):
|
||||
pyexec = "%s/bin/python3" % (install_dir)
|
||||
elif os.path.isfile("%s/bin/python3.0" % (install_dir)):
|
||||
pyexec = "%s/bin/python3.0" % (install_dir)
|
||||
else:
|
||||
logger.error("Python3 binary not found. `%s`" % (install_dir))
|
||||
return
|
||||
else:
|
||||
pyexec = "%s/bin/python" % (install_dir)
|
||||
|
||||
try:
|
||||
s = Subprocess(log=self._logfile, shell=True, cwd=PATH_DISTS, print_cmd=False)
|
||||
logger.info("Installing distribute into %s" % install_dir)
|
||||
s.check_call("%s %s" % (pyexec, basename))
|
||||
if os.path.isfile("%s/bin/easy_install" % (install_dir)) and not is_python3:
|
||||
logger.info("Installing pip into %s" % install_dir)
|
||||
s.check_call("%s/bin/easy_install pip" % (install_dir), cwd=None)
|
||||
except:
|
||||
logger.error("Failed to install setuptools. See %s/build.log to see why." % (ROOT))
|
||||
logger.info("Skip install setuptools.")
|
||||
|
||||
InstallCommand()
|
||||
@@ -0,0 +1,26 @@
|
||||
import os
|
||||
from pythonbrew.basecommand import Command
|
||||
from pythonbrew.define import PATH_PYTHONS
|
||||
from pythonbrew.log import logger
|
||||
import sys
|
||||
|
||||
class InstalledCommand(Command):
|
||||
name = "installed"
|
||||
usage = "%prog"
|
||||
summary = "List the installed versions of python"
|
||||
|
||||
def run_command(self, options, args):
|
||||
cur = ""
|
||||
if not os.path.islink("%s/current" % PATH_PYTHONS):
|
||||
logger.info("%s (*)" % sys.executable)
|
||||
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)
|
||||
else:
|
||||
logger.info("%s" % (d))
|
||||
|
||||
InstalledCommand()
|
||||
@@ -0,0 +1,34 @@
|
||||
import re
|
||||
from pythonbrew.basecommand import Command
|
||||
from pythonbrew.define import PYTHON_PACKAGE_URL
|
||||
from pythonbrew.util import Package
|
||||
from pythonbrew.log import logger
|
||||
|
||||
class ListCommand(Command):
|
||||
name = "list"
|
||||
usage = "%prog [VERSION]"
|
||||
summary = "List the available install version of python"
|
||||
|
||||
def run_command(self, options, args):
|
||||
if args:
|
||||
pkg = Package(args[0])
|
||||
_re = re.compile(r"%s" % pkg.name)
|
||||
pkgs = []
|
||||
for pkgname in self._get_packages_name():
|
||||
if _re.match(pkgname):
|
||||
pkgs.append(pkgname)
|
||||
if pkgs:
|
||||
logger.info("Pythons:")
|
||||
for pkgname in pkgs:
|
||||
logger.info(" %s" % pkgname)
|
||||
else:
|
||||
print "Package not found. `%s`" % pkg.name
|
||||
else:
|
||||
logger.info("Pythons:")
|
||||
for pkgname in self._get_packages_name():
|
||||
logger.info(" %s" % pkgname)
|
||||
|
||||
def _get_packages_name(self):
|
||||
return ["Python-%s" % version for version in sorted(PYTHON_PACKAGE_URL.keys())]
|
||||
|
||||
ListCommand()
|
||||
@@ -0,0 +1,12 @@
|
||||
from pythonbrew.basecommand import Command
|
||||
from pythonbrew.util import off
|
||||
|
||||
class OffCommand(Command):
|
||||
name = "off"
|
||||
usage = "%prog"
|
||||
summary = "Disable pythonbrew"
|
||||
|
||||
def run_command(self, options, args):
|
||||
off()
|
||||
|
||||
OffCommand()
|
||||
@@ -0,0 +1,41 @@
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
from pythonbrew.basecommand import Command
|
||||
from pythonbrew.define import PATH_PYTHONS, PATH_BIN
|
||||
from pythonbrew.util import off, symlink, Package
|
||||
from pythonbrew.log import logger
|
||||
|
||||
class SwitchCommand(Command):
|
||||
name = "switch"
|
||||
usage = "%prog VERSION"
|
||||
summary = "Switch to the given version"
|
||||
|
||||
def run_command(self, options, args):
|
||||
if not args:
|
||||
logger.error("Unrecognized command line argument: argument not found.")
|
||||
sys.exit(1)
|
||||
pkg = Package(args[0])
|
||||
pkgname = pkg.name
|
||||
pkgdir = "%s/%s" % (PATH_PYTHONS, pkgname)
|
||||
if not os.path.isdir(pkgdir):
|
||||
logger.error("`%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)
|
||||
for root, dirs, files in os.walk("%s/current/bin/" % PATH_PYTHONS):
|
||||
for f in files:
|
||||
symlink("%s%s" % (root, f), "%s/%s" % (PATH_BIN, f))
|
||||
break
|
||||
# I want better code
|
||||
if not os.path.isfile("%s/python" % PATH_BIN):
|
||||
if os.path.isfile("%s/python3" % PATH_BIN):
|
||||
symlink(os.path.realpath("%s/python3" % PATH_BIN), "%s/python" % PATH_BIN)
|
||||
elif os.path.isfile("%s/python3.0" % PATH_BIN):
|
||||
symlink(os.path.realpath("%s/python3.0" % PATH_BIN), "%s/python" % PATH_BIN)
|
||||
|
||||
SwitchCommand()
|
||||
@@ -0,0 +1,29 @@
|
||||
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.log import logger
|
||||
|
||||
class UninstallCommand(Command):
|
||||
name = "uninstall"
|
||||
usage = "%prog VERSION"
|
||||
summary = "Uninstall the given version of python"
|
||||
|
||||
def run_command(self, options, args):
|
||||
if args:
|
||||
pkg = Package(args[0])
|
||||
pkgname = pkg.name
|
||||
pkgpath = "%s/%s" % (PATH_PYTHONS, pkgname)
|
||||
if not os.path.isdir(pkgpath):
|
||||
logger.error("`%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()
|
||||
rm_r(pkgpath)
|
||||
else:
|
||||
self.parser.print_help()
|
||||
|
||||
UninstallCommand()
|
||||
@@ -0,0 +1,64 @@
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
from pythonbrew.basecommand import Command
|
||||
from pythonbrew.define import PATH_DISTS, VERSION, PYTHONBREW_DIRNAME, ROOT
|
||||
from pythonbrew.log import logger
|
||||
from pythonbrew.downloader import Downloader, get_pythonbrew_update_url
|
||||
from pythonbrew.util import Subprocess, rm_r
|
||||
|
||||
class UpdateCommand(Command):
|
||||
name = "update"
|
||||
usage = "%prog"
|
||||
summary = "Upgrades pythonbrew to the latest version"
|
||||
|
||||
def run_command(self, options, args):
|
||||
version = "head"
|
||||
if args:
|
||||
version = args[0]
|
||||
|
||||
# check for latest version
|
||||
if version == VERSION:
|
||||
logger.info("You are already running the installed latest version of pythonbrew.")
|
||||
sys.exit()
|
||||
|
||||
download_url = get_pythonbrew_update_url(version)
|
||||
if not download_url:
|
||||
logger.error("`%s` of pythonbrew not found." % version)
|
||||
sys.exit(1)
|
||||
|
||||
distname = "pythonbrew.tgz"
|
||||
download_path = "%s/%s" % (PATH_DISTS, distname)
|
||||
try:
|
||||
d = Downloader()
|
||||
d.download(distname, download_url, download_path)
|
||||
except:
|
||||
logger.error("Failed to download. `%s`" % download_url)
|
||||
sys.exit(1)
|
||||
|
||||
_re = re.compile("^%s.*" % PYTHONBREW_DIRNAME)
|
||||
for name in os.listdir(PATH_DISTS):
|
||||
if _re.match(name):
|
||||
rm_r("%s/%s" % (PATH_DISTS, name))
|
||||
try:
|
||||
s = Subprocess(shell=True, cwd=PATH_DISTS, print_cmd=False)
|
||||
logger.info("Extracting %s" % download_path)
|
||||
s.check_call("tar zxf %s" % download_path)
|
||||
except:
|
||||
logger.error("Failed to update pythonbrew.")
|
||||
sys.exit(1)
|
||||
|
||||
for name in os.listdir(PATH_DISTS):
|
||||
if _re.match(name):
|
||||
try:
|
||||
installer_path = "%s/%s" % (PATH_DISTS, name)
|
||||
s = Subprocess(shell=True, cwd=PATH_DISTS, print_cmd=False)
|
||||
logger.info("Installing %s into %s" % (installer_path, ROOT))
|
||||
s.check_call("%s %s/pythonbrew_install.py" % (sys.executable, installer_path))
|
||||
except:
|
||||
logger.error("Failed to update pythonbrew.")
|
||||
sys.exit(1)
|
||||
break
|
||||
logger.info("The pythonbrew has been updated.")
|
||||
|
||||
UpdateCommand()
|
||||
@@ -0,0 +1,13 @@
|
||||
from pythonbrew.basecommand import Command
|
||||
from pythonbrew.define import VERSION
|
||||
from pythonbrew.log import logger
|
||||
|
||||
class VersionCommand(Command):
|
||||
name = "version"
|
||||
usage = "%prog"
|
||||
summary = "Show version"
|
||||
|
||||
def run_command(self, options, args):
|
||||
logger.info(VERSION)
|
||||
|
||||
VersionCommand()
|
||||
@@ -0,0 +1,56 @@
|
||||
import os
|
||||
|
||||
VERSION = "0.5"
|
||||
|
||||
if os.environ.has_key("PYTHONBREW_ROOT"):
|
||||
ROOT = os.environ["PYTHONBREW_ROOT"]
|
||||
else:
|
||||
ROOT = "%s/.pythonbrew" % os.environ["HOME"]
|
||||
|
||||
INSTALLER_ROOT = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
PATH_PYTHONS = "%s/pythons" % ROOT
|
||||
PATH_BUILD = "%s/build" % ROOT
|
||||
PATH_DISTS = "%s/dists" % ROOT
|
||||
PATH_ETC = "%s/etc" % ROOT
|
||||
PATH_BIN = "%s/bin" % ROOT
|
||||
PATH_LOG = "%s/log" % ROOT
|
||||
PATH_SCRIPTS = "%s/scripts" % ROOT
|
||||
PATH_SCRIPTS_PYTHONBREW = "%s/pythonbrew" % PATH_SCRIPTS
|
||||
PATH_SCRIPTS_PYTHONBREW_COMMANDS = "%s/commands" % PATH_SCRIPTS_PYTHONBREW
|
||||
|
||||
# file path
|
||||
PATH_BIN_PYTHONBREW = "%s/pythonbrew" % PATH_BIN
|
||||
PATH_BIN_PYBREW = "%s/pybrew" % PATH_BIN # pybrew is symlink as pythonbrew
|
||||
|
||||
# download setuptools url
|
||||
DISTRIBUTE_SETUP_DLSITE = "http://python-distribute.org/distribute_setup.py"
|
||||
|
||||
# download pythonbrew url
|
||||
PYTHONBREW_UPDATE_URL = {
|
||||
"head": "http://github.com/utahta/pythonbrew/tarball/master"
|
||||
}
|
||||
PYTHONBREW_DIRNAME = "utahta-pythonbrew"
|
||||
|
||||
# download Python package url
|
||||
PYTHON_PACKAGE_URL = {}
|
||||
PYTHON_PACKAGE_URL["1.5.2"] = "http://www.python.org/ftp/python/src/py152.tgz"
|
||||
PYTHON_PACKAGE_URL["1.6.1"] = "http://www.python.org/download/releases/1.6.1/Python-1.6.1.tar.gz"
|
||||
_PYTHON_PACKAGE_VERSIONS = [
|
||||
"2.0", "2.0.1",
|
||||
"2.1", "2.1.1", "2.1.2", "2.1.3",
|
||||
"2.2", "2.2.1", "2.2.2", "2.2.3",
|
||||
"2.3", "2.3.1", "2.3.2", "2.3.4", "2.3.5", "2.3.6", "2.3.7",
|
||||
"2.4", "2.4.1", "2.4.2", "2.4.3", "2.4.4", "2.4.5", "2.4.6",
|
||||
"2.5", "2.5.1", "2.5.2", "2.5.3", "2.5.4", "2.5.5",
|
||||
"2.6", "2.6.1", "2.6.2", "2.6.3", "2.6.4", "2.6.5", "2.6.6",
|
||||
"2.7",
|
||||
"3.0", "3.0.1",
|
||||
"3.1", "3.1.1", "3.1.2",
|
||||
]
|
||||
for version in _PYTHON_PACKAGE_VERSIONS:
|
||||
PYTHON_PACKAGE_URL[version] = "http://www.python.org/ftp/python/%s/Python-%s.tgz" % (version, version)
|
||||
del _PYTHON_PACKAGE_VERSIONS
|
||||
PYTHON_PACKAGE_URL["3.2a1"] = "http://www.python.org/ftp/python/3.2/Python-3.2a1.tgz"
|
||||
PYTHON_PACKAGE_URL["3.2a2"] = "http://www.python.org/ftp/python/3.2/Python-3.2a2.tgz"
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import sys
|
||||
import urllib
|
||||
from pythonbrew.util import size_format
|
||||
from pythonbrew.define import PYTHON_PACKAGE_URL, PYTHONBREW_UPDATE_URL
|
||||
|
||||
class Downloader(object):
|
||||
def __init__(self):
|
||||
self._msg = ""
|
||||
self._last_msg = ""
|
||||
self._bytes = 0.0
|
||||
|
||||
def download(self, msg, url, path):
|
||||
self._msg = msg
|
||||
self._bytes = 0
|
||||
urllib.urlretrieve(url, path, self._download_progress)
|
||||
print " downloaded."
|
||||
|
||||
def _download_progress(self, block, blockbytes, maxbytes):
|
||||
self._bytes += float(blockbytes)
|
||||
if self._bytes >= maxbytes:
|
||||
self._bytes = maxbytes
|
||||
percent = (self._bytes / maxbytes) * 100
|
||||
max_size = size_format(maxbytes)
|
||||
now_size = size_format(self._bytes)
|
||||
now_msg = "\rDownloading %s (%s): %3i%% %s" % (self._msg, max_size, percent, now_size)
|
||||
padding = " " * (len(self._last_msg) - len(now_msg))
|
||||
sys.stdout.write("%s%s" % (now_msg, padding))
|
||||
sys.stdout.flush()
|
||||
self._last_msg = now_msg
|
||||
|
||||
def get_pythonbrew_update_url(version):
|
||||
if PYTHONBREW_UPDATE_URL.has_key(version):
|
||||
return PYTHONBREW_UPDATE_URL[version]
|
||||
return None
|
||||
|
||||
def get_python_package_url(version):
|
||||
if PYTHON_PACKAGE_URL.has_key(version):
|
||||
return PYTHON_PACKAGE_URL[version]
|
||||
return None
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
class BuildingException(Exception):
|
||||
"""General exception during building"""
|
||||
@@ -0,0 +1,46 @@
|
||||
import os
|
||||
import sys
|
||||
import glob
|
||||
import shutil
|
||||
from pythonbrew.util import makedirs, symlink
|
||||
from pythonbrew.define import PATH_BUILD, PATH_BIN, PATH_DISTS, PATH_PYTHONS,\
|
||||
PATH_ETC, PATH_SCRIPTS, PATH_SCRIPTS_PYTHONBREW,\
|
||||
PATH_SCRIPTS_PYTHONBREW_COMMANDS, INSTALLER_ROOT, PATH_BIN_PYTHONBREW,\
|
||||
PATH_BIN_PYBREW, ROOT, PATH_LOG
|
||||
|
||||
def install_pythonbrew():
|
||||
makedirs(PATH_PYTHONS)
|
||||
makedirs(PATH_BUILD)
|
||||
makedirs(PATH_DISTS)
|
||||
makedirs(PATH_ETC)
|
||||
makedirs(PATH_BIN)
|
||||
makedirs(PATH_LOG)
|
||||
makedirs(PATH_SCRIPTS)
|
||||
makedirs(PATH_SCRIPTS_PYTHONBREW)
|
||||
makedirs(PATH_SCRIPTS_PYTHONBREW_COMMANDS)
|
||||
|
||||
for path in glob.glob("%s/*.py" % INSTALLER_ROOT):
|
||||
shutil.copy(path, PATH_SCRIPTS_PYTHONBREW)
|
||||
|
||||
for path in glob.glob("%s/commands/*.py" % INSTALLER_ROOT):
|
||||
shutil.copy(path, PATH_SCRIPTS_PYTHONBREW_COMMANDS)
|
||||
|
||||
fp = open("%s/pythonbrew.py" % PATH_SCRIPTS, "w")
|
||||
fp.write("""import pythonbrew
|
||||
if __name__ == "__main__":
|
||||
pythonbrew.main()
|
||||
""")
|
||||
fp.close()
|
||||
|
||||
fp = open(PATH_BIN_PYTHONBREW, "w")
|
||||
fp.write("""#!/usr/bin/env bash
|
||||
%s %s/pythonbrew.py $@
|
||||
""" % (sys.executable, PATH_SCRIPTS))
|
||||
fp.close()
|
||||
os.chmod(PATH_BIN_PYTHONBREW, 0755)
|
||||
symlink(PATH_BIN_PYTHONBREW, PATH_BIN_PYBREW) # pyb as pythonbrew
|
||||
|
||||
os.system("echo 'export PATH=%s/bin:%s/current/bin:${PATH}' > %s/bashrc" % (ROOT, PATH_PYTHONS, PATH_ETC))
|
||||
os.system("echo 'setenv PATH %s/bin:%s/current/bin:$PATH' > %s/cshrc" % (ROOT, PATH_PYTHONS, PATH_ETC))
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import sys
|
||||
import logging
|
||||
|
||||
class Logger(object):
|
||||
|
||||
DEBUG = logging.DEBUG
|
||||
INFO = logging.INFO
|
||||
ERROR = logging.ERROR
|
||||
|
||||
def __init__(self):
|
||||
self._consumers = []
|
||||
consumer = logging.getLogger('info')
|
||||
consumer.setLevel(Logger.INFO)
|
||||
hdlr = logging.StreamHandler(sys.stdout)
|
||||
hdlr.setFormatter(logging.Formatter("%(message)s"))
|
||||
consumer.addHandler(hdlr)
|
||||
self.add_consumer(Logger.INFO, consumer)
|
||||
|
||||
consumer = logging.getLogger('error')
|
||||
consumer.setLevel(Logger.ERROR)
|
||||
hdlr = logging.StreamHandler(sys.stderr)
|
||||
hdlr.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))
|
||||
consumer.addHandler(hdlr)
|
||||
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, *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))
|
||||
|
||||
logger = Logger()
|
||||
@@ -0,0 +1,111 @@
|
||||
import os
|
||||
import sys
|
||||
import errno
|
||||
import shutil
|
||||
import urllib
|
||||
import subprocess
|
||||
import re
|
||||
from pythonbrew.define import PATH_BIN, PATH_PYTHONS
|
||||
from pythonbrew.exceptions import BuildingException
|
||||
from pythonbrew.log import logger
|
||||
|
||||
def size_format(b):
|
||||
kb = 1000
|
||||
mb = kb*kb
|
||||
b = float(b)
|
||||
if b >= mb:
|
||||
return "%.1fMb" % (b/mb)
|
||||
if b >= kb:
|
||||
return "%.1fKb" % (b/kb)
|
||||
return "%.0fbytes" % (b)
|
||||
|
||||
def is_url(name):
|
||||
if ':' not in name:
|
||||
return False
|
||||
scheme = name.split(':', 1)[0].lower()
|
||||
return scheme in ['http', 'https', 'file', 'ftp']
|
||||
|
||||
def splitext(name):
|
||||
base, ext = os.path.splitext(name)
|
||||
if base.lower().endswith('.tar'):
|
||||
ext = base[-4:] + ext
|
||||
base = base[:-4]
|
||||
return base, ext
|
||||
|
||||
def is_archive_file(name):
|
||||
ext = splitext(name)[1].lower()
|
||||
archives = ('.zip', '.tar.gz', '.tar.bz2', '.tgz', '.tar')
|
||||
if ext in archives:
|
||||
return True
|
||||
return False
|
||||
|
||||
def makedirs(path):
|
||||
try:
|
||||
os.makedirs(path)
|
||||
except OSError, (e, es):
|
||||
if errno.EEXIST != e:
|
||||
raise
|
||||
|
||||
def symlink(src, dst):
|
||||
try:
|
||||
os.symlink(src, dst)
|
||||
except:
|
||||
pass
|
||||
|
||||
def unlink(path):
|
||||
try:
|
||||
os.unlink(path)
|
||||
except OSError, (e, es):
|
||||
if errno.ENOENT != e:
|
||||
raise
|
||||
|
||||
def rm_r(path):
|
||||
"""like rm -r command."""
|
||||
if os.path.isdir(path):
|
||||
shutil.rmtree(path)
|
||||
else:
|
||||
unlink(path)
|
||||
|
||||
def off():
|
||||
for root, dirs, files in os.walk(PATH_BIN):
|
||||
for f in files:
|
||||
if f == "pythonbrew" or f == "pybrew":
|
||||
continue
|
||||
unlink("%s/%s" % (root, f))
|
||||
unlink("%s/current" % PATH_PYTHONS)
|
||||
|
||||
class Subprocess(object):
|
||||
def __init__(self, log=None, shell=False, cwd=None, print_cmd=True):
|
||||
self._log = log
|
||||
self._shell = shell
|
||||
self._cwd = cwd
|
||||
self._print_cmd = print_cmd
|
||||
|
||||
def chdir(self, cwd):
|
||||
self._cwd = cwd
|
||||
|
||||
def check_call(self, cmd, shell=None, cwd=None):
|
||||
if shell:
|
||||
self._shell = shell
|
||||
if cwd:
|
||||
self._cwd = cwd
|
||||
if self._print_cmd:
|
||||
logger.info(cmd)
|
||||
if self._log:
|
||||
cmd = "(%s) >> '%s' 2>&1" % (cmd, self._log)
|
||||
retcode = subprocess.call(cmd, shell=self._shell, cwd=self._cwd)
|
||||
if retcode != 0:
|
||||
raise BuildingException()
|
||||
|
||||
class Package(object):
|
||||
def __init__(self, name):
|
||||
self.name = None
|
||||
self.version = None
|
||||
m = re.search("^Python-(.*)$", name)
|
||||
if m:
|
||||
self.name = name
|
||||
self.version = m.group(1)
|
||||
else:
|
||||
self.name = "Python-%s" % name
|
||||
self.version = name
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
from pythonbrew.installer import install_pythonbrew
|
||||
if __name__ == "__main__":
|
||||
install_pythonbrew()
|
||||
Reference in New Issue
Block a user