1*9e965d6fSRomain Jobredeaux# Copyright 2018 The Bazel Authors. All rights reserved. 2*9e965d6fSRomain Jobredeaux# 3*9e965d6fSRomain Jobredeaux# Licensed under the Apache License, Version 2.0 (the "License"); 4*9e965d6fSRomain Jobredeaux# you may not use this file except in compliance with the License. 5*9e965d6fSRomain Jobredeaux# You may obtain a copy of the License at 6*9e965d6fSRomain Jobredeaux# 7*9e965d6fSRomain Jobredeaux# http://www.apache.org/licenses/LICENSE-2.0 8*9e965d6fSRomain Jobredeaux# 9*9e965d6fSRomain Jobredeaux# Unless required by applicable law or agreed to in writing, software 10*9e965d6fSRomain Jobredeaux# distributed under the License is distributed on an "AS IS" BASIS, 11*9e965d6fSRomain Jobredeaux# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*9e965d6fSRomain Jobredeaux# See the License for the specific language governing permissions and 13*9e965d6fSRomain Jobredeaux# limitations under the License. 14*9e965d6fSRomain Jobredeaux 15*9e965d6fSRomain Jobredeaux"""Utilities for the Android rules.""" 16*9e965d6fSRomain Jobredeaux 17*9e965d6fSRomain Jobredeauxload(":providers.bzl", "FailureInfo") 18*9e965d6fSRomain Jobredeaux 19*9e965d6fSRomain JobredeauxANDROID_TOOLCHAIN_TYPE = Label("//toolchains/android:toolchain_type") 20*9e965d6fSRomain Jobredeaux 21*9e965d6fSRomain Jobredeaux_CUU = "\033[A" 22*9e965d6fSRomain Jobredeaux_EL = "\033[K" 23*9e965d6fSRomain Jobredeaux_DEFAULT = "\033[0m" 24*9e965d6fSRomain Jobredeaux_BOLD = "\033[1m" 25*9e965d6fSRomain Jobredeaux_RED = "\033[31m" 26*9e965d6fSRomain Jobredeaux_GREEN = "\033[32m" 27*9e965d6fSRomain Jobredeaux_MAGENTA = "\033[35m" 28*9e965d6fSRomain Jobredeaux_ERASE_PREV_LINE = "\n" + _CUU + _EL 29*9e965d6fSRomain Jobredeaux 30*9e965d6fSRomain Jobredeaux_INFO = _ERASE_PREV_LINE + _GREEN + "INFO: " + _DEFAULT + "%s" 31*9e965d6fSRomain Jobredeaux_WARNING = _ERASE_PREV_LINE + _MAGENTA + "WARNING: " + _DEFAULT + "%s" 32*9e965d6fSRomain Jobredeaux_ERROR = _ERASE_PREV_LINE + _BOLD + _RED + "ERROR: " + _DEFAULT + "%s" 33*9e965d6fSRomain Jobredeaux 34*9e965d6fSRomain Jobredeaux_WORD_CHARS = { 35*9e965d6fSRomain Jobredeaux "A": True, 36*9e965d6fSRomain Jobredeaux "B": True, 37*9e965d6fSRomain Jobredeaux "C": True, 38*9e965d6fSRomain Jobredeaux "D": True, 39*9e965d6fSRomain Jobredeaux "E": True, 40*9e965d6fSRomain Jobredeaux "F": True, 41*9e965d6fSRomain Jobredeaux "G": True, 42*9e965d6fSRomain Jobredeaux "H": True, 43*9e965d6fSRomain Jobredeaux "I": True, 44*9e965d6fSRomain Jobredeaux "J": True, 45*9e965d6fSRomain Jobredeaux "K": True, 46*9e965d6fSRomain Jobredeaux "L": True, 47*9e965d6fSRomain Jobredeaux "M": True, 48*9e965d6fSRomain Jobredeaux "N": True, 49*9e965d6fSRomain Jobredeaux "O": True, 50*9e965d6fSRomain Jobredeaux "P": True, 51*9e965d6fSRomain Jobredeaux "Q": True, 52*9e965d6fSRomain Jobredeaux "R": True, 53*9e965d6fSRomain Jobredeaux "S": True, 54*9e965d6fSRomain Jobredeaux "T": True, 55*9e965d6fSRomain Jobredeaux "U": True, 56*9e965d6fSRomain Jobredeaux "V": True, 57*9e965d6fSRomain Jobredeaux "W": True, 58*9e965d6fSRomain Jobredeaux "X": True, 59*9e965d6fSRomain Jobredeaux "Y": True, 60*9e965d6fSRomain Jobredeaux "Z": True, 61*9e965d6fSRomain Jobredeaux "a": True, 62*9e965d6fSRomain Jobredeaux "b": True, 63*9e965d6fSRomain Jobredeaux "c": True, 64*9e965d6fSRomain Jobredeaux "d": True, 65*9e965d6fSRomain Jobredeaux "e": True, 66*9e965d6fSRomain Jobredeaux "f": True, 67*9e965d6fSRomain Jobredeaux "g": True, 68*9e965d6fSRomain Jobredeaux "h": True, 69*9e965d6fSRomain Jobredeaux "i": True, 70*9e965d6fSRomain Jobredeaux "j": True, 71*9e965d6fSRomain Jobredeaux "k": True, 72*9e965d6fSRomain Jobredeaux "l": True, 73*9e965d6fSRomain Jobredeaux "m": True, 74*9e965d6fSRomain Jobredeaux "n": True, 75*9e965d6fSRomain Jobredeaux "o": True, 76*9e965d6fSRomain Jobredeaux "p": True, 77*9e965d6fSRomain Jobredeaux "q": True, 78*9e965d6fSRomain Jobredeaux "r": True, 79*9e965d6fSRomain Jobredeaux "s": True, 80*9e965d6fSRomain Jobredeaux "t": True, 81*9e965d6fSRomain Jobredeaux "u": True, 82*9e965d6fSRomain Jobredeaux "v": True, 83*9e965d6fSRomain Jobredeaux "w": True, 84*9e965d6fSRomain Jobredeaux "x": True, 85*9e965d6fSRomain Jobredeaux "y": True, 86*9e965d6fSRomain Jobredeaux "z": True, 87*9e965d6fSRomain Jobredeaux "0": True, 88*9e965d6fSRomain Jobredeaux "1": True, 89*9e965d6fSRomain Jobredeaux "2": True, 90*9e965d6fSRomain Jobredeaux "3": True, 91*9e965d6fSRomain Jobredeaux "4": True, 92*9e965d6fSRomain Jobredeaux "5": True, 93*9e965d6fSRomain Jobredeaux "6": True, 94*9e965d6fSRomain Jobredeaux "7": True, 95*9e965d6fSRomain Jobredeaux "8": True, 96*9e965d6fSRomain Jobredeaux "9": True, 97*9e965d6fSRomain Jobredeaux "_": True, 98*9e965d6fSRomain Jobredeaux} 99*9e965d6fSRomain Jobredeaux 100*9e965d6fSRomain Jobredeaux_HEX_CHAR = { 101*9e965d6fSRomain Jobredeaux 0x0: "0", 102*9e965d6fSRomain Jobredeaux 0x1: "1", 103*9e965d6fSRomain Jobredeaux 0x2: "2", 104*9e965d6fSRomain Jobredeaux 0x3: "3", 105*9e965d6fSRomain Jobredeaux 0x4: "4", 106*9e965d6fSRomain Jobredeaux 0x5: "5", 107*9e965d6fSRomain Jobredeaux 0x6: "6", 108*9e965d6fSRomain Jobredeaux 0x7: "7", 109*9e965d6fSRomain Jobredeaux 0x8: "8", 110*9e965d6fSRomain Jobredeaux 0x9: "9", 111*9e965d6fSRomain Jobredeaux 0xA: "A", 112*9e965d6fSRomain Jobredeaux 0xB: "B", 113*9e965d6fSRomain Jobredeaux 0xC: "C", 114*9e965d6fSRomain Jobredeaux 0xD: "D", 115*9e965d6fSRomain Jobredeaux 0xE: "E", 116*9e965d6fSRomain Jobredeaux 0xF: "F", 117*9e965d6fSRomain Jobredeaux} 118*9e965d6fSRomain Jobredeaux 119*9e965d6fSRomain Jobredeaux_JAVA_RESERVED = { 120*9e965d6fSRomain Jobredeaux "abstract": True, 121*9e965d6fSRomain Jobredeaux "assert": True, 122*9e965d6fSRomain Jobredeaux "boolean": True, 123*9e965d6fSRomain Jobredeaux "break": True, 124*9e965d6fSRomain Jobredeaux "byte": True, 125*9e965d6fSRomain Jobredeaux "case": True, 126*9e965d6fSRomain Jobredeaux "catch": True, 127*9e965d6fSRomain Jobredeaux "char": True, 128*9e965d6fSRomain Jobredeaux "class": True, 129*9e965d6fSRomain Jobredeaux "const": True, 130*9e965d6fSRomain Jobredeaux "continue": True, 131*9e965d6fSRomain Jobredeaux "default": True, 132*9e965d6fSRomain Jobredeaux "do": True, 133*9e965d6fSRomain Jobredeaux "double": True, 134*9e965d6fSRomain Jobredeaux "else": True, 135*9e965d6fSRomain Jobredeaux "enum": True, 136*9e965d6fSRomain Jobredeaux "extends": True, 137*9e965d6fSRomain Jobredeaux "final": True, 138*9e965d6fSRomain Jobredeaux "finally": True, 139*9e965d6fSRomain Jobredeaux "float": True, 140*9e965d6fSRomain Jobredeaux "for": True, 141*9e965d6fSRomain Jobredeaux "goto": True, 142*9e965d6fSRomain Jobredeaux "if": True, 143*9e965d6fSRomain Jobredeaux "implements": True, 144*9e965d6fSRomain Jobredeaux "import": True, 145*9e965d6fSRomain Jobredeaux "instanceof": True, 146*9e965d6fSRomain Jobredeaux "int": True, 147*9e965d6fSRomain Jobredeaux "interface": True, 148*9e965d6fSRomain Jobredeaux "long": True, 149*9e965d6fSRomain Jobredeaux "native": True, 150*9e965d6fSRomain Jobredeaux "new": True, 151*9e965d6fSRomain Jobredeaux "package": True, 152*9e965d6fSRomain Jobredeaux "private": True, 153*9e965d6fSRomain Jobredeaux "protected": True, 154*9e965d6fSRomain Jobredeaux "public": True, 155*9e965d6fSRomain Jobredeaux "return": True, 156*9e965d6fSRomain Jobredeaux "short": True, 157*9e965d6fSRomain Jobredeaux "static": True, 158*9e965d6fSRomain Jobredeaux "strictfp": True, 159*9e965d6fSRomain Jobredeaux "super": True, 160*9e965d6fSRomain Jobredeaux "switch": True, 161*9e965d6fSRomain Jobredeaux "synchronized": True, 162*9e965d6fSRomain Jobredeaux "this": True, 163*9e965d6fSRomain Jobredeaux "throw": True, 164*9e965d6fSRomain Jobredeaux "throws": True, 165*9e965d6fSRomain Jobredeaux "transient": True, 166*9e965d6fSRomain Jobredeaux "try": True, 167*9e965d6fSRomain Jobredeaux "void": True, 168*9e965d6fSRomain Jobredeaux "volatile": True, 169*9e965d6fSRomain Jobredeaux "while": True, 170*9e965d6fSRomain Jobredeaux "true": True, 171*9e965d6fSRomain Jobredeaux "false": True, 172*9e965d6fSRomain Jobredeaux "null": True, 173*9e965d6fSRomain Jobredeaux} 174*9e965d6fSRomain Jobredeaux 175*9e965d6fSRomain Jobredeauxdef _collect_providers(provider, *all_deps): 176*9e965d6fSRomain Jobredeaux """Collects the requested providers from the given list of deps.""" 177*9e965d6fSRomain Jobredeaux providers = [] 178*9e965d6fSRomain Jobredeaux for deps in all_deps: 179*9e965d6fSRomain Jobredeaux for dep in deps: 180*9e965d6fSRomain Jobredeaux if provider in dep: 181*9e965d6fSRomain Jobredeaux providers.append(dep[provider]) 182*9e965d6fSRomain Jobredeaux return providers 183*9e965d6fSRomain Jobredeaux 184*9e965d6fSRomain Jobredeauxdef _join_depsets(providers, attr, order = "default"): 185*9e965d6fSRomain Jobredeaux """Returns a merged depset using 'attr' from each provider in 'providers'.""" 186*9e965d6fSRomain Jobredeaux return depset(transitive = [getattr(p, attr) for p in providers], order = order) 187*9e965d6fSRomain Jobredeaux 188*9e965d6fSRomain Jobredeauxdef _first(collection): 189*9e965d6fSRomain Jobredeaux """Returns the first item in the collection.""" 190*9e965d6fSRomain Jobredeaux for i in collection: 191*9e965d6fSRomain Jobredeaux return i 192*9e965d6fSRomain Jobredeaux return _error("The collection is empty.") 193*9e965d6fSRomain Jobredeaux 194*9e965d6fSRomain Jobredeauxdef _only(collection): 195*9e965d6fSRomain Jobredeaux """Returns the only item in the collection.""" 196*9e965d6fSRomain Jobredeaux if len(collection) != 1: 197*9e965d6fSRomain Jobredeaux _error("Expected one element, has %s." % len(collection)) 198*9e965d6fSRomain Jobredeaux return _first(collection) 199*9e965d6fSRomain Jobredeaux 200*9e965d6fSRomain Jobredeauxdef _list_or_depset_to_list(list_or_depset): 201*9e965d6fSRomain Jobredeaux if type(list_or_depset) == "list": 202*9e965d6fSRomain Jobredeaux return list_or_depset 203*9e965d6fSRomain Jobredeaux elif type(list_or_depset) == "depset": 204*9e965d6fSRomain Jobredeaux return list_or_depset.to_list() 205*9e965d6fSRomain Jobredeaux else: 206*9e965d6fSRomain Jobredeaux return _error("Expected a list or a depset. Got %s" % type(list_or_depset)) 207*9e965d6fSRomain Jobredeaux 208*9e965d6fSRomain Jobredeauxdef _copy_file(ctx, src, dest): 209*9e965d6fSRomain Jobredeaux if src.is_directory or dest.is_directory: 210*9e965d6fSRomain Jobredeaux fail("Cannot use copy_file with directories") 211*9e965d6fSRomain Jobredeaux ctx.actions.run_shell( 212*9e965d6fSRomain Jobredeaux command = "cp --reflink=auto $1 $2", 213*9e965d6fSRomain Jobredeaux arguments = [src.path, dest.path], 214*9e965d6fSRomain Jobredeaux inputs = [src], 215*9e965d6fSRomain Jobredeaux outputs = [dest], 216*9e965d6fSRomain Jobredeaux mnemonic = "CopyFile", 217*9e965d6fSRomain Jobredeaux progress_message = "Copy %s to %s" % (src.short_path, dest.short_path), 218*9e965d6fSRomain Jobredeaux ) 219*9e965d6fSRomain Jobredeaux 220*9e965d6fSRomain Jobredeauxdef _copy_dir(ctx, src, dest): 221*9e965d6fSRomain Jobredeaux if not src.is_directory: 222*9e965d6fSRomain Jobredeaux fail("copy_dir src must be a directory") 223*9e965d6fSRomain Jobredeaux ctx.actions.run_shell( 224*9e965d6fSRomain Jobredeaux command = "cp -r --reflink=auto $1 $2", 225*9e965d6fSRomain Jobredeaux arguments = [src.path, dest.path], 226*9e965d6fSRomain Jobredeaux inputs = [src], 227*9e965d6fSRomain Jobredeaux outputs = [dest], 228*9e965d6fSRomain Jobredeaux mnemonic = "CopyDir", 229*9e965d6fSRomain Jobredeaux progress_message = "Copy %s to %s" % (src.short_path, dest.short_path), 230*9e965d6fSRomain Jobredeaux ) 231*9e965d6fSRomain Jobredeaux 232*9e965d6fSRomain Jobredeauxdef _info(msg): 233*9e965d6fSRomain Jobredeaux """Print info.""" 234*9e965d6fSRomain Jobredeaux print(_INFO % msg) 235*9e965d6fSRomain Jobredeaux 236*9e965d6fSRomain Jobredeauxdef _warn(msg): 237*9e965d6fSRomain Jobredeaux """Print warning.""" 238*9e965d6fSRomain Jobredeaux print(_WARNING % msg) 239*9e965d6fSRomain Jobredeaux 240*9e965d6fSRomain Jobredeauxdef _debug(msg): 241*9e965d6fSRomain Jobredeaux """Print debug.""" 242*9e965d6fSRomain Jobredeaux print("\n%s" % msg) 243*9e965d6fSRomain Jobredeaux 244*9e965d6fSRomain Jobredeauxdef _error(msg): 245*9e965d6fSRomain Jobredeaux """Print error and fail.""" 246*9e965d6fSRomain Jobredeaux fail(_ERASE_PREV_LINE + _CUU + _ERASE_PREV_LINE + _CUU + _ERROR % msg) 247*9e965d6fSRomain Jobredeaux 248*9e965d6fSRomain Jobredeauxdef _expand_var(config_vars, value): 249*9e965d6fSRomain Jobredeaux """Expands make variables of the form $(SOME_VAR_NAME) for a single value. 250*9e965d6fSRomain Jobredeaux 251*9e965d6fSRomain Jobredeaux "$$(SOME_VAR_NAME)" is escaped to a literal value of "$(SOME_VAR_NAME)" instead of being 252*9e965d6fSRomain Jobredeaux expanded. 253*9e965d6fSRomain Jobredeaux 254*9e965d6fSRomain Jobredeaux Args: 255*9e965d6fSRomain Jobredeaux config_vars: String dictionary which maps config variables to their expanded values. 256*9e965d6fSRomain Jobredeaux value: The string to apply substitutions to. 257*9e965d6fSRomain Jobredeaux 258*9e965d6fSRomain Jobredeaux Returns: 259*9e965d6fSRomain Jobredeaux The string value with substitutions applied. 260*9e965d6fSRomain Jobredeaux """ 261*9e965d6fSRomain Jobredeaux parts = value.split("$(") 262*9e965d6fSRomain Jobredeaux replacement = parts[0] 263*9e965d6fSRomain Jobredeaux last_char = replacement[-1] if replacement else "" 264*9e965d6fSRomain Jobredeaux for part in parts[1:]: 265*9e965d6fSRomain Jobredeaux var_end = part.find(")") 266*9e965d6fSRomain Jobredeaux if last_char == "$": 267*9e965d6fSRomain Jobredeaux # If "$$(..." is found, treat it as "$(..." 268*9e965d6fSRomain Jobredeaux replacement += "(" + part 269*9e965d6fSRomain Jobredeaux elif var_end == -1 or part[:var_end] not in config_vars: 270*9e965d6fSRomain Jobredeaux replacement += "$(" + part 271*9e965d6fSRomain Jobredeaux else: 272*9e965d6fSRomain Jobredeaux replacement += config_vars[part[:var_end]] + part[var_end + 1:] 273*9e965d6fSRomain Jobredeaux last_char = replacement[-1] if replacement else "" 274*9e965d6fSRomain Jobredeaux return replacement 275*9e965d6fSRomain Jobredeaux 276*9e965d6fSRomain Jobredeauxdef _expand_make_vars(ctx, vals): 277*9e965d6fSRomain Jobredeaux """Expands make variables of the form $(SOME_VAR_NAME). 278*9e965d6fSRomain Jobredeaux 279*9e965d6fSRomain Jobredeaux Args: 280*9e965d6fSRomain Jobredeaux ctx: The rules context. 281*9e965d6fSRomain Jobredeaux vals: Dictionary. Values of the form $(...) will be replaced. 282*9e965d6fSRomain Jobredeaux 283*9e965d6fSRomain Jobredeaux Returns: 284*9e965d6fSRomain Jobredeaux A dictionary containing vals.keys() and the expanded values. 285*9e965d6fSRomain Jobredeaux """ 286*9e965d6fSRomain Jobredeaux res = {} 287*9e965d6fSRomain Jobredeaux for k, v in vals.items(): 288*9e965d6fSRomain Jobredeaux res[k] = _expand_var(ctx.var, v) 289*9e965d6fSRomain Jobredeaux return res 290*9e965d6fSRomain Jobredeaux 291*9e965d6fSRomain Jobredeauxdef _dedupe_split_attr(attr): 292*9e965d6fSRomain Jobredeaux if not attr: 293*9e965d6fSRomain Jobredeaux return [] 294*9e965d6fSRomain Jobredeaux arch = _first(sorted(attr.keys())) 295*9e965d6fSRomain Jobredeaux return attr[arch] 296*9e965d6fSRomain Jobredeaux 297*9e965d6fSRomain Jobredeauxdef _get_runfiles(ctx, attrs): 298*9e965d6fSRomain Jobredeaux runfiles = ctx.runfiles() 299*9e965d6fSRomain Jobredeaux for attr in attrs: 300*9e965d6fSRomain Jobredeaux executable = attr[DefaultInfo].files_to_run.executable 301*9e965d6fSRomain Jobredeaux if executable: 302*9e965d6fSRomain Jobredeaux runfiles = runfiles.merge(ctx.runfiles([executable])) 303*9e965d6fSRomain Jobredeaux runfiles = runfiles.merge( 304*9e965d6fSRomain Jobredeaux ctx.runfiles( 305*9e965d6fSRomain Jobredeaux # Wrap DefaultInfo.files in depset to strip ordering. 306*9e965d6fSRomain Jobredeaux transitive_files = depset( 307*9e965d6fSRomain Jobredeaux transitive = [attr[DefaultInfo].files], 308*9e965d6fSRomain Jobredeaux ), 309*9e965d6fSRomain Jobredeaux ), 310*9e965d6fSRomain Jobredeaux ) 311*9e965d6fSRomain Jobredeaux runfiles = runfiles.merge(attr[DefaultInfo].default_runfiles) 312*9e965d6fSRomain Jobredeaux return runfiles 313*9e965d6fSRomain Jobredeaux 314*9e965d6fSRomain Jobredeauxdef _sanitize_string(s, replacement = ""): 315*9e965d6fSRomain Jobredeaux """Sanitizes a string by replacing all non-word characters. 316*9e965d6fSRomain Jobredeaux 317*9e965d6fSRomain Jobredeaux This matches the \\w regex character class [A_Za-z0-9_]. 318*9e965d6fSRomain Jobredeaux 319*9e965d6fSRomain Jobredeaux Args: 320*9e965d6fSRomain Jobredeaux s: String to sanitize. 321*9e965d6fSRomain Jobredeaux replacement: Replacement for all non-word characters. Optional. 322*9e965d6fSRomain Jobredeaux 323*9e965d6fSRomain Jobredeaux Returns: 324*9e965d6fSRomain Jobredeaux The original string with all non-word characters replaced. 325*9e965d6fSRomain Jobredeaux """ 326*9e965d6fSRomain Jobredeaux return "".join([s[i] if s[i] in _WORD_CHARS else replacement for i in range(len(s))]) 327*9e965d6fSRomain Jobredeaux 328*9e965d6fSRomain Jobredeauxdef _hex(n, pad = True): 329*9e965d6fSRomain Jobredeaux """Convert an integer number to an uppercase hexadecimal string. 330*9e965d6fSRomain Jobredeaux 331*9e965d6fSRomain Jobredeaux Args: 332*9e965d6fSRomain Jobredeaux n: Integer number. 333*9e965d6fSRomain Jobredeaux pad: Optional. Pad the result to 8 characters with leading zeroes. Default = True. 334*9e965d6fSRomain Jobredeaux 335*9e965d6fSRomain Jobredeaux Returns: 336*9e965d6fSRomain Jobredeaux Return a representation of an integer number as a hexadecimal string. 337*9e965d6fSRomain Jobredeaux """ 338*9e965d6fSRomain Jobredeaux hex_str = "" 339*9e965d6fSRomain Jobredeaux for _ in range(8): 340*9e965d6fSRomain Jobredeaux r = n % 16 341*9e965d6fSRomain Jobredeaux n = n // 16 342*9e965d6fSRomain Jobredeaux hex_str = _HEX_CHAR[r] + hex_str 343*9e965d6fSRomain Jobredeaux if pad: 344*9e965d6fSRomain Jobredeaux return hex_str 345*9e965d6fSRomain Jobredeaux else: 346*9e965d6fSRomain Jobredeaux return hex_str.lstrip("0") 347*9e965d6fSRomain Jobredeaux 348*9e965d6fSRomain Jobredeauxdef _sanitize_java_package(pkg): 349*9e965d6fSRomain Jobredeaux return ".".join(["xxx" if p in _JAVA_RESERVED else p for p in pkg.split(".")]) 350*9e965d6fSRomain Jobredeaux 351*9e965d6fSRomain Jobredeauxdef _check_for_failures(label, *all_deps): 352*9e965d6fSRomain Jobredeaux """Collects FailureInfo providers from the given list of deps and fails if there's at least one.""" 353*9e965d6fSRomain Jobredeaux failure_infos = _collect_providers(FailureInfo, *all_deps) 354*9e965d6fSRomain Jobredeaux if failure_infos: 355*9e965d6fSRomain Jobredeaux error = "in label '%s':" % label 356*9e965d6fSRomain Jobredeaux for failure_info in failure_infos: 357*9e965d6fSRomain Jobredeaux error += "\n\t" + failure_info.error 358*9e965d6fSRomain Jobredeaux _error(error) 359*9e965d6fSRomain Jobredeaux 360*9e965d6fSRomain Jobredeauxdef _run_validation( 361*9e965d6fSRomain Jobredeaux ctx, 362*9e965d6fSRomain Jobredeaux validation_out, 363*9e965d6fSRomain Jobredeaux executable, 364*9e965d6fSRomain Jobredeaux outputs = [], 365*9e965d6fSRomain Jobredeaux tools = [], 366*9e965d6fSRomain Jobredeaux **args): 367*9e965d6fSRomain Jobredeaux """Creates an action that runs an executable as a validation. 368*9e965d6fSRomain Jobredeaux 369*9e965d6fSRomain Jobredeaux Note: When the validation executable fails, it should return a non-zero 370*9e965d6fSRomain Jobredeaux value to signify a validation failure. 371*9e965d6fSRomain Jobredeaux 372*9e965d6fSRomain Jobredeaux Args: 373*9e965d6fSRomain Jobredeaux ctx: The context. 374*9e965d6fSRomain Jobredeaux validation_out: A File. The output of the executable is piped to the 375*9e965d6fSRomain Jobredeaux file. This artifact should then be propagated to "validations" in the 376*9e965d6fSRomain Jobredeaux OutputGroupInfo. 377*9e965d6fSRomain Jobredeaux executable: See ctx.actions.run#executable. 378*9e965d6fSRomain Jobredeaux outputs: See ctx.actions.run#outputs. 379*9e965d6fSRomain Jobredeaux tools: See ctx.actions.run#tools. 380*9e965d6fSRomain Jobredeaux **args: Remaining args are directly propagated to ctx.actions.run_shell. 381*9e965d6fSRomain Jobredeaux See ctx.actions.run_shell for further documentation. 382*9e965d6fSRomain Jobredeaux """ 383*9e965d6fSRomain Jobredeaux exec_type = type(executable) 384*9e965d6fSRomain Jobredeaux exec_bin = None 385*9e965d6fSRomain Jobredeaux exec_bin_path = None 386*9e965d6fSRomain Jobredeaux if exec_type == "FilesToRunProvider": 387*9e965d6fSRomain Jobredeaux exec_bin = executable.executable 388*9e965d6fSRomain Jobredeaux exec_bin_path = exec_bin.path 389*9e965d6fSRomain Jobredeaux elif exec_type == "File": 390*9e965d6fSRomain Jobredeaux exec_bin = executable 391*9e965d6fSRomain Jobredeaux exec_bin_path = exec_bin.path 392*9e965d6fSRomain Jobredeaux elif exec_type == type(""): 393*9e965d6fSRomain Jobredeaux exec_bin_path = executable 394*9e965d6fSRomain Jobredeaux else: 395*9e965d6fSRomain Jobredeaux fail( 396*9e965d6fSRomain Jobredeaux "Error, executable should be a File, FilesToRunProvider or a " + 397*9e965d6fSRomain Jobredeaux "string that represents a path to a tool, got: %s" % exec_type, 398*9e965d6fSRomain Jobredeaux ) 399*9e965d6fSRomain Jobredeaux 400*9e965d6fSRomain Jobredeaux ctx.actions.run_shell( 401*9e965d6fSRomain Jobredeaux command = """#!/bin/bash 402*9e965d6fSRomain Jobredeauxset -eu 403*9e965d6fSRomain Jobredeauxset -o pipefail # Returns the executables failure code, if it fails. 404*9e965d6fSRomain Jobredeaux 405*9e965d6fSRomain JobredeauxEXECUTABLE={executable} 406*9e965d6fSRomain JobredeauxVALIDATION_OUT={validation_out} 407*9e965d6fSRomain Jobredeaux 408*9e965d6fSRomain Jobredeaux"${{EXECUTABLE}}" $@ 2>&1 | tee -a "${{VALIDATION_OUT}}" 409*9e965d6fSRomain Jobredeaux""".format( 410*9e965d6fSRomain Jobredeaux executable = exec_bin_path, 411*9e965d6fSRomain Jobredeaux validation_out = validation_out.path, 412*9e965d6fSRomain Jobredeaux ), 413*9e965d6fSRomain Jobredeaux tools = tools + ([exec_bin] if exec_bin else []), 414*9e965d6fSRomain Jobredeaux outputs = [validation_out] + outputs, 415*9e965d6fSRomain Jobredeaux **args 416*9e965d6fSRomain Jobredeaux ) 417*9e965d6fSRomain Jobredeaux 418*9e965d6fSRomain Jobredeauxdef get_android_toolchain(ctx): 419*9e965d6fSRomain Jobredeaux return ctx.toolchains[ANDROID_TOOLCHAIN_TYPE] 420*9e965d6fSRomain Jobredeaux 421*9e965d6fSRomain Jobredeauxdef get_android_sdk(ctx): 422*9e965d6fSRomain Jobredeaux if hasattr(ctx.fragments.android, "incompatible_use_toolchain_resolution") and ctx.fragments.android.incompatible_use_toolchain_resolution: 423*9e965d6fSRomain Jobredeaux return ctx.toolchains["//toolchains/android_sdk:toolchain_type"].android_sdk_info 424*9e965d6fSRomain Jobredeaux else: 425*9e965d6fSRomain Jobredeaux return ctx.attr._android_sdk[AndroidSdkInfo] 426*9e965d6fSRomain Jobredeaux 427*9e965d6fSRomain Jobredeauxdef _get_compilation_mode(ctx): 428*9e965d6fSRomain Jobredeaux """Retrieves the compilation mode from the context. 429*9e965d6fSRomain Jobredeaux 430*9e965d6fSRomain Jobredeaux Returns: 431*9e965d6fSRomain Jobredeaux A string that represents the compilation mode. 432*9e965d6fSRomain Jobredeaux """ 433*9e965d6fSRomain Jobredeaux return ctx.var["COMPILATION_MODE"] 434*9e965d6fSRomain Jobredeaux 435*9e965d6fSRomain Jobredeauxcompilation_mode = struct( 436*9e965d6fSRomain Jobredeaux DBG = "dbg", 437*9e965d6fSRomain Jobredeaux FASTBUILD = "fastbuild", 438*9e965d6fSRomain Jobredeaux OPT = "opt", 439*9e965d6fSRomain Jobredeaux get = _get_compilation_mode, 440*9e965d6fSRomain Jobredeaux) 441*9e965d6fSRomain Jobredeaux 442*9e965d6fSRomain Jobredeauxutils = struct( 443*9e965d6fSRomain Jobredeaux check_for_failures = _check_for_failures, 444*9e965d6fSRomain Jobredeaux collect_providers = _collect_providers, 445*9e965d6fSRomain Jobredeaux copy_file = _copy_file, 446*9e965d6fSRomain Jobredeaux copy_dir = _copy_dir, 447*9e965d6fSRomain Jobredeaux expand_make_vars = _expand_make_vars, 448*9e965d6fSRomain Jobredeaux first = _first, 449*9e965d6fSRomain Jobredeaux dedupe_split_attr = _dedupe_split_attr, 450*9e965d6fSRomain Jobredeaux get_runfiles = _get_runfiles, 451*9e965d6fSRomain Jobredeaux join_depsets = _join_depsets, 452*9e965d6fSRomain Jobredeaux only = _only, 453*9e965d6fSRomain Jobredeaux run_validation = _run_validation, 454*9e965d6fSRomain Jobredeaux sanitize_string = _sanitize_string, 455*9e965d6fSRomain Jobredeaux sanitize_java_package = _sanitize_java_package, 456*9e965d6fSRomain Jobredeaux hex = _hex, 457*9e965d6fSRomain Jobredeaux list_or_depset_to_list = _list_or_depset_to_list, 458*9e965d6fSRomain Jobredeaux) 459*9e965d6fSRomain Jobredeaux 460*9e965d6fSRomain Jobredeauxlog = struct( 461*9e965d6fSRomain Jobredeaux debug = _debug, 462*9e965d6fSRomain Jobredeaux error = _error, 463*9e965d6fSRomain Jobredeaux info = _info, 464*9e965d6fSRomain Jobredeaux warn = _warn, 465*9e965d6fSRomain Jobredeaux) 466*9e965d6fSRomain Jobredeaux 467*9e965d6fSRomain Jobredeauxtesting = struct( 468*9e965d6fSRomain Jobredeaux expand_var = _expand_var, 469*9e965d6fSRomain Jobredeaux) 470