Justin Shepherd | 0d9bbd1 | 2011-08-11 12:57:44 -0500 | [diff] [blame] | 1 | # vim: tabstop=4 shiftwidth=4 softtabstop=4 |
| 2 | |
| 3 | """ |
| 4 | Installation script for Kong's testing virtualenv |
| 5 | """ |
| 6 | |
| 7 | import os |
| 8 | import stat |
| 9 | import string |
| 10 | import subprocess |
| 11 | import sys |
| 12 | |
| 13 | ROOT = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) |
| 14 | VENV = os.path.join(ROOT, '.kong-venv') |
| 15 | PIP_REQUIRES = os.path.join(ROOT, 'tools', 'pip-requires') |
| 16 | |
| 17 | |
| 18 | def die(message, *args): |
| 19 | print >> sys.stderr, message % args |
| 20 | sys.exit(1) |
| 21 | |
| 22 | |
| 23 | def whereis(executable): |
| 24 | """ |
| 25 | Detect whereis a binary and make sure it's executable we can execute. |
| 26 | """ |
| 27 | for d in string.split(os.environ['PATH'], \ |
| 28 | os.pathsep): |
| 29 | f = os.path.join(d, executable) |
| 30 | if os.path.isfile(f): |
| 31 | try: |
| 32 | st = os.stat(f) |
| 33 | except OSError: |
| 34 | continue |
| 35 | if stat.S_IMODE(st[stat.ST_MODE]) & 0111: |
| 36 | return True |
| 37 | return False |
| 38 | |
| 39 | |
| 40 | def run_command(cmd, redirect_output=True, check_exit_code=True): |
| 41 | """ |
| 42 | Runs a command in an out-of-process shell, returning the |
| 43 | output of that command. Working directory is ROOT. |
| 44 | """ |
| 45 | if redirect_output: |
| 46 | stdout = subprocess.PIPE |
| 47 | else: |
| 48 | stdout = None |
| 49 | |
| 50 | proc = subprocess.Popen(cmd, cwd=ROOT, stdout=stdout) |
| 51 | output = proc.communicate()[0] |
| 52 | if check_exit_code and proc.returncode != 0: |
| 53 | die('Command "%s" failed.\n%s', ' '.join(cmd), output) |
| 54 | return output |
| 55 | |
| 56 | |
| 57 | HAS_EASY_INSTALL = bool(whereis("easy_install")) |
| 58 | HAS_VIRTUALENV = bool(whereis("virtualenv")) |
| 59 | |
| 60 | |
| 61 | def check_dependencies(): |
| 62 | """Make sure virtualenv is in the path.""" |
| 63 | |
| 64 | if not HAS_VIRTUALENV: |
| 65 | print 'not found.' |
| 66 | # Try installing it via easy_install... |
| 67 | if HAS_EASY_INSTALL: |
| 68 | print 'Installing virtualenv via easy_install...', |
| 69 | if not run_command(['easy_install', 'virtualenv']): |
| 70 | die('ERROR: virtualenv not found.\n\n' |
| 71 | 'Glance development requires virtualenv, please install' |
| 72 | ' it using your favorite package management tool') |
| 73 | print 'done.' |
| 74 | print 'done.' |
| 75 | |
| 76 | |
| 77 | def create_virtualenv(venv=VENV): |
| 78 | """Creates the virtual environment and installs PIP only into the |
| 79 | virtual environment |
| 80 | """ |
| 81 | print 'Creating venv...', |
| 82 | run_command(['virtualenv', '-q', '--no-site-packages', VENV]) |
| 83 | print 'done.' |
| 84 | print 'Installing pip in virtualenv...', |
| 85 | if not run_command(['tools/with_venv.sh', 'easy_install', 'pip']).strip(): |
| 86 | die("Failed to install pip.") |
| 87 | print 'done.' |
| 88 | |
| 89 | |
| 90 | def install_dependencies(venv=VENV): |
| 91 | print 'Installing dependencies with pip (this can take a while)...' |
| 92 | |
| 93 | # Install greenlet by hand - just listing it in the requires file does not |
| 94 | # get it in stalled in the right order |
| 95 | venv_tool = 'tools/with_venv.sh' |
| 96 | run_command([venv_tool, 'pip', 'install', '-E', venv, '-r', PIP_REQUIRES], |
| 97 | redirect_output=False) |
| 98 | |
| 99 | # Tell the virtual env how to "import glance" |
| 100 | pthfile = os.path.join(venv, "lib", "python2.6", "site-packages", |
| 101 | "glance.pth") |
| 102 | f = open(pthfile, 'w') |
| 103 | f.write("%s\n" % ROOT) |
| 104 | |
| 105 | |
| 106 | def print_help(): |
| 107 | help = """ |
| 108 | Kong testing environment setup is complete. |
| 109 | |
| 110 | Kong testing uses virtualenv to track and manage Python dependencies |
| 111 | while in development and testing. |
| 112 | |
| 113 | To activate the Kong virtualenv for the extent of your current shell |
| 114 | session you can run: |
| 115 | |
| 116 | $ source .kong-venv/bin/activate |
| 117 | |
| 118 | Or, if you prefer, you can run commands in the virtualenv on a case by case |
| 119 | basis by running: |
| 120 | |
| 121 | $ tools/with_venv.sh <your command> |
| 122 | |
| 123 | Also, make test will automatically use the virtualenv. |
| 124 | """ |
| 125 | print help |
| 126 | |
| 127 | |
| 128 | def main(argv): |
| 129 | check_dependencies() |
| 130 | create_virtualenv() |
| 131 | install_dependencies() |
| 132 | print_help() |
| 133 | |
| 134 | if __name__ == '__main__': |
| 135 | main(sys.argv) |