michael@0: #!/usr/bin/env python michael@0: # This Source Code Form is subject to the terms of the Mozilla Public michael@0: # License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: # file, You can obtain one at http://mozilla.org/MPL/2.0/. michael@0: michael@0: """ michael@0: This scripts sets up a virtualenv and installs TPS into it. michael@0: It's probably best to specify a path NOT inside the repo, otherwise michael@0: all the virtualenv files will show up in e.g. hg status. michael@0: """ michael@0: michael@0: import optparse michael@0: import os michael@0: import shutil michael@0: import subprocess michael@0: import sys michael@0: import urllib2 michael@0: import zipfile michael@0: michael@0: michael@0: here = os.path.dirname(os.path.abspath(__file__)) michael@0: usage_message = """ michael@0: *********************************************************************** michael@0: michael@0: To run TPS, activate the virtualenv using: michael@0: source {TARGET}/{BIN_NAME} michael@0: michael@0: To change your TPS config, please edit the file: michael@0: {TARGET}/config.json michael@0: michael@0: To execute tps use: michael@0: runtps --binary=/path/to/firefox michael@0: michael@0: See runtps --help for all options michael@0: michael@0: *********************************************************************** michael@0: """ michael@0: michael@0: # Link to the folder, which contains the zip archives of virtualenv michael@0: URL_VIRTUALENV = 'https://codeload.github.com/pypa/virtualenv/zip/' michael@0: VERSION_VIRTUALENV = '1.11.6' michael@0: michael@0: michael@0: if sys.platform == 'win32': michael@0: bin_name = os.path.join('Scripts', 'activate.bat') michael@0: activate_env = os.path.join('Scripts', 'activate_this.py') michael@0: python_env = os.path.join('Scripts', 'python.exe') michael@0: else: michael@0: bin_name = os.path.join('bin', 'activate') michael@0: activate_env = os.path.join('bin', 'activate_this.py') michael@0: python_env = os.path.join('bin', 'python') michael@0: michael@0: michael@0: def download(url, target): michael@0: """Downloads the specified url to the given target.""" michael@0: response = urllib2.urlopen(url) michael@0: with open(target, 'wb') as f: michael@0: f.write(response.read()) michael@0: michael@0: return target michael@0: michael@0: michael@0: def setup_virtualenv(target, python_bin=None): michael@0: script_path = os.path.join(here, 'virtualenv-%s' % VERSION_VIRTUALENV, michael@0: 'virtualenv.py') michael@0: michael@0: print 'Downloading virtualenv %s' % VERSION_VIRTUALENV michael@0: zip_path = download(URL_VIRTUALENV + VERSION_VIRTUALENV, michael@0: os.path.join(here, 'virtualenv.zip')) michael@0: michael@0: try: michael@0: with zipfile.ZipFile(zip_path, 'r') as f: michael@0: f.extractall(here) michael@0: michael@0: print 'Creating new virtual environment' michael@0: cmd_args = [sys.executable, script_path, target] michael@0: michael@0: if python_bin: michael@0: cmd_args.extend(['-p', python_bin]) michael@0: michael@0: subprocess.check_call(cmd_args) michael@0: finally: michael@0: try: michael@0: os.remove(zip_path) michael@0: except OSError: michael@0: pass michael@0: michael@0: shutil.rmtree(os.path.dirname(script_path), ignore_errors=True) michael@0: michael@0: michael@0: def update_configfile(source, target, replacements): michael@0: lines = [] michael@0: michael@0: with open(source) as config: michael@0: for line in config: michael@0: for source_string, target_string in replacements.iteritems(): michael@0: if target_string: michael@0: line = line.replace(source_string, target_string) michael@0: lines.append(line) michael@0: michael@0: with open(target, 'w') as config: michael@0: for line in lines: michael@0: config.write(line) michael@0: michael@0: michael@0: def main(): michael@0: parser = optparse.OptionParser('Usage: %prog [options] path_to_venv') michael@0: parser.add_option('--password', michael@0: type='string', michael@0: dest='password', michael@0: metavar='FX_ACCOUNT_PASSWORD', michael@0: default=None, michael@0: help='The Firefox Account password.') michael@0: parser.add_option('-p', '--python', michael@0: type='string', michael@0: dest='python', michael@0: metavar='PYTHON_BIN', michael@0: default=None, michael@0: help='The Python interpreter to use.') michael@0: parser.add_option('--sync-passphrase', michael@0: type='string', michael@0: dest='sync_passphrase', michael@0: metavar='SYNC_ACCOUNT_PASSPHRASE', michael@0: default=None, michael@0: help='The old Firefox Sync account passphrase.') michael@0: parser.add_option('--sync-password', michael@0: type='string', michael@0: dest='sync_password', michael@0: metavar='SYNC_ACCOUNT_PASSWORD', michael@0: default=None, michael@0: help='The old Firefox Sync account password.') michael@0: parser.add_option('--sync-username', michael@0: type='string', michael@0: dest='sync_username', michael@0: metavar='SYNC_ACCOUNT_USERNAME', michael@0: default=None, michael@0: help='The old Firefox Sync account username.') michael@0: parser.add_option('--username', michael@0: type='string', michael@0: dest='username', michael@0: metavar='FX_ACCOUNT_USERNAME', michael@0: default=None, michael@0: help='The Firefox Account username.') michael@0: michael@0: (options, args) = parser.parse_args(args=None, values=None) michael@0: michael@0: if len(args) != 1: michael@0: parser.error('Path to the environment has to be specified') michael@0: target = args[0] michael@0: assert(target) michael@0: michael@0: setup_virtualenv(target, python_bin=options.python) michael@0: michael@0: # Activate tps environment michael@0: tps_env = os.path.join(target, activate_env) michael@0: execfile(tps_env, dict(__file__=tps_env)) michael@0: michael@0: # Install TPS in environment michael@0: subprocess.check_call([os.path.join(target, python_env), michael@0: os.path.join(here, 'setup.py'), 'install']) michael@0: michael@0: # Get the path to tests and extensions directory by checking check where michael@0: # the tests and extensions directories are located michael@0: sync_dir = os.path.abspath(os.path.join(here, '..', '..', 'services', michael@0: 'sync')) michael@0: if os.path.exists(sync_dir): michael@0: testdir = os.path.join(sync_dir, 'tests', 'tps') michael@0: extdir = os.path.join(sync_dir, 'tps', 'extensions') michael@0: else: michael@0: testdir = os.path.join(here, 'tests') michael@0: extdir = os.path.join(here, 'extensions') michael@0: michael@0: update_configfile(os.path.join(here, 'config', 'config.json.in'), michael@0: os.path.join(target, 'config.json'), michael@0: replacements={ michael@0: '__TESTDIR__': testdir.replace('\\','/'), michael@0: '__EXTENSIONDIR__': extdir.replace('\\','/'), michael@0: '__FX_ACCOUNT_USERNAME__': options.username, michael@0: '__FX_ACCOUNT_PASSWORD__': options.password, michael@0: '__SYNC_ACCOUNT_USERNAME__': options.sync_username, michael@0: '__SYNC_ACCOUNT_PASSWORD__': options.sync_password, michael@0: '__SYNC_ACCOUNT_PASSPHRASE__': options.sync_passphrase}) michael@0: michael@0: if not (options.username and options.password): michael@0: print '\nFirefox Account credentials not specified.' michael@0: if not (options.sync_username and options.sync_password and options.passphrase): michael@0: print '\nFirefox Sync account credentials not specified.' michael@0: michael@0: # Print the user instructions michael@0: print usage_message.format(TARGET=target, michael@0: BIN_NAME=bin_name) michael@0: michael@0: if __name__ == "__main__": michael@0: main()