blob: ae234fe32318f3e204d0c6940d071944d75363e6 [file] [log] [blame]
Rahul Chaudhry8ac4ec02014-11-01 09:31:15 -07001# Copyright 2013 The Chromium OS Authors. All rights reserved.
Yunlian Jiangb0a02f42013-08-22 09:55:54 -07002# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
Ahmad Shariffd356fb2012-05-07 12:02:16 -07004"""Utilities for toolchain build."""
5
Rahul Chaudhrycbc5a262015-12-30 17:05:14 -08006from __future__ import print_function
7
Luis Lozanof2a3ef42015-12-15 13:49:30 -08008__author__ = 'asharif@google.com (Ahmad Sharif)'
Ahmad Shariffd356fb2012-05-07 12:02:16 -07009
Ahmad Shariff395c262012-10-09 17:48:09 -070010from contextlib import contextmanager
Ahmad Shariffd356fb2012-05-07 12:02:16 -070011import os
12import re
Ahmad Sharif4467f002012-12-20 12:09:49 -080013import shutil
14import sys
Han Shencc34c222014-01-03 11:39:39 -080015import traceback
Ahmad Sharif4467f002012-12-20 12:09:49 -080016
Ahmad Shariffd356fb2012-05-07 12:02:16 -070017import command_executer
18import logger
Ahmad Shariff395c262012-10-09 17:48:09 -070019
Luis Lozanof2a3ef42015-12-15 13:49:30 -080020CHROMEOS_SCRIPTS_DIR = '~/trunk/src/scripts'
21TOOLCHAIN_UTILS_PATH = '~/trunk/src/platform/dev/toolchain_utils.sh'
Rahul Chaudhry8ac4ec02014-11-01 09:31:15 -070022
23
Ahmad Shariff395c262012-10-09 17:48:09 -070024def GetChromeOSVersionFromLSBVersion(lsb_version):
Ahmad Sharif4467f002012-12-20 12:09:49 -080025 """Get Chromeos version from Lsb version."""
Ahmad Shariff395c262012-10-09 17:48:09 -070026 ce = command_executer.GetCommandExecuter()
Luis Lozanof2a3ef42015-12-15 13:49:30 -080027 command = ('git ls-remote '
28 'https://chromium.googlesource.com/chromiumos/manifest.git')
Luis Lozano036c9232015-12-10 10:47:01 -080029 ret, out, _ = ce.RunCommandWOutput(command, print_to_console=False)
Luis Lozanof2a3ef42015-12-15 13:49:30 -080030 assert ret == 0, 'Command %s failed' % command
Ahmad Shariff395c262012-10-09 17:48:09 -070031 lower = []
32 for line in out.splitlines():
Luis Lozanof2a3ef42015-12-15 13:49:30 -080033 mo = re.search(r'refs/heads/release-R(\d+)-(\d+)\.B', line)
Ahmad Shariff395c262012-10-09 17:48:09 -070034 if mo:
35 revision = int(mo.group(1))
36 build = int(mo.group(2))
Luis Lozanof2a3ef42015-12-15 13:49:30 -080037 lsb_build = int(lsb_version.split('.')[0])
Ahmad Shariff395c262012-10-09 17:48:09 -070038 if lsb_build > build:
39 lower.append(revision)
40 lower = sorted(lower)
41 if lower:
Luis Lozanof2a3ef42015-12-15 13:49:30 -080042 return 'R%d-%s' % (lower[-1] + 1, lsb_version)
Ahmad Shariff395c262012-10-09 17:48:09 -070043 else:
Luis Lozanof2a3ef42015-12-15 13:49:30 -080044 return 'Unknown'
Ahmad Shariffd356fb2012-05-07 12:02:16 -070045
46
47def ApplySubs(string, *substitutions):
48 for pattern, replacement in substitutions:
49 string = re.sub(pattern, replacement, string)
50 return string
51
52
Ahmad Sharif4467f002012-12-20 12:09:49 -080053def UnitToNumber(unit_num, base=1000):
54 """Convert a number with unit to float."""
Luis Lozanof2a3ef42015-12-15 13:49:30 -080055 unit_dict = {'kilo': base, 'mega': base**2, 'giga': base**3}
Ahmad Sharif4467f002012-12-20 12:09:49 -080056 unit_num = unit_num.lower()
Luis Lozanof2a3ef42015-12-15 13:49:30 -080057 mo = re.search(r'(\d*)(.+)?', unit_num)
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -070058 number = mo.group(1)
59 unit = mo.group(2)
Ahmad Shariff395c262012-10-09 17:48:09 -070060 if not unit:
61 return float(number)
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -070062 for k, v in unit_dict.items():
63 if k.startswith(unit):
64 return float(number) * v
Luis Lozanof2a3ef42015-12-15 13:49:30 -080065 raise Exception('Unit: %s not found in byte: %s!' % (unit, unit_num))
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -070066
67
Ahmad Shariffd356fb2012-05-07 12:02:16 -070068def GetFilenameFromString(string):
David Sharp3e8c2192016-01-27 20:16:38 -080069 return ApplySubs(string, (r'/', '__'), (r'\s', '_'), (r'[\\$="?^]', ''),)
Ahmad Shariffd356fb2012-05-07 12:02:16 -070070
71
72def GetRoot(scr_name):
73 """Break up pathname into (dir+name)."""
74 abs_path = os.path.abspath(scr_name)
75 return (os.path.dirname(abs_path), os.path.basename(abs_path))
76
77
Ahmad Sharif4467f002012-12-20 12:09:49 -080078def GetChromeOSKeyFile(chromeos_root):
Luis Lozanof2a3ef42015-12-15 13:49:30 -080079 return os.path.join(chromeos_root, 'src', 'scripts', 'mod_for_test_scripts',
80 'ssh_keys', 'testing_rsa')
Ahmad Sharif4467f002012-12-20 12:09:49 -080081
82
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -070083def GetChrootPath(chromeos_root):
Luis Lozanof2a3ef42015-12-15 13:49:30 -080084 return os.path.join(chromeos_root, 'chroot')
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -070085
86
87def GetInsideChrootPath(chromeos_root, file_path):
88 if not file_path.startswith(GetChrootPath(chromeos_root)):
89 raise Exception("File: %s doesn't seem to be in the chroot: %s" %
Luis Lozanof2a3ef42015-12-15 13:49:30 -080090 (file_path, chromeos_root))
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -070091 return file_path[len(GetChrootPath(chromeos_root)):]
92
93
94def GetOutsideChrootPath(chromeos_root, file_path):
Luis Lozanof2a3ef42015-12-15 13:49:30 -080095 return os.path.join(GetChrootPath(chromeos_root), file_path.lstrip('/'))
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -070096
97
Ahmad Shariffd356fb2012-05-07 12:02:16 -070098def FormatQuotedCommand(command):
David Sharp3e8c2192016-01-27 20:16:38 -080099 return ApplySubs(command, ('"', r'\"'))
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700100
101
102def FormatCommands(commands):
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800103 return ApplySubs(
104 str(commands), ('&&', '&&\n'), (';', ';\n'), (r'\n+\s*', '\n'))
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700105
106
107def GetImageDir(chromeos_root, board):
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800108 return os.path.join(chromeos_root, 'src', 'build', 'images', board)
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700109
110
cmtice56fb7162014-06-18 11:32:15 -0700111def LabelLatestImage(chromeos_root, board, label, vanilla_path=None):
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700112 image_dir = GetImageDir(chromeos_root, board)
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800113 latest_image_dir = os.path.join(image_dir, 'latest')
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700114 latest_image_dir = os.path.realpath(latest_image_dir)
115 latest_image_dir = os.path.basename(latest_image_dir)
cmtice56fb7162014-06-18 11:32:15 -0700116 retval = 0
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700117 with WorkingDirectory(image_dir):
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800118 command = 'ln -sf -T %s %s' % (latest_image_dir, label)
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700119 ce = command_executer.GetCommandExecuter()
cmtice56fb7162014-06-18 11:32:15 -0700120 retval = ce.RunCommand(command)
121 if retval:
122 return retval
123 if vanilla_path:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800124 command = 'ln -sf -T %s %s' % (vanilla_path, 'vanilla')
cmtice56fb7162014-06-18 11:32:15 -0700125 retval2 = ce.RunCommand(command)
126 return retval2
127 return retval
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700128
129
130def DoesLabelExist(chromeos_root, board, label):
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800131 image_label = os.path.join(GetImageDir(chromeos_root, board), label)
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700132 return os.path.exists(image_label)
133
134
Luis Lozanof81680c2013-03-15 14:44:13 -0700135def GetBuildPackagesCommand(board, usepkg=False, debug=False):
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700136 if usepkg:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800137 usepkg_flag = '--usepkg'
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700138 else:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800139 usepkg_flag = '--nousepkg'
Luis Lozanof81680c2013-03-15 14:44:13 -0700140 if debug:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800141 withdebug_flag = '--withdebug'
Luis Lozanof81680c2013-03-15 14:44:13 -0700142 else:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800143 withdebug_flag = '--nowithdebug'
144 return ('%s/build_packages %s --withdev --withtest --withautotest '
145 '--skip_toolchain_update %s --board=%s '
146 '--accept_licenses=@CHROMEOS' %
Rahul Chaudhry8ac4ec02014-11-01 09:31:15 -0700147 (CHROMEOS_SCRIPTS_DIR, usepkg_flag, withdebug_flag, board))
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700148
149
Luis Lozanof81680c2013-03-15 14:44:13 -0700150def GetBuildImageCommand(board, dev=False):
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800151 dev_args = ''
Luis Lozanof81680c2013-03-15 14:44:13 -0700152 if dev:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800153 dev_args = '--noenable_rootfs_verification --disk_layout=2gb-rootfs'
154 return ('%s/build_image --board=%s %s test' %
Rahul Chaudhry8ac4ec02014-11-01 09:31:15 -0700155 (CHROMEOS_SCRIPTS_DIR, board, dev_args))
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700156
Han Shene4b6f222013-11-22 10:02:38 -0800157
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800158def GetSetupBoardCommand(board,
159 gcc_version=None,
160 binutils_version=None,
161 usepkg=None,
162 force=None):
Ahmad Sharif4467f002012-12-20 12:09:49 -0800163 """Get setup_board command."""
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700164 options = []
165
166 if gcc_version:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800167 options.append('--gcc_version=%s' % gcc_version)
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700168
169 if binutils_version:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800170 options.append('--binutils_version=%s' % binutils_version)
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700171
172 if usepkg:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800173 options.append('--usepkg')
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700174 else:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800175 options.append('--nousepkg')
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700176
177 if force:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800178 options.append('--force')
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700179
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800180 options.append('--accept_licenses=@CHROMEOS')
Yunlian Jiangb0a02f42013-08-22 09:55:54 -0700181
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800182 return ('%s/setup_board --board=%s %s' %
183 (CHROMEOS_SCRIPTS_DIR, board, ' '.join(options)))
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700184
185
186def CanonicalizePath(path):
187 path = os.path.expanduser(path)
188 path = os.path.realpath(path)
189 return path
190
191
192def GetCtargetFromBoard(board, chromeos_root):
Ahmad Sharif4467f002012-12-20 12:09:49 -0800193 """Get Ctarget from board."""
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800194 base_board = board.split('_')[0]
195 command = ('source %s; get_ctarget_from_board %s' %
Rahul Chaudhry8ac4ec02014-11-01 09:31:15 -0700196 (TOOLCHAIN_UTILS_PATH, base_board))
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700197 ce = command_executer.GetCommandExecuter()
Luis Lozano036c9232015-12-10 10:47:01 -0800198 ret, out, _ = ce.ChrootRunCommandWOutput(chromeos_root, command)
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700199 if ret != 0:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800200 raise ValueError('Board %s is invalid!' % board)
Ahmad Shariff395c262012-10-09 17:48:09 -0700201 # Remove ANSI escape sequences.
202 out = StripANSIEscapeSequences(out)
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700203 return out.strip()
204
205
Rahul Chaudhry215c12f2014-11-04 15:18:47 -0800206def GetArchFromBoard(board, chromeos_root):
207 """Get Arch from board."""
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800208 base_board = board.split('_')[0]
209 command = ('source %s; get_board_arch %s' %
Rahul Chaudhry215c12f2014-11-04 15:18:47 -0800210 (TOOLCHAIN_UTILS_PATH, base_board))
211 ce = command_executer.GetCommandExecuter()
Luis Lozano036c9232015-12-10 10:47:01 -0800212 ret, out, _ = ce.ChrootRunCommandWOutput(chromeos_root, command)
Rahul Chaudhry215c12f2014-11-04 15:18:47 -0800213 if ret != 0:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800214 raise ValueError('Board %s is invalid!' % board)
Rahul Chaudhry215c12f2014-11-04 15:18:47 -0800215 # Remove ANSI escape sequences.
216 out = StripANSIEscapeSequences(out)
217 return out.strip()
218
219
220def GetGccLibsDestForBoard(board, chromeos_root):
221 """Get gcc libs destination from board."""
222 arch = GetArchFromBoard(board, chromeos_root)
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800223 if arch == 'x86':
224 return '/build/%s/usr/lib/gcc/' % board
225 if arch == 'amd64':
226 return '/build/%s/usr/lib64/gcc/' % board
227 if arch == 'arm':
228 return '/build/%s/usr/lib/gcc/' % board
229 if arch == 'arm64':
230 return '/build/%s/usr/lib/gcc/' % board
231 raise ValueError('Arch %s is invalid!' % arch)
Rahul Chaudhry215c12f2014-11-04 15:18:47 -0800232
233
Ahmad Shariff395c262012-10-09 17:48:09 -0700234def StripANSIEscapeSequences(string):
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800235 string = re.sub(r'\x1b\[[0-9]*[a-zA-Z]', '', string)
Ahmad Shariff395c262012-10-09 17:48:09 -0700236 return string
237
238
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700239def GetChromeSrcDir():
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800240 return 'var/cache/distfiles/target/chrome-src/src'
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700241
242
243def GetEnvStringFromDict(env_dict):
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800244 return ' '.join(["%s=\"%s\"" % var for var in env_dict.items()])
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700245
246
Ahmad Shariff395c262012-10-09 17:48:09 -0700247def MergeEnvStringWithDict(env_string, env_dict, prepend=True):
Ahmad Sharif4467f002012-12-20 12:09:49 -0800248 """Merge env string with dict."""
Ahmad Shariff395c262012-10-09 17:48:09 -0700249 if not env_string.strip():
250 return GetEnvStringFromDict(env_dict)
251 override_env_list = []
252 ce = command_executer.GetCommandExecuter()
253 for k, v in env_dict.items():
254 v = v.strip("\"'")
255 if prepend:
256 new_env = "%s=\"%s $%s\"" % (k, v, k)
257 else:
258 new_env = "%s=\"$%s %s\"" % (k, k, v)
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800259 command = '; '.join([env_string, new_env, 'echo $%s' % k])
Luis Lozano036c9232015-12-10 10:47:01 -0800260 ret, out, _ = ce.RunCommandWOutput(command)
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800261 override_env_list.append('%s=%r' % (k, out.strip()))
262 ret = env_string + ' ' + ' '.join(override_env_list)
Ahmad Shariff395c262012-10-09 17:48:09 -0700263 return ret.strip()
264
265
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700266def GetAllImages(chromeos_root, board):
267 ce = command_executer.GetCommandExecuter()
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800268 command = ('find %s/src/build/images/%s -name chromiumos_test_image.bin' %
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700269 (chromeos_root, board))
Luis Lozano036c9232015-12-10 10:47:01 -0800270 ret, out, _ = ce.RunCommandWOutput(command)
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800271 assert ret == 0, 'Could not run command: %s' % command
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700272 return out.splitlines()
273
274
Ahmad Sharif4467f002012-12-20 12:09:49 -0800275def IsFloat(text):
276 if text is None:
277 return False
278 try:
279 float(text)
280 return True
281 except ValueError:
282 return False
283
Han Shene4b6f222013-11-22 10:02:38 -0800284
Ahmad Sharif4467f002012-12-20 12:09:49 -0800285def RemoveChromeBrowserObjectFiles(chromeos_root, board):
Han Shene4b6f222013-11-22 10:02:38 -0800286 """Remove any object files from all the posible locations."""
Ahmad Sharif4467f002012-12-20 12:09:49 -0800287 out_dir = os.path.join(
288 GetChrootPath(chromeos_root),
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800289 'var/cache/chromeos-chrome/chrome-src/src/out_%s' % board)
Ahmad Sharif4467f002012-12-20 12:09:49 -0800290 if os.path.exists(out_dir):
291 shutil.rmtree(out_dir)
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800292 logger.GetLogger().LogCmd('rm -rf %s' % out_dir)
Ahmad Sharif4467f002012-12-20 12:09:49 -0800293 out_dir = os.path.join(
294 GetChrootPath(chromeos_root),
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800295 'var/cache/chromeos-chrome/chrome-src-internal/src/out_%s' % board)
Ahmad Sharif4467f002012-12-20 12:09:49 -0800296 if os.path.exists(out_dir):
297 shutil.rmtree(out_dir)
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800298 logger.GetLogger().LogCmd('rm -rf %s' % out_dir)
Ahmad Sharif4467f002012-12-20 12:09:49 -0800299
Han Shene4b6f222013-11-22 10:02:38 -0800300
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700301@contextmanager
302def WorkingDirectory(new_dir):
Ahmad Sharif4467f002012-12-20 12:09:49 -0800303 """Get the working directory."""
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700304 old_dir = os.getcwd()
305 if old_dir != new_dir:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800306 msg = 'cd %s' % new_dir
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700307 logger.GetLogger().LogCmd(msg)
308 os.chdir(new_dir)
309 yield new_dir
310 if old_dir != new_dir:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800311 msg = 'cd %s' % old_dir
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700312 logger.GetLogger().LogCmd(msg)
313 os.chdir(old_dir)
Han Shen91445322013-03-20 13:43:31 -0700314
Han Shene4b6f222013-11-22 10:02:38 -0800315
Han Shen91445322013-03-20 13:43:31 -0700316def HasGitStagedChanges(git_dir):
317 """Return True if git repository has staged changes."""
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800318 command = 'cd {0} && git diff --quiet --cached --exit-code HEAD'.format(
Han Shene4b6f222013-11-22 10:02:38 -0800319 git_dir)
Han Shen91445322013-03-20 13:43:31 -0700320 return command_executer.GetCommandExecuter().RunCommand(
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800321 command,
322 print_to_console=False)
Han Shene4b6f222013-11-22 10:02:38 -0800323
Han Shen91445322013-03-20 13:43:31 -0700324
325def HasGitUnstagedChanges(git_dir):
326 """Return True if git repository has un-staged changes."""
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800327 command = 'cd {0} && git diff --quiet --exit-code HEAD'.format(git_dir)
Han Shen91445322013-03-20 13:43:31 -0700328 return command_executer.GetCommandExecuter().RunCommand(
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800329 command,
330 print_to_console=False)
Han Shene4b6f222013-11-22 10:02:38 -0800331
Han Shen91445322013-03-20 13:43:31 -0700332
333def HasGitUntrackedChanges(git_dir):
334 """Return True if git repository has un-tracked changes."""
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800335 command = ('cd {0} && test -z '
336 '$(git ls-files --exclude-standard --others)').format(git_dir)
Han Shen91445322013-03-20 13:43:31 -0700337 return command_executer.GetCommandExecuter().RunCommand(
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800338 command,
339 print_to_console=False)
Han Shene4b6f222013-11-22 10:02:38 -0800340
Han Shen91445322013-03-20 13:43:31 -0700341
Han Shen819f8622014-04-08 16:57:38 -0700342def GitGetCommitHash(git_dir, commit_symbolic_name):
343 """Return githash for the symbolic git commit.
344
345 For example, commit_symbolic_name could be
346 "cros/gcc.gnu.org/branches/gcc/gcc-4_8-mobile, this function returns the git
347 hash for this symbolic name.
348
349 Args:
350 git_dir: a git working tree.
351 commit_symbolic_name: a symbolic name for a particular git commit.
Rahul Chaudhry30840d72016-01-29 13:13:18 -0800352
Han Shen819f8622014-04-08 16:57:38 -0700353 Returns:
354 The git hash for the symbolic name or None if fails.
355 """
356
357 command = ('cd {0} && git log -n 1 --pretty="format:%H" {1}').format(
358 git_dir, commit_symbolic_name)
Luis Lozano036c9232015-12-10 10:47:01 -0800359 rv, out, _ = command_executer.GetCommandExecuter().RunCommandWOutput(
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800360 command,
361 print_to_console=False)
Han Shen819f8622014-04-08 16:57:38 -0700362 if rv == 0:
363 return out.strip()
364 return None
365
366
Han Shen91445322013-03-20 13:43:31 -0700367def IsGitTreeClean(git_dir):
Han Shene4b6f222013-11-22 10:02:38 -0800368 """Test if git tree has no local changes.
369
370 Args:
371 git_dir: git tree directory.
Rahul Chaudhry30840d72016-01-29 13:13:18 -0800372
Han Shene4b6f222013-11-22 10:02:38 -0800373 Returns:
374 True if git dir is clean.
375 """
Han Shen91445322013-03-20 13:43:31 -0700376 if HasGitStagedChanges(git_dir):
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800377 logger.GetLogger().LogWarning('Git tree has staged changes.')
Han Shen91445322013-03-20 13:43:31 -0700378 return False
379 if HasGitUnstagedChanges(git_dir):
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800380 logger.GetLogger().LogWarning('Git tree has unstaged changes.')
Han Shen91445322013-03-20 13:43:31 -0700381 return False
382 if HasGitUntrackedChanges(git_dir):
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800383 logger.GetLogger().LogWarning('Git tree has un-tracked changes.')
Han Shen91445322013-03-20 13:43:31 -0700384 return False
385 return True
386
Han Shene4b6f222013-11-22 10:02:38 -0800387
Han Shen91445322013-03-20 13:43:31 -0700388def GetGitChangesAsList(git_dir, path=None, staged=False):
Han Shene4b6f222013-11-22 10:02:38 -0800389 """Get changed files as a list.
390
391 Args:
392 git_dir: git tree directory.
393 path: a relative path that is part of the tree directory, could be null.
394 staged: whether to include staged files as well.
Rahul Chaudhry30840d72016-01-29 13:13:18 -0800395
Han Shene4b6f222013-11-22 10:02:38 -0800396 Returns:
397 A list containing all the changed files.
398 """
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800399 command = 'cd {0} && git diff --name-only'.format(git_dir)
Han Shen91445322013-03-20 13:43:31 -0700400 if staged:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800401 command += ' --cached'
Han Shen91445322013-03-20 13:43:31 -0700402 if path:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800403 command += ' -- ' + path
Luis Lozano036c9232015-12-10 10:47:01 -0800404 _, out, _ = command_executer.GetCommandExecuter().RunCommandWOutput(
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800405 command,
406 print_to_console=False)
Han Shen91445322013-03-20 13:43:31 -0700407 rv = []
408 for line in out.splitlines():
409 rv.append(line)
410 return rv
Han Shene4b6f222013-11-22 10:02:38 -0800411
412
413def IsChromeOsTree(chromeos_root):
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800414 return (os.path.isdir(os.path.join(chromeos_root,
415 'src/third_party/chromiumos-overlay')) and
416 os.path.isdir(os.path.join(chromeos_root, 'manifest')))
Han Shene4b6f222013-11-22 10:02:38 -0800417
418
419def DeleteChromeOsTree(chromeos_root, dry_run=False):
420 """Delete a ChromeOs tree *safely*.
421
422 Args:
423 chromeos_root: dir of the tree, could be a relative one (but be careful)
424 dry_run: only prints out the command if True
425
426 Returns:
427 True if everything is ok.
428 """
429 if not IsChromeOsTree(chromeos_root):
430 logger.GetLogger().LogWarning(
431 '"{0}" does not seem to be a valid chromeos tree, do nothing.'.format(
432 chromeos_root))
433 return False
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800434 cmd0 = 'cd {0} && cros_sdk --delete'.format(chromeos_root)
Han Shene4b6f222013-11-22 10:02:38 -0800435 if dry_run:
Rahul Chaudhrycbc5a262015-12-30 17:05:14 -0800436 print(cmd0)
Han Shene4b6f222013-11-22 10:02:38 -0800437 else:
438 if command_executer.GetCommandExecuter().RunCommand(
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800439 cmd0,
440 print_to_console=True) != 0:
Han Shene4b6f222013-11-22 10:02:38 -0800441 return False
442
443 cmd1 = ('export CHROMEOSDIRNAME="$(dirname $(cd {0} && pwd))" && '
444 'export CHROMEOSBASENAME="$(basename $(cd {0} && pwd))" && '
445 'cd $CHROMEOSDIRNAME && sudo rm -fr $CHROMEOSBASENAME').format(
446 chromeos_root)
447 if dry_run:
Rahul Chaudhrycbc5a262015-12-30 17:05:14 -0800448 print(cmd1)
Han Shene4b6f222013-11-22 10:02:38 -0800449 return True
450
451 return command_executer.GetCommandExecuter().RunCommand(
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800452 cmd1,
453 print_to_console=True) == 0
Han Shencc34c222014-01-03 11:39:39 -0800454
455
456def ApplyGerritPatches(chromeos_root,
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800457 gerrit_patch_string,
458 branch='cros/master'):
Han Shencc34c222014-01-03 11:39:39 -0800459 """Apply gerrit patches on a chromeos tree.
460
461 Args:
462 chromeos_root: chromeos tree path
463 gerrit_patch_string: a patch string just like the one gives to cbuildbot,
464 'id1 id2 *id3 ... idn'. A prefix of '* means this is an internal patch.
465 branch: the tree based on which to apply the patches.
Rahul Chaudhry30840d72016-01-29 13:13:18 -0800466
Han Shencc34c222014-01-03 11:39:39 -0800467 Returns:
468 True if success.
469 """
470
471 ### First of all, we need chromite libs
472 sys.path.append(os.path.join(chromeos_root, 'chromite'))
Rahul Chaudhryeff2fc12016-02-24 10:12:43 -0800473 # Imports below are ok after modifying path to add chromite.
474 # Pylint cannot detect that and complains.
475 # pylint: disable=import-error
Han Shencc34c222014-01-03 11:39:39 -0800476 from lib import git
477 from lib import gerrit
478 manifest = git.ManifestCheckout(chromeos_root)
479 patch_list = gerrit_patch_string.split(' ')
480 ### This takes time, print log information.
481 logger.GetLogger().LogOutput('Retrieving patch information from server ...')
482 patch_info_list = gerrit.GetGerritPatchInfo(patch_list)
483 for pi in patch_info_list:
484 project_checkout = manifest.FindCheckout(pi.project, strict=False)
485 if not project_checkout:
486 logger.GetLogger().LogError(
487 'Failed to find patch project "{project}" in manifest.'.format(
488 project=pi.project))
489 return False
490
491 pi_str = '{project}:{ref}'.format(project=pi.project, ref=pi.ref)
492 try:
493 project_git_path = project_checkout.GetPath(absolute=True)
494 logger.GetLogger().LogOutput('Applying patch "{0}" in "{1}" ...'.format(
495 pi_str, project_git_path))
496 pi.Apply(project_git_path, branch, trivial=False)
497 except Exception:
498 traceback.print_exc(file=sys.stdout)
499 logger.GetLogger().LogError('Failed to apply patch "{0}"'.format(pi_str))
500 return False
501 return True
cmtice5c09fc22015-04-22 09:25:53 -0700502
503
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800504def BooleanPrompt(prompt='Do you want to continue?',
505 default=True,
506 true_value='yes',
507 false_value='no',
508 prolog=None):
cmtice5c09fc22015-04-22 09:25:53 -0700509 """Helper function for processing boolean choice prompts.
510
511 Args:
512 prompt: The question to present to the user.
513 default: Boolean to return if the user just presses enter.
514 true_value: The text to display that represents a True returned.
515 false_value: The text to display that represents a False returned.
516 prolog: The text to display before prompt.
517
518 Returns:
519 True or False.
520 """
521 true_value, false_value = true_value.lower(), false_value.lower()
522 true_text, false_text = true_value, false_value
523 if true_value == false_value:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800524 raise ValueError('true_value and false_value must differ: got %r' %
525 true_value)
cmtice5c09fc22015-04-22 09:25:53 -0700526
527 if default:
528 true_text = true_text[0].upper() + true_text[1:]
529 else:
530 false_text = false_text[0].upper() + false_text[1:]
531
532 prompt = ('\n%s (%s/%s)? ' % (prompt, true_text, false_text))
533
534 if prolog:
535 prompt = ('\n%s\n%s' % (prolog, prompt))
536
537 while True:
538 try:
539 response = raw_input(prompt).lower()
540 except EOFError:
541 # If the user hits CTRL+D, or stdin is disabled, use the default.
542 print()
543 response = None
544 except KeyboardInterrupt:
545 # If the user hits CTRL+C, just exit the process.
546 print()
Rahul Chaudhryeff2fc12016-02-24 10:12:43 -0800547 print('CTRL+C detected; exiting')
548 sys.exit()
cmtice5c09fc22015-04-22 09:25:53 -0700549
550 if not response:
551 return default
552 if true_value.startswith(response):
553 if not false_value.startswith(response):
554 return True
555 # common prefix between the two...
556 elif false_value.startswith(response):
557 return False