Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 import argparse | |
| 6 import fnmatch | |
| 7 import logging | |
| 8 import os | |
| 9 import shutil | |
| 10 import subprocess | |
| 11 import sys | |
| 12 import tempfile | |
| 13 | |
| 14 | |
| 15 THIS_DIR = os.path.abspath(os.path.dirname(__file__)) | |
| 16 ROOT_DIR = os.path.abspath(os.path.join(THIS_DIR, '..', '..')) | |
| 17 | |
| 18 DEVNULL = open(os.devnull, 'w') | |
| 19 | |
| 20 | |
| 21 def _check_call(argv, **kwargs): | |
| 22 """Wrapper for subprocess.check_call that adds logging.""" | |
| 23 logging.info('running %r', argv) | |
| 24 subprocess.check_call(argv, **kwargs) | |
| 25 | |
| 26 | |
| 27 def get_target_git_version(): | |
| 28 """Returns git version that should be installed.""" | |
| 29 if os.path.exists(os.path.join(ROOT_DIR, '.git_bleeding_edge')): | |
| 30 git_version_file = 'git_version_bleeding_edge.txt' | |
| 31 else: | |
| 32 git_version_file = 'git_version.txt' | |
| 33 with open(os.path.join(THIS_DIR, git_version_file)) as f: | |
| 34 return f.read().strip() | |
| 35 | |
| 36 | |
| 37 def clean_up_old_git_installations(git_directory): | |
| 38 """Removes git installations other than |git_directory|.""" | |
| 39 for entry in fnmatch.filter(os.listdir(ROOT_DIR), 'git-*_bin'): | |
|
iannucci
2016/08/18 18:45:39
I think you just want to use the glob library: htt
| |
| 40 full_entry = os.path.join(ROOT_DIR, entry) | |
| 41 if full_entry != git_directory: | |
| 42 logging.info('Cleaning up old git installation %r', entry) | |
| 43 shutil.rmtree(full_entry, ignore_errors=True) | |
| 44 | |
| 45 | |
| 46 def bootstrap_cipd(cipd_directory): | |
| 47 """Bootstraps CIPD client into |cipd_directory|.""" | |
| 48 _check_call([ | |
| 49 sys.executable, | |
| 50 os.path.join(ROOT_DIR, 'recipe_modules', 'cipd', 'resources', | |
| 51 'bootstrap.py'), | |
|
iannucci
2016/08/18 18:45:39
Let's add a comment in this bootstrap.py file to m
| |
| 52 '--platform', 'windows-amd64', | |
|
iannucci
2016/08/18 18:45:39
why doesn't bootstrap.py automatically compute thi
| |
| 53 '--dest-directory', cipd_directory | |
| 54 ]) | |
| 55 | |
| 56 | |
| 57 def cipd_install(args, dest_directory, package, version): | |
| 58 """Installs CIPD |package| at |version| into |dest_directory|.""" | |
| 59 manifest_file = tempfile.mktemp() | |
| 60 try: | |
| 61 with open(manifest_file, 'w') as f: | |
| 62 f.write('%s %s\n' % (package, version)) | |
| 63 | |
| 64 cipd_args = [ | |
| 65 args.cipd_client, | |
| 66 'ensure', | |
| 67 '-list', manifest_file, | |
| 68 '-root', dest_directory, | |
| 69 ] | |
| 70 if args.cipd_cache_directory: | |
| 71 cipd_args.extend(['-cache-dir', args.cipd_cache_directory]) | |
| 72 if args.verbose: | |
| 73 cipd_args.append('-verbose') | |
| 74 _check_call(cipd_args) | |
| 75 finally: | |
| 76 os.remove(manifest_file) | |
| 77 | |
| 78 | |
| 79 def need_to_install_git(args, git_directory): | |
| 80 """Returns True if git needs to be installed.""" | |
| 81 if args.force: | |
| 82 return True | |
| 83 git_exe_path = os.path.join(git_directory, 'bin', 'git.exe') | |
| 84 if not os.path.exists(git_exe_path): | |
| 85 return True | |
| 86 if subprocess.call( | |
| 87 [git_exe_path, '--version'], | |
| 88 stdout=DEVNULL, stderr=DEVNULL) != 0: | |
| 89 return True | |
| 90 for script in ('git.bat', 'gitk.bat', 'ssh.bat', 'ssh-keygen.bat', | |
| 91 'git-bash'): | |
| 92 full_path = os.path.join(ROOT_DIR, script) | |
| 93 if not os.path.exists(full_path): | |
| 94 return True | |
| 95 with open(full_path) as f: | |
| 96 if os.path.relpath(git_directory, ROOT_DIR) not in f.read(): | |
| 97 return True | |
| 98 if not os.path.exists(os.path.join( | |
| 99 git_directory, 'etc', 'profile.d', 'python.sh')): | |
| 100 return True | |
| 101 return False | |
| 102 | |
| 103 | |
| 104 def install_git(args, git_version, git_directory): | |
| 105 """Installs |git_version| into |git_directory|.""" | |
| 106 if not args.cipd_client: | |
| 107 bootstrap_cipd(ROOT_DIR) | |
| 108 args.cipd_client = os.path.join(ROOT_DIR, 'cipd') | |
| 109 temp_dir = tempfile.mkdtemp() | |
| 110 try: | |
| 111 cipd_install(args, | |
| 112 temp_dir, | |
| 113 'infra/depot_tools/git_installer/windows-amd64', | |
| 114 'v' + git_version.replace('.', '_')) | |
| 115 | |
| 116 if not os.path.exists(git_directory): | |
| 117 os.makedirs(git_directory) | |
| 118 | |
| 119 # 7-zip has weird expectations for command-line syntax. Pass it as a string | |
| 120 # to avoid subprocess module quoting breaking it. Also double-escape | |
| 121 # backslashes in paths. | |
| 122 _check_call(' '.join([ | |
| 123 os.path.join(temp_dir, 'git-installer.exe'), | |
| 124 '-y', | |
| 125 '-InstallPath="%s"' % git_directory.replace('\\', '\\\\'), | |
| 126 '-Directory="%s"' % git_directory.replace('\\', '\\\\'), | |
|
iannucci
2016/08/18 18:45:38
if you use raw strings, you can halve the number o
| |
| 127 ])) | |
| 128 finally: | |
| 129 shutil.rmtree(temp_dir, ignore_errors=True) | |
| 130 | |
| 131 with open(os.path.join(THIS_DIR, 'git.template.bat')) as f: | |
| 132 git_template = f.read() | |
| 133 git_template = git_template.replace( | |
| 134 'GIT_BIN_DIR', os.path.relpath(git_directory, ROOT_DIR)) | |
| 135 with open(os.path.join(ROOT_DIR, 'git.bat'), 'w') as f: | |
| 136 f.write(git_template.replace('GIT_PROGRAM', 'cmd\\git.exe')) | |
| 137 with open(os.path.join(ROOT_DIR, 'gitk.bat'), 'w') as f: | |
| 138 f.write(git_template.replace('GIT_PROGRAM', 'cmd\\gitk.exe')) | |
| 139 with open(os.path.join(ROOT_DIR, 'ssh.bat'), 'w') as f: | |
| 140 f.write(git_template.replace('GIT_PROGRAM', 'usr\\bin\\ssh.exe')) | |
| 141 with open(os.path.join(ROOT_DIR, 'ssh-keygen.bat'), 'w') as f: | |
| 142 f.write(git_template.replace('GIT_PROGRAM', 'usr\\bin\\ssh-keygen.exe')) | |
|
iannucci
2016/08/18 18:45:39
can we make this a loop over e.g. a list of tuples
| |
| 143 with open(os.path.join(THIS_DIR, 'git-bash.template.sh')) as f: | |
| 144 git_bash_template = f.read() | |
| 145 with open(os.path.join(ROOT_DIR, 'git-bash'), 'w') as f: | |
| 146 f.write(git_bash_template.replace( | |
| 147 'GIT_BIN_DIR', os.path.relpath(git_directory, ROOT_DIR))) | |
| 148 shutil.copyfile( | |
| 149 os.path.join(THIS_DIR, 'profile.d.python.sh'), | |
| 150 os.path.join(git_directory, 'etc', 'profile.d', 'python.sh')) | |
| 151 | |
| 152 git_bat_path = os.path.join(ROOT_DIR, 'git.bat') | |
| 153 _check_call([git_bat_path, 'config', '--system', 'core.autocrlf', 'false']) | |
| 154 _check_call([git_bat_path, 'config', '--system', 'core.filemode', 'false']) | |
| 155 _check_call([git_bat_path, 'config', '--system', 'core.preloadindex', 'true']) | |
| 156 _check_call([git_bat_path, 'config', '--system', 'core.fscache', 'true']) | |
| 157 | |
| 158 | |
| 159 def sync_git_help_files(git_directory): | |
| 160 """Updates depot_tools help files inside |git_directory|.""" | |
| 161 _check_call([ | |
| 162 'xcopy', '/i', '/q', '/d', '/y', | |
| 163 os.path.join(ROOT_DIR, 'man', 'html', '*'), | |
| 164 os.path.join(git_directory, 'mingw64', 'share', 'doc', 'git-doc')], | |
| 165 stdout=DEVNULL) | |
|
iannucci
2016/08/18 18:45:39
this is a bit janky (it should probably not shell
| |
| 166 | |
| 167 | |
| 168 def main(argv): | |
| 169 parser = argparse.ArgumentParser() | |
| 170 parser.add_argument('--cipd-client', help='Path to CIPD client binary.') | |
| 171 parser.add_argument('--cipd-cache-directory', | |
| 172 help='Path to CIPD cache directory.') | |
| 173 parser.add_argument('--force', action='store_true', | |
| 174 help='Always re-install git.') | |
| 175 parser.add_argument('--verbose', action='store_true') | |
| 176 args = parser.parse_args(argv) | |
| 177 | |
| 178 if os.environ.get('WIN_TOOLS_FORCE') == '1': | |
| 179 args.force = True | |
| 180 | |
| 181 logging.basicConfig(level=logging.INFO if args.verbose else logging.WARN) | |
| 182 | |
| 183 git_version = get_target_git_version() | |
| 184 git_directory = os.path.join(ROOT_DIR, 'git-%s-64_bin' % git_version) | |
| 185 | |
| 186 clean_up_old_git_installations(git_directory) | |
| 187 | |
| 188 if need_to_install_git(args, git_directory): | |
| 189 install_git(args, git_version, git_directory) | |
| 190 | |
| 191 sync_git_help_files(git_directory) | |
| 192 | |
| 193 return 0 | |
| 194 | |
| 195 | |
| 196 if __name__ == '__main__': | |
| 197 sys.exit(main(sys.argv[1:])) | |
| OLD | NEW |