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