create_venv.py (6448B)
1 #!/usr/bin/env python3 2 # This Source Code Form is subject to the terms of the Mozilla Public 3 # License, v. 2.0. If a copy of the MPL was not distributed with this 4 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 6 """ 7 This scripts sets up a virtualenv and installs TPS into it. 8 It's probably best to specify a path NOT inside the repo, otherwise 9 all the virtualenv files will show up in e.g. hg status. 10 """ 11 12 import optparse 13 import os 14 import subprocess 15 import sys 16 import venv 17 18 here = os.path.dirname(os.path.abspath(__file__)) 19 usage_message = """ 20 *********************************************************************** 21 22 To run TPS, activate the virtualenv using: 23 source {TARGET}/{BIN_NAME} 24 25 To change your TPS config, please edit the file: 26 {TARGET}/config.json 27 28 To execute tps use: 29 runtps --binary=/path/to/firefox 30 31 See runtps --help for all options 32 33 *********************************************************************** 34 """ 35 36 if sys.platform == "win32": 37 bin_name = os.path.join("Scripts", "activate.bat") 38 python_env = os.path.join("Scripts", "python.exe") 39 else: 40 bin_name = os.path.join("bin", "activate") 41 python_env = os.path.join("bin", "python") 42 43 44 def setup_virtualenv(target): 45 print("Creating new virtual environment:", os.path.abspath(target)) 46 # system_site_packages=True so we have access to setuptools. 47 venv.create(target, system_site_packages=True) 48 49 50 def update_configfile(source, target, replacements): 51 lines = [] 52 53 with open(source) as config: 54 for line in config: 55 for source_string, target_string in replacements.items(): 56 if target_string: 57 line = line.replace(source_string, target_string) 58 lines.append(line) 59 60 with open(target, "w") as config: 61 for line in lines: 62 config.write(line) 63 64 65 def main(): 66 parser = optparse.OptionParser("Usage: %prog [options] path_to_venv") 67 parser.add_option( 68 "--keep-config", 69 dest="keep_config", 70 action="store_true", 71 help="Keep the existing config file.", 72 ) 73 parser.add_option( 74 "--password", 75 type="string", 76 dest="password", 77 metavar="FX_ACCOUNT_PASSWORD", 78 default=None, 79 help="The Firefox Account password.", 80 ) 81 parser.add_option( 82 "-p", 83 "--python", 84 type="string", 85 dest="python", 86 metavar="PYTHON_BIN", 87 default=None, 88 help="The Python interpreter to use.", 89 ) 90 parser.add_option( 91 "--sync-passphrase", 92 type="string", 93 dest="sync_passphrase", 94 metavar="SYNC_ACCOUNT_PASSPHRASE", 95 default=None, 96 help="The old Firefox Sync account passphrase.", 97 ) 98 parser.add_option( 99 "--sync-password", 100 type="string", 101 dest="sync_password", 102 metavar="SYNC_ACCOUNT_PASSWORD", 103 default=None, 104 help="The old Firefox Sync account password.", 105 ) 106 parser.add_option( 107 "--sync-username", 108 type="string", 109 dest="sync_username", 110 metavar="SYNC_ACCOUNT_USERNAME", 111 default=None, 112 help="The old Firefox Sync account username.", 113 ) 114 parser.add_option( 115 "--username", 116 type="string", 117 dest="username", 118 metavar="FX_ACCOUNT_USERNAME", 119 default=None, 120 help="The Firefox Account username.", 121 ) 122 123 (options, args) = parser.parse_args(args=None, values=None) 124 125 if len(args) != 1: 126 parser.error("Path to the environment has to be specified") 127 target = args[0] 128 assert target 129 130 setup_virtualenv(target) 131 132 # Activate tps environment 133 activate(target) 134 135 # Install TPS in environment 136 subprocess.check_call([ 137 os.path.join(target, python_env), 138 os.path.join(here, "setup.py"), 139 "install", 140 ]) 141 142 # Get the path to tests and extensions directory by checking check where 143 # the tests and extensions directories are located 144 sync_dir = os.path.abspath(os.path.join(here, "..", "..", "services", "sync")) 145 if os.path.exists(sync_dir): 146 testdir = os.path.join(sync_dir, "tests", "tps") 147 extdir = os.path.join(sync_dir, "tps", "extensions") 148 else: 149 testdir = os.path.join(here, "tests") 150 extdir = os.path.join(here, "extensions") 151 152 if not options.keep_config: 153 update_configfile( 154 os.path.join(here, "config", "config.json.in"), 155 os.path.join(target, "config.json"), 156 replacements={ 157 "__TESTDIR__": testdir.replace("\\", "/"), 158 "__EXTENSIONDIR__": extdir.replace("\\", "/"), 159 "__FX_ACCOUNT_USERNAME__": options.username, 160 "__FX_ACCOUNT_PASSWORD__": options.password, 161 "__SYNC_ACCOUNT_USERNAME__": options.sync_username, 162 "__SYNC_ACCOUNT_PASSWORD__": options.sync_password, 163 "__SYNC_ACCOUNT_PASSPHRASE__": options.sync_passphrase, 164 }, 165 ) 166 167 if not (options.username and options.password): 168 print("\nFirefox Account credentials not specified.") 169 if not (options.sync_username and options.sync_password and options.passphrase): 170 print("\nFirefox Sync account credentials not specified.") 171 172 # Print the user instructions 173 print(usage_message.format(TARGET=target, BIN_NAME=bin_name)) 174 175 176 def activate(target): 177 # This is a lightly modified copy of `activate_this.py`, which existed when 178 # venv was an external package, but doesn't come with the builtin venv support. 179 old_os_path = os.environ.get("PATH", "") 180 os.environ["PATH"] = ( 181 os.path.dirname(os.path.abspath(__file__)) + os.pathsep + old_os_path 182 ) 183 base = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 184 if sys.platform == "win32": 185 site_packages = os.path.join(base, "Lib", "site-packages") 186 else: 187 site_packages = os.path.join( 188 base, "lib", "python%s" % sys.version[:3], "site-packages" 189 ) 190 prev_sys_path = list(sys.path) 191 import site 192 193 site.addsitedir(site_packages) 194 sys.real_prefix = sys.prefix 195 sys.prefix = base 196 # Move the added items to the front of the path: 197 new_sys_path = [] 198 for item in list(sys.path): 199 if item not in prev_sys_path: 200 new_sys_path.append(item) 201 sys.path.remove(item) 202 sys.path[:0] = new_sys_path 203 204 205 if __name__ == "__main__": 206 main()