diff --git a/pythonbrew-install b/pythonbrew-install index c931952..d7f82f9 100755 --- a/pythonbrew-install +++ b/pythonbrew-install @@ -1,6 +1,7 @@ #!/usr/bin/env bash PYTHON=`command -v python` +CURL=`command -v curl` usage() { @@ -31,9 +32,12 @@ parse_arguments() parse_arguments $@ if [[ ! -x $PYTHON ]] ; then - echo "I think $PYTHON is not Python interpreter." + echo "Python (2.4, 2.5 or 2.6) is required." exit fi +if [[ ! -x $CURL ]] ; then + echo "curl is required." +fi PYTHON_VERSION=`$PYTHON -V 2>&1` PYTHON_VERSION=${PYTHON_VERSION/"Python "/""} @@ -61,7 +65,7 @@ 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 +builtin cd $PATH_DISTS ; curl -sL $DOWNLOAD_URL -o "$TEMP_TARBALL" echo "Extracting $PATH_DISTS/$TEMP_TARBALL" builtin cd $PATH_DISTS ; tar zxf $TEMP_TARBALL @@ -74,51 +78,3 @@ 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!! -" diff --git a/pythonbrew/commands/uninstall.py b/pythonbrew/commands/uninstall.py index 1c5e12f..35bcc74 100644 --- a/pythonbrew/commands/uninstall.py +++ b/pythonbrew/commands/uninstall.py @@ -16,7 +16,7 @@ class UninstallCommand(Command): pkgname = pkg.name pkgpath = "%s/%s" % (PATH_PYTHONS, pkgname) if not os.path.isdir(pkgpath): - logger.error("`%s` is not installed." % pkgname) + 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) diff --git a/pythonbrew/commands/update.py b/pythonbrew/commands/update.py index 1d9ff40..6b9930d 100644 --- a/pythonbrew/commands/update.py +++ b/pythonbrew/commands/update.py @@ -1,11 +1,13 @@ import os import sys -import re from pythonbrew.basecommand import Command -from pythonbrew.define import PATH_DISTS, VERSION, PYTHONBREW_DIRNAME, ROOT +from pythonbrew.define import PATH_DISTS, VERSION, ROOT,\ + PATH_BUILD from pythonbrew.log import logger -from pythonbrew.downloader import Downloader, get_pythonbrew_update_url -from pythonbrew.util import Subprocess, rm_r +from pythonbrew.downloader import Downloader, get_pythonbrew_update_url,\ + get_response_from_url +from pythonbrew.util import rm_r, is_html, unpack_downloadfile +from pythonbrew.installer import PythonbrewInstaller class UpdateCommand(Command): name = "update" @@ -26,39 +28,34 @@ class UpdateCommand(Command): if not download_url: logger.error("`%s` of pythonbrew not found." % version) sys.exit(1) + resp = get_response_from_url(download_url) + content_type = resp.info()['content-type'] + if is_html(content_type): + logger.error("Invalid content-type: `%s`" % content_type) + sys.exit(1) distname = "pythonbrew.tgz" - download_path = "%s/%s" % (PATH_DISTS, distname) + download_file = os.path.join(PATH_DISTS, distname) try: d = Downloader() - d.download(distname, download_url, download_path) + d.download(distname, download_url, download_file) 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.") + + extract_dir = os.path.join(PATH_BUILD, "pythonbrew") + rm_r(extract_dir) + if not unpack_downloadfile(content_type, download_file, extract_dir): 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 + try: + installer_path = "%s/pythonbrew" % (extract_dir) + logger.info("Installing %s into %s" % (extract_dir, ROOT)) + PythonbrewInstaller().install(installer_path) + except: + logger.error("Failed to update pythonbrew.") + raise + sys.exit(1) logger.info("The pythonbrew has been updated.") UpdateCommand() diff --git a/pythonbrew/define.py b/pythonbrew/define.py index d7e4855..da20905 100644 --- a/pythonbrew/define.py +++ b/pythonbrew/define.py @@ -36,7 +36,6 @@ PYTHONBREW_UPDATE_URL = { "0.5": "https://github.com/utahta/pythonbrew/tarball/0.5", "0.6": "https://github.com/utahta/pythonbrew/tarball/0.6", } -PYTHONBREW_DIRNAME = "utahta-pythonbrew" # download Python package url PYTHON_PACKAGE_URL = {} diff --git a/pythonbrew/installer.py b/pythonbrew/installer.py index 9d73bab..fdd924a 100644 --- a/pythonbrew/installer.py +++ b/pythonbrew/installer.py @@ -4,8 +4,9 @@ import glob import shutil import re from pythonbrew.util import makedirs, symlink, Package, is_url, splitext, Link,\ - unlink, is_gzip, is_html, untar_file, Subprocess, rm_r,\ - is_macosx_snowleopard, is_python25, is_python24, is_python26 + unlink, is_html, Subprocess, rm_r,\ + is_macosx_snowleopard, is_python25, is_python24, is_python26,\ + unpack_downloadfile 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,\ @@ -16,42 +17,79 @@ from pythonbrew.downloader import get_python_package_url, Downloader,\ from pythonbrew.log import logger 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(os.path.join(INSTALLER_ROOT,"*.py")): - shutil.copy(path, PATH_SCRIPTS_PYTHONBREW) - - for path in glob.glob(os.path.join(INSTALLER_ROOT,"commands","*.py")): - shutil.copy(path, PATH_SCRIPTS_PYTHONBREW_COMMANDS) + PythonbrewInstaller().install(INSTALLER_ROOT) - rm_r(PATH_PATCHES) - shutil.copytree(os.path.join(INSTALLER_ROOT,"patches"), PATH_PATCHES) + m = re.search("(t?csh)", os.environ.get("SHELL")) + if m: + shrc = "cshrc" + yourshrc = m.group(1)+"rc" + else: + shrc = yourshrc = "bashrc" - fp = open("%s/pythonbrew_main.py" % PATH_SCRIPTS, "w") - fp.write("""import pythonbrew + logger.info(""" +Well-done! Congratulations! + +The pythonbrew is installed as: + + %(ROOT)s + +Please add the following line to the end of your ~/.%(yourshrc)s + + source %(PATH_ETC)s/%(shrc)s + +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)s!! +""" % {'ROOT':ROOT, 'yourshrc':yourshrc, 'shrc':shrc, 'PATH_ETC':PATH_ETC}) + +class PythonbrewInstaller(object): + def install(self, installer_root): + 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(os.path.join(installer_root,"*.py")): + shutil.copy(path, PATH_SCRIPTS_PYTHONBREW) + + for path in glob.glob(os.path.join(installer_root,"commands","*.py")): + shutil.copy(path, PATH_SCRIPTS_PYTHONBREW_COMMANDS) + + rm_r(PATH_PATCHES) + shutil.copytree(os.path.join(installer_root,"patches"), PATH_PATCHES) + + fp = open("%s/pythonbrew_main.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 + fp.close() + + fp = open(PATH_BIN_PYTHONBREW, "w") + fp.write("""#!/usr/bin/env bash %s %s/pythonbrew_main.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)) + fp.close() + os.chmod(PATH_BIN_PYTHONBREW, 0755) + symlink(PATH_BIN_PYTHONBREW, PATH_BIN_PYBREW) # pybrew is symbolic 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)) class PythonInstaller(object): def __init__(self, arg, options): @@ -132,16 +170,13 @@ class PythonInstaller(object): sys.exit(1) def unpack(self): - logger.info("Extracting %s" % os.path.basename(self.download_file)) - if is_gzip(self.content_type, self.download_file): - untar_file(self.download_file, self.build_dir) - else: - logger.error("Cannot determine archive format of %s" % self.download_file) + if not unpack_downloadfile(self.content_type, self.download_file, self.build_dir): + sys.exit(1) def patch(self): version = self.pkg.version try: - s = Subprocess(log=self.logfile, shell=True, cwd=self.build_dir, print_cmd=False) + s = Subprocess(log=self.logfile, cwd=self.build_dir) patches = [] if is_macosx_snowleopard(): if is_python24(version): @@ -179,11 +214,11 @@ class PythonInstaller(object): elif is_python26(version): configure_option = '--with-universal-archs="intel" MACOSX_DEPLOYMENT_TARGET=10.6' - s = Subprocess(log=self.logfile, shell=True, cwd=self.build_dir, print_cmd=False) + s = Subprocess(log=self.logfile, cwd=self.build_dir) s.check_call("./configure --prefix=%s %s %s" % (self.install_dir, self.options.configure, configure_option)) def make(self): - s = Subprocess(log=self.logfile, shell=True, cwd=self.build_dir, print_cmd=False) + s = Subprocess(log=self.logfile, cwd=self.build_dir) if self.options.force: s.check_call("make") else: @@ -194,7 +229,7 @@ class PythonInstaller(object): version = self.pkg.version if version == "1.5.2" or version == "1.6.1": makedirs(self.install_dir) - s = Subprocess(log=self.logfile, shell=True, cwd=self.build_dir, print_cmd=False) + s = Subprocess(log=self.logfile, cwd=self.build_dir) s.check_call("make install") def install_setuptools(self): @@ -227,12 +262,12 @@ class PythonInstaller(object): pyexec = os.path.join(install_dir,"bin","python") try: - s = Subprocess(log=self.logfile, shell=True, cwd=PATH_DISTS, print_cmd=False) + s = Subprocess(log=self.logfile, cwd=PATH_DISTS) logger.info("Installing distribute into %s" % install_dir) s.check_call("%s %s" % (pyexec, filename)) 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) + s.check_call("%s/bin/easy_install pip" % (install_dir)) except: logger.error("Failed to install setuptools. See %s/build.log to see why." % (ROOT)) logger.info("Skip install setuptools.") diff --git a/pythonbrew/util.py b/pythonbrew/util.py index a86fae0..6877a96 100644 --- a/pythonbrew/util.py +++ b/pythonbrew/util.py @@ -89,7 +89,7 @@ def rm_r(path): """like rm -r command.""" if os.path.isdir(path): shutil.rmtree(path) - else: + elif os.path.isfile(path): unlink(path) def off(): @@ -175,8 +175,17 @@ def untar_file(filename, location): finally: tar.close() +def unpack_downloadfile(content_type, download_file, target_dir): + logger.info("Extracting %s" % os.path.basename(download_file)) + if is_gzip(content_type, download_file): + untar_file(download_file, target_dir) + else: + logger.error("Cannot determine archive format of %s" % download_file) + return False + return True + class Subprocess(object): - def __init__(self, log=None, shell=False, cwd=None, print_cmd=True): + def __init__(self, log=None, shell=True, cwd=None, print_cmd=False): self._log = log self._shell = shell self._cwd = cwd