1*760c253cSXin Li# -*- coding: utf-8 -*- 2*760c253cSXin Li# Copyright 2013 The ChromiumOS Authors 3*760c253cSXin Li# Use of this source code is governed by a BSD-style license that can be 4*760c253cSXin Li# found in the LICENSE file. 5*760c253cSXin Li 6*760c253cSXin Li"""Utilities for toolchain build.""" 7*760c253cSXin Li 8*760c253cSXin Li 9*760c253cSXin Li__author__ = "[email protected] (Ahmad Sharif)" 10*760c253cSXin Li 11*760c253cSXin Lifrom contextlib import contextmanager 12*760c253cSXin Liimport os 13*760c253cSXin Liimport re 14*760c253cSXin Liimport shutil 15*760c253cSXin Liimport sys 16*760c253cSXin Li 17*760c253cSXin Lifrom cros_utils import command_executer 18*760c253cSXin Lifrom cros_utils import logger 19*760c253cSXin Li 20*760c253cSXin Li 21*760c253cSXin LiCHROMEOS_SCRIPTS_DIR = "/mnt/host/source/src/scripts" 22*760c253cSXin LiTOOLCHAIN_UTILS_PATH = ( 23*760c253cSXin Li "/mnt/host/source/src/third_party/toolchain-utils/" 24*760c253cSXin Li "cros_utils/toolchain_utils.sh" 25*760c253cSXin Li) 26*760c253cSXin Li 27*760c253cSXin Li 28*760c253cSXin Lidef GetChromeOSVersionFromLSBVersion(lsb_version): 29*760c253cSXin Li """Get Chromeos version from Lsb version.""" 30*760c253cSXin Li ce = command_executer.GetCommandExecuter() 31*760c253cSXin Li command = ( 32*760c253cSXin Li "git ls-remote " 33*760c253cSXin Li "https://chromium.googlesource.com/chromiumos/manifest.git " 34*760c253cSXin Li "refs/heads/release-R*" 35*760c253cSXin Li ) 36*760c253cSXin Li ret, out, _ = ce.RunCommandWOutput(command, print_to_console=False) 37*760c253cSXin Li assert ret == 0, "Command %s failed" % command 38*760c253cSXin Li lower = [] 39*760c253cSXin Li for line in out.splitlines(): 40*760c253cSXin Li mo = re.search(r"refs/heads/release-R(\d+)-(\d+)\.B", line) 41*760c253cSXin Li if mo: 42*760c253cSXin Li revision = int(mo.group(1)) 43*760c253cSXin Li build = int(mo.group(2)) 44*760c253cSXin Li lsb_build = int(lsb_version.split(".")[0]) 45*760c253cSXin Li if lsb_build > build: 46*760c253cSXin Li lower.append(revision) 47*760c253cSXin Li lower = sorted(lower) 48*760c253cSXin Li if lower: 49*760c253cSXin Li return "R%d-%s" % (lower[-1] + 1, lsb_version) 50*760c253cSXin Li else: 51*760c253cSXin Li return "Unknown" 52*760c253cSXin Li 53*760c253cSXin Li 54*760c253cSXin Lidef ApplySubs(string, *substitutions): 55*760c253cSXin Li for pattern, replacement in substitutions: 56*760c253cSXin Li string = re.sub(pattern, replacement, string) 57*760c253cSXin Li return string 58*760c253cSXin Li 59*760c253cSXin Li 60*760c253cSXin Lidef UnitToNumber(unit_num, base=1000): 61*760c253cSXin Li """Convert a number with unit to float.""" 62*760c253cSXin Li unit_dict = {"kilo": base, "mega": base**2, "giga": base**3} 63*760c253cSXin Li unit_num = unit_num.lower() 64*760c253cSXin Li mo = re.search(r"(\d*)(.+)?", unit_num) 65*760c253cSXin Li number = mo.group(1) 66*760c253cSXin Li unit = mo.group(2) 67*760c253cSXin Li if not unit: 68*760c253cSXin Li return float(number) 69*760c253cSXin Li for k, v in unit_dict.items(): 70*760c253cSXin Li if k.startswith(unit): 71*760c253cSXin Li return float(number) * v 72*760c253cSXin Li raise RuntimeError("Unit: %s not found in byte: %s!" % (unit, unit_num)) 73*760c253cSXin Li 74*760c253cSXin Li 75*760c253cSXin Lidef GetFilenameFromString(string): 76*760c253cSXin Li return ApplySubs( 77*760c253cSXin Li string, 78*760c253cSXin Li (r"/", "__"), 79*760c253cSXin Li (r"\s", "_"), 80*760c253cSXin Li (r'[\\$="?^]', ""), 81*760c253cSXin Li ) 82*760c253cSXin Li 83*760c253cSXin Li 84*760c253cSXin Lidef GetRoot(scr_name): 85*760c253cSXin Li """Break up pathname into (dir+name).""" 86*760c253cSXin Li abs_path = os.path.abspath(scr_name) 87*760c253cSXin Li return (os.path.dirname(abs_path), os.path.basename(abs_path)) 88*760c253cSXin Li 89*760c253cSXin Li 90*760c253cSXin Lidef GetChromeOSKeyFile(chromeos_root): 91*760c253cSXin Li return os.path.join( 92*760c253cSXin Li chromeos_root, 93*760c253cSXin Li "chromite", 94*760c253cSXin Li "ssh_keys", 95*760c253cSXin Li "testing_rsa", 96*760c253cSXin Li ) 97*760c253cSXin Li 98*760c253cSXin Li 99*760c253cSXin Lidef GetInsideChrootPath(chromeos_root, file_path): 100*760c253cSXin Li sys.path.insert(0, chromeos_root) 101*760c253cSXin Li 102*760c253cSXin Li from chromite.lib import path_util 103*760c253cSXin Li 104*760c253cSXin Li return path_util.ToChrootPath(path=file_path, source_path=chromeos_root) 105*760c253cSXin Li 106*760c253cSXin Li 107*760c253cSXin Lidef GetOutsideChrootPath(chromeos_root, file_path): 108*760c253cSXin Li sys.path.insert(0, chromeos_root) 109*760c253cSXin Li 110*760c253cSXin Li from chromite.lib import path_util 111*760c253cSXin Li 112*760c253cSXin Li return path_util.FromChrootPath(path=file_path, source_path=chromeos_root) 113*760c253cSXin Li 114*760c253cSXin Li 115*760c253cSXin Lidef FormatQuotedCommand(command): 116*760c253cSXin Li return ApplySubs(command, ('"', r"\"")) 117*760c253cSXin Li 118*760c253cSXin Li 119*760c253cSXin Lidef FormatCommands(commands): 120*760c253cSXin Li return ApplySubs( 121*760c253cSXin Li str(commands), ("&&", "&&\n"), (";", ";\n"), (r"\n+\s*", "\n") 122*760c253cSXin Li ) 123*760c253cSXin Li 124*760c253cSXin Li 125*760c253cSXin Lidef GetImageDir(chromeos_root, board): 126*760c253cSXin Li return GetOutsideChrootPath( 127*760c253cSXin Li chromeos_root, 128*760c253cSXin Li os.path.join(chromeos_root, "src", "build", "images", board), 129*760c253cSXin Li ) 130*760c253cSXin Li 131*760c253cSXin Li 132*760c253cSXin Lidef LabelLatestImage(chromeos_root, board, label, vanilla_path=None): 133*760c253cSXin Li image_dir = GetImageDir(chromeos_root, board) 134*760c253cSXin Li latest_image_dir = os.path.join(image_dir, "latest") 135*760c253cSXin Li latest_image_dir = os.path.realpath(latest_image_dir) 136*760c253cSXin Li latest_image_dir = os.path.basename(latest_image_dir) 137*760c253cSXin Li retval = 0 138*760c253cSXin Li with WorkingDirectory(image_dir): 139*760c253cSXin Li command = "ln -sf -T %s %s" % (latest_image_dir, label) 140*760c253cSXin Li ce = command_executer.GetCommandExecuter() 141*760c253cSXin Li retval = ce.RunCommand(command) 142*760c253cSXin Li if retval: 143*760c253cSXin Li return retval 144*760c253cSXin Li if vanilla_path: 145*760c253cSXin Li command = "ln -sf -T %s %s" % (vanilla_path, "vanilla") 146*760c253cSXin Li retval2 = ce.RunCommand(command) 147*760c253cSXin Li return retval2 148*760c253cSXin Li return retval 149*760c253cSXin Li 150*760c253cSXin Li 151*760c253cSXin Lidef DoesLabelExist(chromeos_root, board, label): 152*760c253cSXin Li image_label = os.path.join(GetImageDir(chromeos_root, board), label) 153*760c253cSXin Li return os.path.exists(image_label) 154*760c253cSXin Li 155*760c253cSXin Li 156*760c253cSXin Lidef GetBuildPackagesCommand(board, usepkg=False, debug=False): 157*760c253cSXin Li if usepkg: 158*760c253cSXin Li usepkg_flag = "--usepkg" 159*760c253cSXin Li else: 160*760c253cSXin Li usepkg_flag = "--nousepkg" 161*760c253cSXin Li if debug: 162*760c253cSXin Li withdebug_flag = "--withdebug" 163*760c253cSXin Li else: 164*760c253cSXin Li withdebug_flag = "--nowithdebug" 165*760c253cSXin Li return ( 166*760c253cSXin Li "%s/build_packages %s --withdev --withtest --withautotest " 167*760c253cSXin Li "--skip_toolchain_update %s --board=%s " 168*760c253cSXin Li "--accept_licenses=@CHROMEOS" 169*760c253cSXin Li % (CHROMEOS_SCRIPTS_DIR, usepkg_flag, withdebug_flag, board) 170*760c253cSXin Li ) 171*760c253cSXin Li 172*760c253cSXin Li 173*760c253cSXin Lidef GetBuildImageCommand(board, dev=False): 174*760c253cSXin Li dev_args = "" 175*760c253cSXin Li if dev: 176*760c253cSXin Li dev_args = "--noenable_rootfs_verification --disk_layout=2gb-rootfs" 177*760c253cSXin Li return "%s/build_image --board=%s %s test" % ( 178*760c253cSXin Li CHROMEOS_SCRIPTS_DIR, 179*760c253cSXin Li board, 180*760c253cSXin Li dev_args, 181*760c253cSXin Li ) 182*760c253cSXin Li 183*760c253cSXin Li 184*760c253cSXin Lidef GetSetupBoardCommand(board, usepkg=None, force=None): 185*760c253cSXin Li """Get setup_board command.""" 186*760c253cSXin Li options = [] 187*760c253cSXin Li 188*760c253cSXin Li if usepkg: 189*760c253cSXin Li options.append("--usepkg") 190*760c253cSXin Li else: 191*760c253cSXin Li options.append("--nousepkg") 192*760c253cSXin Li 193*760c253cSXin Li if force: 194*760c253cSXin Li options.append("--force") 195*760c253cSXin Li 196*760c253cSXin Li options.append("--accept-licenses=@CHROMEOS") 197*760c253cSXin Li 198*760c253cSXin Li return "setup_board --board=%s %s" % (board, " ".join(options)) 199*760c253cSXin Li 200*760c253cSXin Li 201*760c253cSXin Lidef CanonicalizePath(path): 202*760c253cSXin Li path = os.path.expanduser(path) 203*760c253cSXin Li path = os.path.realpath(path) 204*760c253cSXin Li return path 205*760c253cSXin Li 206*760c253cSXin Li 207*760c253cSXin Lidef GetCtargetFromBoard(board, chromeos_root): 208*760c253cSXin Li """Get Ctarget from board.""" 209*760c253cSXin Li base_board = board.split("_")[0] 210*760c253cSXin Li command = "source %s; get_ctarget_from_board %s" % ( 211*760c253cSXin Li TOOLCHAIN_UTILS_PATH, 212*760c253cSXin Li base_board, 213*760c253cSXin Li ) 214*760c253cSXin Li ce = command_executer.GetCommandExecuter() 215*760c253cSXin Li ret, out, _ = ce.ChrootRunCommandWOutput(chromeos_root, command) 216*760c253cSXin Li if ret != 0: 217*760c253cSXin Li raise ValueError("Board %s is invalid!" % board) 218*760c253cSXin Li # Remove ANSI escape sequences. 219*760c253cSXin Li out = StripANSIEscapeSequences(out) 220*760c253cSXin Li return out.strip() 221*760c253cSXin Li 222*760c253cSXin Li 223*760c253cSXin Lidef GetArchFromBoard(board, chromeos_root): 224*760c253cSXin Li """Get Arch from board.""" 225*760c253cSXin Li base_board = board.split("_")[0] 226*760c253cSXin Li command = "source %s; get_board_arch %s" % ( 227*760c253cSXin Li TOOLCHAIN_UTILS_PATH, 228*760c253cSXin Li base_board, 229*760c253cSXin Li ) 230*760c253cSXin Li ce = command_executer.GetCommandExecuter() 231*760c253cSXin Li ret, out, _ = ce.ChrootRunCommandWOutput(chromeos_root, command) 232*760c253cSXin Li if ret != 0: 233*760c253cSXin Li raise ValueError("Board %s is invalid!" % board) 234*760c253cSXin Li # Remove ANSI escape sequences. 235*760c253cSXin Li out = StripANSIEscapeSequences(out) 236*760c253cSXin Li return out.strip() 237*760c253cSXin Li 238*760c253cSXin Li 239*760c253cSXin Lidef GetGccLibsDestForBoard(board, chromeos_root): 240*760c253cSXin Li """Get gcc libs destination from board.""" 241*760c253cSXin Li arch = GetArchFromBoard(board, chromeos_root) 242*760c253cSXin Li if arch == "x86": 243*760c253cSXin Li return "/build/%s/usr/lib/gcc/" % board 244*760c253cSXin Li if arch == "amd64": 245*760c253cSXin Li return "/build/%s/usr/lib64/gcc/" % board 246*760c253cSXin Li if arch == "arm": 247*760c253cSXin Li return "/build/%s/usr/lib/gcc/" % board 248*760c253cSXin Li if arch == "arm64": 249*760c253cSXin Li return "/build/%s/usr/lib/gcc/" % board 250*760c253cSXin Li raise ValueError("Arch %s is invalid!" % arch) 251*760c253cSXin Li 252*760c253cSXin Li 253*760c253cSXin Lidef StripANSIEscapeSequences(string): 254*760c253cSXin Li string = re.sub(r"\x1b\[[0-9]*[a-zA-Z]", "", string) 255*760c253cSXin Li return string 256*760c253cSXin Li 257*760c253cSXin Li 258*760c253cSXin Lidef GetChromeSrcDir(): 259*760c253cSXin Li return "var/cache/distfiles/target/chrome-src/src" 260*760c253cSXin Li 261*760c253cSXin Li 262*760c253cSXin Lidef GetEnvStringFromDict(env_dict): 263*760c253cSXin Li return " ".join(['%s="%s"' % var for var in env_dict.items()]) 264*760c253cSXin Li 265*760c253cSXin Li 266*760c253cSXin Lidef MergeEnvStringWithDict(env_string, env_dict, prepend=True): 267*760c253cSXin Li """Merge env string with dict.""" 268*760c253cSXin Li if not env_string.strip(): 269*760c253cSXin Li return GetEnvStringFromDict(env_dict) 270*760c253cSXin Li override_env_list = [] 271*760c253cSXin Li ce = command_executer.GetCommandExecuter() 272*760c253cSXin Li for k, v in env_dict.items(): 273*760c253cSXin Li v = v.strip("\"'") 274*760c253cSXin Li if prepend: 275*760c253cSXin Li new_env = '%s="%s $%s"' % (k, v, k) 276*760c253cSXin Li else: 277*760c253cSXin Li new_env = '%s="$%s %s"' % (k, k, v) 278*760c253cSXin Li command = "; ".join([env_string, new_env, "echo $%s" % k]) 279*760c253cSXin Li ret, out, _ = ce.RunCommandWOutput(command) 280*760c253cSXin Li override_env_list.append("%s=%r" % (k, out.strip())) 281*760c253cSXin Li ret = env_string + " " + " ".join(override_env_list) 282*760c253cSXin Li return ret.strip() 283*760c253cSXin Li 284*760c253cSXin Li 285*760c253cSXin Lidef GetAllImages(chromeos_root, board): 286*760c253cSXin Li ce = command_executer.GetCommandExecuter() 287*760c253cSXin Li command = "find %s/src/build/images/%s -name chromiumos_test_image.bin" % ( 288*760c253cSXin Li chromeos_root, 289*760c253cSXin Li board, 290*760c253cSXin Li ) 291*760c253cSXin Li ret, out, _ = ce.RunCommandWOutput(command) 292*760c253cSXin Li assert ret == 0, "Could not run command: %s" % command 293*760c253cSXin Li return out.splitlines() 294*760c253cSXin Li 295*760c253cSXin Li 296*760c253cSXin Lidef IsFloat(text): 297*760c253cSXin Li if text is None: 298*760c253cSXin Li return False 299*760c253cSXin Li try: 300*760c253cSXin Li float(text) 301*760c253cSXin Li return True 302*760c253cSXin Li except ValueError: 303*760c253cSXin Li return False 304*760c253cSXin Li 305*760c253cSXin Li 306*760c253cSXin Lidef RemoveChromeBrowserObjectFiles(chromeos_root, board): 307*760c253cSXin Li """Remove any object files from all the posible locations.""" 308*760c253cSXin Li out_dir = GetOutsideChrootPath( 309*760c253cSXin Li chromeos_root, 310*760c253cSXin Li "/var/cache/chromeos-chrome/chrome-src/src/out_%s" % board, 311*760c253cSXin Li ) 312*760c253cSXin Li if os.path.exists(out_dir): 313*760c253cSXin Li shutil.rmtree(out_dir) 314*760c253cSXin Li logger.GetLogger().LogCmd("rm -rf %s" % out_dir) 315*760c253cSXin Li out_dir = GetOutsideChrootPath( 316*760c253cSXin Li chromeos_root, 317*760c253cSXin Li "/var/cache/chromeos-chrome/chrome-src-internal/src/out_%s" % board, 318*760c253cSXin Li ) 319*760c253cSXin Li if os.path.exists(out_dir): 320*760c253cSXin Li shutil.rmtree(out_dir) 321*760c253cSXin Li logger.GetLogger().LogCmd("rm -rf %s" % out_dir) 322*760c253cSXin Li 323*760c253cSXin Li 324*760c253cSXin Li@contextmanager 325*760c253cSXin Lidef WorkingDirectory(new_dir): 326*760c253cSXin Li """Get the working directory.""" 327*760c253cSXin Li old_dir = os.getcwd() 328*760c253cSXin Li if old_dir != new_dir: 329*760c253cSXin Li msg = "cd %s" % new_dir 330*760c253cSXin Li logger.GetLogger().LogCmd(msg) 331*760c253cSXin Li os.chdir(new_dir) 332*760c253cSXin Li yield new_dir 333*760c253cSXin Li if old_dir != new_dir: 334*760c253cSXin Li msg = "cd %s" % old_dir 335*760c253cSXin Li logger.GetLogger().LogCmd(msg) 336*760c253cSXin Li os.chdir(old_dir) 337*760c253cSXin Li 338*760c253cSXin Li 339*760c253cSXin Lidef HasGitStagedChanges(git_dir): 340*760c253cSXin Li """Return True if git repository has staged changes.""" 341*760c253cSXin Li command = f"cd {git_dir} && git diff --quiet --cached --exit-code HEAD" 342*760c253cSXin Li return command_executer.GetCommandExecuter().RunCommand( 343*760c253cSXin Li command, print_to_console=False 344*760c253cSXin Li ) 345*760c253cSXin Li 346*760c253cSXin Li 347*760c253cSXin Lidef HasGitUnstagedChanges(git_dir): 348*760c253cSXin Li """Return True if git repository has un-staged changes.""" 349*760c253cSXin Li command = f"cd {git_dir} && git diff --quiet --exit-code HEAD" 350*760c253cSXin Li return command_executer.GetCommandExecuter().RunCommand( 351*760c253cSXin Li command, print_to_console=False 352*760c253cSXin Li ) 353*760c253cSXin Li 354*760c253cSXin Li 355*760c253cSXin Lidef HasGitUntrackedChanges(git_dir): 356*760c253cSXin Li """Return True if git repository has un-tracked changes.""" 357*760c253cSXin Li command = ( 358*760c253cSXin Li f"cd {git_dir} && test -z " 359*760c253cSXin Li "$(git ls-files --exclude-standard --others)" 360*760c253cSXin Li ) 361*760c253cSXin Li return command_executer.GetCommandExecuter().RunCommand( 362*760c253cSXin Li command, print_to_console=False 363*760c253cSXin Li ) 364*760c253cSXin Li 365*760c253cSXin Li 366*760c253cSXin Lidef GitGetCommitHash(git_dir, commit_symbolic_name): 367*760c253cSXin Li """Return githash for the symbolic git commit. 368*760c253cSXin Li 369*760c253cSXin Li For example, commit_symbolic_name could be 370*760c253cSXin Li "cros/gcc.gnu.org/branches/gcc/gcc-4_8-mobile, this function returns the git 371*760c253cSXin Li hash for this symbolic name. 372*760c253cSXin Li 373*760c253cSXin Li Args: 374*760c253cSXin Li git_dir: a git working tree. 375*760c253cSXin Li commit_symbolic_name: a symbolic name for a particular git commit. 376*760c253cSXin Li 377*760c253cSXin Li Returns: 378*760c253cSXin Li The git hash for the symbolic name or None if fails. 379*760c253cSXin Li """ 380*760c253cSXin Li 381*760c253cSXin Li command = ( 382*760c253cSXin Li f"cd {git_dir} && git log -n 1" 383*760c253cSXin Li f' --pretty="format:%H" {commit_symbolic_name}' 384*760c253cSXin Li ) 385*760c253cSXin Li rv, out, _ = command_executer.GetCommandExecuter().RunCommandWOutput( 386*760c253cSXin Li command, print_to_console=False 387*760c253cSXin Li ) 388*760c253cSXin Li if rv == 0: 389*760c253cSXin Li return out.strip() 390*760c253cSXin Li return None 391*760c253cSXin Li 392*760c253cSXin Li 393*760c253cSXin Lidef IsGitTreeClean(git_dir): 394*760c253cSXin Li """Test if git tree has no local changes. 395*760c253cSXin Li 396*760c253cSXin Li Args: 397*760c253cSXin Li git_dir: git tree directory. 398*760c253cSXin Li 399*760c253cSXin Li Returns: 400*760c253cSXin Li True if git dir is clean. 401*760c253cSXin Li """ 402*760c253cSXin Li if HasGitStagedChanges(git_dir): 403*760c253cSXin Li logger.GetLogger().LogWarning("Git tree has staged changes.") 404*760c253cSXin Li return False 405*760c253cSXin Li if HasGitUnstagedChanges(git_dir): 406*760c253cSXin Li logger.GetLogger().LogWarning("Git tree has unstaged changes.") 407*760c253cSXin Li return False 408*760c253cSXin Li if HasGitUntrackedChanges(git_dir): 409*760c253cSXin Li logger.GetLogger().LogWarning("Git tree has un-tracked changes.") 410*760c253cSXin Li return False 411*760c253cSXin Li return True 412*760c253cSXin Li 413*760c253cSXin Li 414*760c253cSXin Lidef GetGitChangesAsList(git_dir, path=None, staged=False): 415*760c253cSXin Li """Get changed files as a list. 416*760c253cSXin Li 417*760c253cSXin Li Args: 418*760c253cSXin Li git_dir: git tree directory. 419*760c253cSXin Li path: a relative path that is part of the tree directory, could be null. 420*760c253cSXin Li staged: whether to include staged files as well. 421*760c253cSXin Li 422*760c253cSXin Li Returns: 423*760c253cSXin Li A list containing all the changed files. 424*760c253cSXin Li """ 425*760c253cSXin Li command = f"cd {git_dir} && git diff --name-only" 426*760c253cSXin Li if staged: 427*760c253cSXin Li command += " --cached" 428*760c253cSXin Li if path: 429*760c253cSXin Li command += " -- " + path 430*760c253cSXin Li _, out, _ = command_executer.GetCommandExecuter().RunCommandWOutput( 431*760c253cSXin Li command, print_to_console=False 432*760c253cSXin Li ) 433*760c253cSXin Li rv = [] 434*760c253cSXin Li for line in out.splitlines(): 435*760c253cSXin Li rv.append(line) 436*760c253cSXin Li return rv 437*760c253cSXin Li 438*760c253cSXin Li 439*760c253cSXin Lidef IsChromeOsTree(chromeos_root): 440*760c253cSXin Li return os.path.isdir( 441*760c253cSXin Li os.path.join(chromeos_root, "src/third_party/chromiumos-overlay") 442*760c253cSXin Li ) and os.path.isdir(os.path.join(chromeos_root, "manifest")) 443*760c253cSXin Li 444*760c253cSXin Li 445*760c253cSXin Lidef DeleteChromeOsTree(chromeos_root, dry_run=False): 446*760c253cSXin Li """Delete a ChromeOs tree *safely*. 447*760c253cSXin Li 448*760c253cSXin Li Args: 449*760c253cSXin Li chromeos_root: dir of the tree, could be a relative one (but be careful) 450*760c253cSXin Li dry_run: only prints out the command if True 451*760c253cSXin Li 452*760c253cSXin Li Returns: 453*760c253cSXin Li True if everything is ok. 454*760c253cSXin Li """ 455*760c253cSXin Li if not IsChromeOsTree(chromeos_root): 456*760c253cSXin Li logger.GetLogger().LogWarning( 457*760c253cSXin Li f'"{chromeos_root}" does not seem to be a' 458*760c253cSXin Li " valid chromeos tree, do nothing." 459*760c253cSXin Li ) 460*760c253cSXin Li return False 461*760c253cSXin Li cmd0 = f"cd {chromeos_root} && cros_sdk --delete" 462*760c253cSXin Li if dry_run: 463*760c253cSXin Li print(cmd0) 464*760c253cSXin Li else: 465*760c253cSXin Li if ( 466*760c253cSXin Li command_executer.GetCommandExecuter().RunCommand( 467*760c253cSXin Li cmd0, print_to_console=True 468*760c253cSXin Li ) 469*760c253cSXin Li != 0 470*760c253cSXin Li ): 471*760c253cSXin Li return False 472*760c253cSXin Li 473*760c253cSXin Li cmd1 = ( 474*760c253cSXin Li f'export CHROMEOSDIRNAME="$(dirname $(cd {chromeos_root} && pwd))" && ' 475*760c253cSXin Li f'export CHROMEOSBASENAME="$(basename $(cd {chromeos_root} && pwd))" && ' 476*760c253cSXin Li "cd $CHROMEOSDIRNAME && sudo rm -fr $CHROMEOSBASENAME" 477*760c253cSXin Li ) 478*760c253cSXin Li if dry_run: 479*760c253cSXin Li print(cmd1) 480*760c253cSXin Li return True 481*760c253cSXin Li 482*760c253cSXin Li return ( 483*760c253cSXin Li command_executer.GetCommandExecuter().RunCommand( 484*760c253cSXin Li cmd1, print_to_console=True 485*760c253cSXin Li ) 486*760c253cSXin Li == 0 487*760c253cSXin Li ) 488*760c253cSXin Li 489*760c253cSXin Li 490*760c253cSXin Lidef BooleanPrompt( 491*760c253cSXin Li prompt="Do you want to continue?", 492*760c253cSXin Li default=True, 493*760c253cSXin Li true_value="yes", 494*760c253cSXin Li false_value="no", 495*760c253cSXin Li prolog=None, 496*760c253cSXin Li): 497*760c253cSXin Li """Helper function for processing boolean choice prompts. 498*760c253cSXin Li 499*760c253cSXin Li Args: 500*760c253cSXin Li prompt: The question to present to the user. 501*760c253cSXin Li default: Boolean to return if the user just presses enter. 502*760c253cSXin Li true_value: The text to display that represents a True returned. 503*760c253cSXin Li false_value: The text to display that represents a False returned. 504*760c253cSXin Li prolog: The text to display before prompt. 505*760c253cSXin Li 506*760c253cSXin Li Returns: 507*760c253cSXin Li True or False. 508*760c253cSXin Li """ 509*760c253cSXin Li true_value, false_value = true_value.lower(), false_value.lower() 510*760c253cSXin Li true_text, false_text = true_value, false_value 511*760c253cSXin Li if true_value == false_value: 512*760c253cSXin Li raise ValueError( 513*760c253cSXin Li "true_value and false_value must differ: got %r" % true_value 514*760c253cSXin Li ) 515*760c253cSXin Li 516*760c253cSXin Li if default: 517*760c253cSXin Li true_text = true_text[0].upper() + true_text[1:] 518*760c253cSXin Li else: 519*760c253cSXin Li false_text = false_text[0].upper() + false_text[1:] 520*760c253cSXin Li 521*760c253cSXin Li prompt = "\n%s (%s/%s)? " % (prompt, true_text, false_text) 522*760c253cSXin Li 523*760c253cSXin Li if prolog: 524*760c253cSXin Li prompt = "\n%s\n%s" % (prolog, prompt) 525*760c253cSXin Li 526*760c253cSXin Li while True: 527*760c253cSXin Li try: 528*760c253cSXin Li # pylint: disable=input-builtin, bad-builtin 529*760c253cSXin Li response = input(prompt).lower() 530*760c253cSXin Li except EOFError: 531*760c253cSXin Li # If the user hits CTRL+D, or stdin is disabled, use the default. 532*760c253cSXin Li print() 533*760c253cSXin Li response = None 534*760c253cSXin Li except KeyboardInterrupt: 535*760c253cSXin Li # If the user hits CTRL+C, just exit the process. 536*760c253cSXin Li print() 537*760c253cSXin Li print("CTRL+C detected; exiting") 538*760c253cSXin Li sys.exit() 539*760c253cSXin Li 540*760c253cSXin Li if not response: 541*760c253cSXin Li return default 542*760c253cSXin Li if true_value.startswith(response): 543*760c253cSXin Li if not false_value.startswith(response): 544*760c253cSXin Li return True 545*760c253cSXin Li # common prefix between the two... 546*760c253cSXin Li elif false_value.startswith(response): 547*760c253cSXin Li return False 548*760c253cSXin Li 549*760c253cSXin Li 550*760c253cSXin Li# pylint: disable=unused-argument 551*760c253cSXin Lidef rgb2short(r, g, b): 552*760c253cSXin Li """Converts RGB values to xterm-256 color.""" 553*760c253cSXin Li 554*760c253cSXin Li redcolor = [255, 124, 160, 196, 9] 555*760c253cSXin Li greencolor = [255, 118, 82, 46, 10] 556*760c253cSXin Li 557*760c253cSXin Li if g == 0: 558*760c253cSXin Li return redcolor[r // 52] 559*760c253cSXin Li if r == 0: 560*760c253cSXin Li return greencolor[g // 52] 561*760c253cSXin Li return 4 562