Files
python-build/pythonbrew/commands/install.py
T
2010-11-13 03:25:56 +09:00

185 lines
6.9 KiB
Python

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()