Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1073)

Side by Side Diff: bootstrap/win/git_bootstrap.py

Issue 2254843004: Add git_bootstrap.py, which bootstraps git on Windows using CIPD (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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:]))
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698