mirror of
https://github.com/kennethreitz-archive/python-build.git
synced 2026-06-05 23:30:18 +00:00
185 lines
6.9 KiB
Python
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()
|