1*7887bec8SAndroid Build Coastguard Worker#!/usr/bin/env python3 2*7887bec8SAndroid Build Coastguard Worker# 3*7887bec8SAndroid Build Coastguard Worker# Copyright (C) 2021 The Android Open Source Project 4*7887bec8SAndroid Build Coastguard Worker# 5*7887bec8SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 6*7887bec8SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 7*7887bec8SAndroid Build Coastguard Worker# You may obtain a copy of the License at 8*7887bec8SAndroid Build Coastguard Worker# 9*7887bec8SAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 10*7887bec8SAndroid Build Coastguard Worker# 11*7887bec8SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 12*7887bec8SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 13*7887bec8SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*7887bec8SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 15*7887bec8SAndroid Build Coastguard Worker# limitations under the License. 16*7887bec8SAndroid Build Coastguard Worker"""A script to copy outputs from Bazel rules to a user specified dist directory. 17*7887bec8SAndroid Build Coastguard Worker 18*7887bec8SAndroid Build Coastguard WorkerThis script is only meant to be executed with `bazel run`. `bazel build <this 19*7887bec8SAndroid Build Coastguard Workerscript>` doesn't actually copy the files, you'd have to `bazel run` a 20*7887bec8SAndroid Build Coastguard Workercopy_to_dist_dir target. 21*7887bec8SAndroid Build Coastguard Worker 22*7887bec8SAndroid Build Coastguard WorkerThis script copies files from Bazel's output tree into a directory specified by 23*7887bec8SAndroid Build Coastguard Workerthe user. It does not check if the dist dir already contains the file, and will 24*7887bec8SAndroid Build Coastguard Workersimply overwrite it. 25*7887bec8SAndroid Build Coastguard Worker 26*7887bec8SAndroid Build Coastguard WorkerOne approach is to wipe the dist dir every time this script runs, but that may 27*7887bec8SAndroid Build Coastguard Workerbe overly destructive and best left to an explicit rm -rf call outside of this 28*7887bec8SAndroid Build Coastguard Workerscript. 29*7887bec8SAndroid Build Coastguard Worker 30*7887bec8SAndroid Build Coastguard WorkerAnother approach is to error out if the file being copied already exist in the 31*7887bec8SAndroid Build Coastguard Workerdist dir, or perform some kind of content hash checking. 32*7887bec8SAndroid Build Coastguard Worker""" 33*7887bec8SAndroid Build Coastguard Worker 34*7887bec8SAndroid Build Coastguard Workerimport argparse 35*7887bec8SAndroid Build Coastguard Workerimport collections 36*7887bec8SAndroid Build Coastguard Workerimport fnmatch 37*7887bec8SAndroid Build Coastguard Workerimport glob 38*7887bec8SAndroid Build Coastguard Workerimport logging 39*7887bec8SAndroid Build Coastguard Workerimport os 40*7887bec8SAndroid Build Coastguard Workerimport pathlib 41*7887bec8SAndroid Build Coastguard Workerimport shutil 42*7887bec8SAndroid Build Coastguard Workerimport sys 43*7887bec8SAndroid Build Coastguard Workerimport tarfile 44*7887bec8SAndroid Build Coastguard Workerimport textwrap 45*7887bec8SAndroid Build Coastguard Worker 46*7887bec8SAndroid Build Coastguard Worker 47*7887bec8SAndroid Build Coastguard Worker_CMDLINE_FLAGS_SENTINEL = "CMDLINE_FLAGS_SENTINEL" 48*7887bec8SAndroid Build Coastguard Worker 49*7887bec8SAndroid Build Coastguard Worker# Arguments that should not be specified in the command line, but only 50*7887bec8SAndroid Build Coastguard Worker# in BUILD files. 51*7887bec8SAndroid Build Coastguard Worker_DEPRECATED_CMDLINE_OPTIONS = { 52*7887bec8SAndroid Build Coastguard Worker "--dist_dir": "Use --destdir instead.", 53*7887bec8SAndroid Build Coastguard Worker "--log": "Use -q instead.", 54*7887bec8SAndroid Build Coastguard Worker "--archive_prefix": "", 55*7887bec8SAndroid Build Coastguard Worker "--flat": "Specify it in the BUILD file (e.g. copy_to_dist_dir(flat=True))", 56*7887bec8SAndroid Build Coastguard Worker "--strip_components": "Specify it in the BUILD file " 57*7887bec8SAndroid Build Coastguard Worker "(e.g. copy_to_dist_dir(strip_components=1))", 58*7887bec8SAndroid Build Coastguard Worker "--prefix": "Specify it in the BUILD file " 59*7887bec8SAndroid Build Coastguard Worker "(e.g. copy_to_dist_dir(prefix='prefix'))", 60*7887bec8SAndroid Build Coastguard Worker "--wipe_dist_dir": "Specify it in the BUILD file " 61*7887bec8SAndroid Build Coastguard Worker "(e.g. copy_to_dist_dir(wipe_dist_dir=True))", 62*7887bec8SAndroid Build Coastguard Worker "--allow_duplicate_filenames": 63*7887bec8SAndroid Build Coastguard Worker "Specify it in the BUILD file " 64*7887bec8SAndroid Build Coastguard Worker "(e.g. copy_to_dist_dir(allow_duplicate_filenames=True))", 65*7887bec8SAndroid Build Coastguard Worker "--mode_override": 66*7887bec8SAndroid Build Coastguard Worker "Specify it in the BUILD file " 67*7887bec8SAndroid Build Coastguard Worker "(e.g. copy_to_dist_dir(mode_overrides=[('*.sh', '755')]))", 68*7887bec8SAndroid Build Coastguard Worker} 69*7887bec8SAndroid Build Coastguard Worker 70*7887bec8SAndroid Build Coastguard Worker 71*7887bec8SAndroid Build Coastguard Workerdef copy_with_modes(src, dst, mode_overrides): 72*7887bec8SAndroid Build Coastguard Worker mode_override = None 73*7887bec8SAndroid Build Coastguard Worker for (pattern, mode) in mode_overrides: 74*7887bec8SAndroid Build Coastguard Worker if fnmatch.fnmatch(src, pattern): 75*7887bec8SAndroid Build Coastguard Worker mode_override = mode 76*7887bec8SAndroid Build Coastguard Worker break 77*7887bec8SAndroid Build Coastguard Worker 78*7887bec8SAndroid Build Coastguard Worker # Remove destination file that may be write-protected 79*7887bec8SAndroid Build Coastguard Worker pathlib.Path(dst).unlink(missing_ok=True) 80*7887bec8SAndroid Build Coastguard Worker 81*7887bec8SAndroid Build Coastguard Worker # Copy the file with copy2 to preserve whatever permissions are set on src 82*7887bec8SAndroid Build Coastguard Worker shutil.copy2(os.path.abspath(src), dst, follow_symlinks=True) 83*7887bec8SAndroid Build Coastguard Worker 84*7887bec8SAndroid Build Coastguard Worker if mode_override: 85*7887bec8SAndroid Build Coastguard Worker os.chmod(dst, mode_override) 86*7887bec8SAndroid Build Coastguard Worker 87*7887bec8SAndroid Build Coastguard Worker 88*7887bec8SAndroid Build Coastguard Workerdef ensure_unique_filenames(files): 89*7887bec8SAndroid Build Coastguard Worker basename_to_srcs_map = collections.defaultdict(list) 90*7887bec8SAndroid Build Coastguard Worker for f in files: 91*7887bec8SAndroid Build Coastguard Worker basename_to_srcs_map[os.path.basename(f)].append(f) 92*7887bec8SAndroid Build Coastguard Worker 93*7887bec8SAndroid Build Coastguard Worker duplicates_exist = False 94*7887bec8SAndroid Build Coastguard Worker for (basename, srcs) in basename_to_srcs_map.items(): 95*7887bec8SAndroid Build Coastguard Worker if len(srcs) > 1: 96*7887bec8SAndroid Build Coastguard Worker duplicates_exist = True 97*7887bec8SAndroid Build Coastguard Worker logging.error('Destination filename "%s" has multiple possible sources: %s', 98*7887bec8SAndroid Build Coastguard Worker basename, srcs) 99*7887bec8SAndroid Build Coastguard Worker 100*7887bec8SAndroid Build Coastguard Worker if duplicates_exist: 101*7887bec8SAndroid Build Coastguard Worker sys.exit(1) 102*7887bec8SAndroid Build Coastguard Worker 103*7887bec8SAndroid Build Coastguard Worker 104*7887bec8SAndroid Build Coastguard Workerdef files_to_dist(pattern): 105*7887bec8SAndroid Build Coastguard Worker # Assume that dist.bzl is in the same package as dist.py 106*7887bec8SAndroid Build Coastguard Worker runfiles_directory = os.path.dirname(__file__) 107*7887bec8SAndroid Build Coastguard Worker dist_manifests = glob.glob( 108*7887bec8SAndroid Build Coastguard Worker os.path.join(runfiles_directory, pattern)) 109*7887bec8SAndroid Build Coastguard Worker if not dist_manifests: 110*7887bec8SAndroid Build Coastguard Worker logging.warning("Could not find a file with pattern %s" 111*7887bec8SAndroid Build Coastguard Worker " in the runfiles directory: %s", pattern, runfiles_directory) 112*7887bec8SAndroid Build Coastguard Worker files_to_dist = [] 113*7887bec8SAndroid Build Coastguard Worker for dist_manifest in dist_manifests: 114*7887bec8SAndroid Build Coastguard Worker with open(dist_manifest, "r") as f: 115*7887bec8SAndroid Build Coastguard Worker files_to_dist += [line.strip() for line in f] 116*7887bec8SAndroid Build Coastguard Worker return files_to_dist 117*7887bec8SAndroid Build Coastguard Worker 118*7887bec8SAndroid Build Coastguard Worker 119*7887bec8SAndroid Build Coastguard Workerdef copy_files_to_dist_dir(files, archives, mode_overrides, dist_dir, flat, prefix, 120*7887bec8SAndroid Build Coastguard Worker strip_components, archive_prefix, wipe_dist_dir, allow_duplicate_filenames, **ignored): 121*7887bec8SAndroid Build Coastguard Worker 122*7887bec8SAndroid Build Coastguard Worker if flat and not allow_duplicate_filenames: 123*7887bec8SAndroid Build Coastguard Worker ensure_unique_filenames(files) 124*7887bec8SAndroid Build Coastguard Worker 125*7887bec8SAndroid Build Coastguard Worker if wipe_dist_dir and os.path.exists(dist_dir): 126*7887bec8SAndroid Build Coastguard Worker shutil.rmtree(dist_dir) 127*7887bec8SAndroid Build Coastguard Worker 128*7887bec8SAndroid Build Coastguard Worker logging.info("Copying to %s", dist_dir) 129*7887bec8SAndroid Build Coastguard Worker 130*7887bec8SAndroid Build Coastguard Worker for src in files: 131*7887bec8SAndroid Build Coastguard Worker if flat: 132*7887bec8SAndroid Build Coastguard Worker src_relpath = os.path.basename(src) 133*7887bec8SAndroid Build Coastguard Worker elif strip_components > 0: 134*7887bec8SAndroid Build Coastguard Worker src_relpath = src.split('/', strip_components)[-1] 135*7887bec8SAndroid Build Coastguard Worker else: 136*7887bec8SAndroid Build Coastguard Worker src_relpath = src 137*7887bec8SAndroid Build Coastguard Worker 138*7887bec8SAndroid Build Coastguard Worker src_relpath = os.path.join(prefix, src_relpath) 139*7887bec8SAndroid Build Coastguard Worker 140*7887bec8SAndroid Build Coastguard Worker dst = os.path.join(dist_dir, src_relpath) 141*7887bec8SAndroid Build Coastguard Worker if os.path.isfile(src): 142*7887bec8SAndroid Build Coastguard Worker dst_dirname = os.path.dirname(dst) 143*7887bec8SAndroid Build Coastguard Worker logging.debug("Copying file: %s" % dst) 144*7887bec8SAndroid Build Coastguard Worker if not os.path.exists(dst_dirname): 145*7887bec8SAndroid Build Coastguard Worker os.makedirs(dst_dirname) 146*7887bec8SAndroid Build Coastguard Worker 147*7887bec8SAndroid Build Coastguard Worker copy_with_modes(src, dst, mode_overrides) 148*7887bec8SAndroid Build Coastguard Worker elif os.path.isdir(src): 149*7887bec8SAndroid Build Coastguard Worker logging.debug("Copying dir: %s" % dst) 150*7887bec8SAndroid Build Coastguard Worker if os.path.exists(dst): 151*7887bec8SAndroid Build Coastguard Worker # make the directory temporary writable, then 152*7887bec8SAndroid Build Coastguard Worker # shutil.copytree will restore correct permissions. 153*7887bec8SAndroid Build Coastguard Worker os.chmod(dst, 750) 154*7887bec8SAndroid Build Coastguard Worker shutil.copytree( 155*7887bec8SAndroid Build Coastguard Worker os.path.abspath(src), 156*7887bec8SAndroid Build Coastguard Worker dst, 157*7887bec8SAndroid Build Coastguard Worker copy_function=lambda s, d: copy_with_modes(s, d, mode_overrides), 158*7887bec8SAndroid Build Coastguard Worker dirs_exist_ok=True, 159*7887bec8SAndroid Build Coastguard Worker ) 160*7887bec8SAndroid Build Coastguard Worker 161*7887bec8SAndroid Build Coastguard Worker for archive in archives: 162*7887bec8SAndroid Build Coastguard Worker try: 163*7887bec8SAndroid Build Coastguard Worker with tarfile.open(archive) as tf: 164*7887bec8SAndroid Build Coastguard Worker dst_dirname = os.path.join(dist_dir, archive_prefix) 165*7887bec8SAndroid Build Coastguard Worker logging.debug("Extracting archive: %s -> %s", archive, dst_dirname) 166*7887bec8SAndroid Build Coastguard Worker tf.extractall(dst_dirname) 167*7887bec8SAndroid Build Coastguard Worker except tarfile.TarError: 168*7887bec8SAndroid Build Coastguard Worker # toybox does not support creating empty tar files, hence the build 169*7887bec8SAndroid Build Coastguard Worker # system may use empty files as empty archives. 170*7887bec8SAndroid Build Coastguard Worker if os.path.getsize(archive) == 0: 171*7887bec8SAndroid Build Coastguard Worker logging.warning("Skipping empty tar file: %s", archive) 172*7887bec8SAndroid Build Coastguard Worker continue 173*7887bec8SAndroid Build Coastguard Worker # re-raise if we do not know anything about this error 174*7887bec8SAndroid Build Coastguard Worker logging.exception("Unknown TarError.") 175*7887bec8SAndroid Build Coastguard Worker raise 176*7887bec8SAndroid Build Coastguard Worker 177*7887bec8SAndroid Build Coastguard Worker 178*7887bec8SAndroid Build Coastguard Workerdef config_logging(log_level_str): 179*7887bec8SAndroid Build Coastguard Worker level = getattr(logging, log_level_str.upper(), None) 180*7887bec8SAndroid Build Coastguard Worker if not isinstance(level, int): 181*7887bec8SAndroid Build Coastguard Worker sys.stderr.write("ERROR: Invalid --log {}\n".format(log_level_str)) 182*7887bec8SAndroid Build Coastguard Worker sys.exit(1) 183*7887bec8SAndroid Build Coastguard Worker logging.basicConfig(level=level, format="[dist] %(levelname)s: %(message)s") 184*7887bec8SAndroid Build Coastguard Worker 185*7887bec8SAndroid Build Coastguard Worker 186*7887bec8SAndroid Build Coastguard Workerclass CheckDeprecationAction(argparse.Action): 187*7887bec8SAndroid Build Coastguard Worker """Checks if a deprecated option is used, then do nothing.""" 188*7887bec8SAndroid Build Coastguard Worker def __call__(self, parser, namespace, values, option_string=None): 189*7887bec8SAndroid Build Coastguard Worker if option_string in _DEPRECATED_CMDLINE_OPTIONS: 190*7887bec8SAndroid Build Coastguard Worker logging.warning("%s is deprecated! %s", option_string, 191*7887bec8SAndroid Build Coastguard Worker _DEPRECATED_CMDLINE_OPTIONS[option_string]) 192*7887bec8SAndroid Build Coastguard Worker 193*7887bec8SAndroid Build Coastguard Worker 194*7887bec8SAndroid Build Coastguard Workerclass StoreAndCheckDeprecationAction(CheckDeprecationAction): 195*7887bec8SAndroid Build Coastguard Worker """Sotres the value, and checks if a deprecated option is used.""" 196*7887bec8SAndroid Build Coastguard Worker def __call__(self, parser, namespace, values, option_string=None): 197*7887bec8SAndroid Build Coastguard Worker super().__call__(parser, namespace, values, option_string) 198*7887bec8SAndroid Build Coastguard Worker setattr(namespace, self.dest, values) 199*7887bec8SAndroid Build Coastguard Worker 200*7887bec8SAndroid Build Coastguard Worker 201*7887bec8SAndroid Build Coastguard Workerclass StoreTrueAndCheckDeprecationAction(CheckDeprecationAction): 202*7887bec8SAndroid Build Coastguard Worker """Sotres true, and checks if a deprecated option is used.""" 203*7887bec8SAndroid Build Coastguard Worker def __call__(self, parser, namespace, values, option_string=None): 204*7887bec8SAndroid Build Coastguard Worker super().__call__(parser, namespace, values, option_string) 205*7887bec8SAndroid Build Coastguard Worker setattr(namespace, self.dest, True) 206*7887bec8SAndroid Build Coastguard Worker 207*7887bec8SAndroid Build Coastguard Worker 208*7887bec8SAndroid Build Coastguard Workerclass AppendAndCheckDeprecationAction(CheckDeprecationAction): 209*7887bec8SAndroid Build Coastguard Worker """Appends the value, and checks if a deprecated option is used.""" 210*7887bec8SAndroid Build Coastguard Worker def __call__(self, parser, namespace, values, option_string=None): 211*7887bec8SAndroid Build Coastguard Worker super().__call__(parser, namespace, values, option_string) 212*7887bec8SAndroid Build Coastguard Worker if not values: 213*7887bec8SAndroid Build Coastguard Worker return 214*7887bec8SAndroid Build Coastguard Worker metavar_len = len(self.metavar)if self.metavar else 1 215*7887bec8SAndroid Build Coastguard Worker value_groups = [values[i:i + metavar_len] 216*7887bec8SAndroid Build Coastguard Worker for i in range(0, len(values), metavar_len)] 217*7887bec8SAndroid Build Coastguard Worker setattr(namespace, self.dest, 218*7887bec8SAndroid Build Coastguard Worker getattr(namespace, self.dest, []) + value_groups) 219*7887bec8SAndroid Build Coastguard Worker 220*7887bec8SAndroid Build Coastguard Worker 221*7887bec8SAndroid Build Coastguard Workerdef _get_parser(cmdline=False) -> argparse.ArgumentParser: 222*7887bec8SAndroid Build Coastguard Worker parser = argparse.ArgumentParser( 223*7887bec8SAndroid Build Coastguard Worker description="Dist Bazel output files into a custom directory.", 224*7887bec8SAndroid Build Coastguard Worker formatter_class=argparse.RawTextHelpFormatter) 225*7887bec8SAndroid Build Coastguard Worker deprecated = parser.add_argument_group( 226*7887bec8SAndroid Build Coastguard Worker "Deprecated command line options", 227*7887bec8SAndroid Build Coastguard Worker description=textwrap.dedent("""\ 228*7887bec8SAndroid Build Coastguard Worker List of command line options that are deprecated. 229*7887bec8SAndroid Build Coastguard Worker Most of them should be specified in the BUILD file instead. 230*7887bec8SAndroid Build Coastguard Worker """)) 231*7887bec8SAndroid Build Coastguard Worker parser.add_argument( 232*7887bec8SAndroid Build Coastguard Worker "--destdir", "--dist_dir", required=not cmdline, dest="dist_dir", 233*7887bec8SAndroid Build Coastguard Worker help=textwrap.dedent("""\ 234*7887bec8SAndroid Build Coastguard Worker path to the dist dir. 235*7887bec8SAndroid Build Coastguard Worker If relative, it is interpreted as relative to Bazel workspace root 236*7887bec8SAndroid Build Coastguard Worker set by the BUILD_WORKSPACE_DIRECTORY environment variable, or 237*7887bec8SAndroid Build Coastguard Worker PWD if BUILD_WORKSPACE_DIRECTORY is not set. 238*7887bec8SAndroid Build Coastguard Worker 239*7887bec8SAndroid Build Coastguard Worker Note: --dist_dir is deprecated; use --destdir instead."""), 240*7887bec8SAndroid Build Coastguard Worker action=StoreAndCheckDeprecationAction if cmdline else "store") 241*7887bec8SAndroid Build Coastguard Worker deprecated.add_argument( 242*7887bec8SAndroid Build Coastguard Worker "--flat", 243*7887bec8SAndroid Build Coastguard Worker action=StoreTrueAndCheckDeprecationAction if cmdline else "store_true", 244*7887bec8SAndroid Build Coastguard Worker help="ignore subdirectories in the manifest") 245*7887bec8SAndroid Build Coastguard Worker deprecated.add_argument( 246*7887bec8SAndroid Build Coastguard Worker "--strip_components", type=int, default=0, 247*7887bec8SAndroid Build Coastguard Worker help="number of leading components to strip from paths before applying --prefix", 248*7887bec8SAndroid Build Coastguard Worker action=StoreAndCheckDeprecationAction if cmdline else "store") 249*7887bec8SAndroid Build Coastguard Worker deprecated.add_argument( 250*7887bec8SAndroid Build Coastguard Worker "--prefix", default="", 251*7887bec8SAndroid Build Coastguard Worker help="path prefix to apply within dist_dir for copied files", 252*7887bec8SAndroid Build Coastguard Worker action=StoreAndCheckDeprecationAction if cmdline else "store") 253*7887bec8SAndroid Build Coastguard Worker deprecated.add_argument( 254*7887bec8SAndroid Build Coastguard Worker "--archive_prefix", default="", 255*7887bec8SAndroid Build Coastguard Worker help="Path prefix to apply within dist_dir for extracted archives. " + 256*7887bec8SAndroid Build Coastguard Worker "Supported archives: tar.", 257*7887bec8SAndroid Build Coastguard Worker action=StoreAndCheckDeprecationAction if cmdline else "store") 258*7887bec8SAndroid Build Coastguard Worker deprecated.add_argument("--log", help="Log level (debug, info, warning, error)", 259*7887bec8SAndroid Build Coastguard Worker default="debug", 260*7887bec8SAndroid Build Coastguard Worker action=StoreAndCheckDeprecationAction if cmdline else "store") 261*7887bec8SAndroid Build Coastguard Worker parser.add_argument("-q", "--quiet", action="store_const", default=False, 262*7887bec8SAndroid Build Coastguard Worker help="Same as --log=error", const="error", dest="log") 263*7887bec8SAndroid Build Coastguard Worker deprecated.add_argument( 264*7887bec8SAndroid Build Coastguard Worker "--wipe_dist_dir", 265*7887bec8SAndroid Build Coastguard Worker action=StoreTrueAndCheckDeprecationAction if cmdline else "store_true", 266*7887bec8SAndroid Build Coastguard Worker help="remove existing dist_dir prior to running", 267*7887bec8SAndroid Build Coastguard Worker ) 268*7887bec8SAndroid Build Coastguard Worker deprecated.add_argument( 269*7887bec8SAndroid Build Coastguard Worker "--allow_duplicate_filenames", 270*7887bec8SAndroid Build Coastguard Worker action=StoreTrueAndCheckDeprecationAction if cmdline else "store_true", 271*7887bec8SAndroid Build Coastguard Worker help="allow multiple files with the same name to be copied to dist_dir (overwriting)" 272*7887bec8SAndroid Build Coastguard Worker ) 273*7887bec8SAndroid Build Coastguard Worker deprecated.add_argument( 274*7887bec8SAndroid Build Coastguard Worker "--mode_override", 275*7887bec8SAndroid Build Coastguard Worker metavar=("PATTERN", "MODE"), 276*7887bec8SAndroid Build Coastguard Worker action=AppendAndCheckDeprecationAction if cmdline else "append", 277*7887bec8SAndroid Build Coastguard Worker nargs=2, 278*7887bec8SAndroid Build Coastguard Worker default=[], 279*7887bec8SAndroid Build Coastguard Worker help='glob pattern and mode to set on files matching pattern (e.g. --mode_override "*.sh" "755")' 280*7887bec8SAndroid Build Coastguard Worker ) 281*7887bec8SAndroid Build Coastguard Worker return parser 282*7887bec8SAndroid Build Coastguard Worker 283*7887bec8SAndroid Build Coastguard Workerdef main(): 284*7887bec8SAndroid Build Coastguard Worker args = sys.argv[1:] 285*7887bec8SAndroid Build Coastguard Worker args.remove(_CMDLINE_FLAGS_SENTINEL) 286*7887bec8SAndroid Build Coastguard Worker args = _get_parser().parse_args(args) 287*7887bec8SAndroid Build Coastguard Worker 288*7887bec8SAndroid Build Coastguard Worker config_logging(args.log) 289*7887bec8SAndroid Build Coastguard Worker 290*7887bec8SAndroid Build Coastguard Worker # Warn about arguments that should not be set in command line. 291*7887bec8SAndroid Build Coastguard Worker _get_parser(cmdline=True).parse_args( 292*7887bec8SAndroid Build Coastguard Worker sys.argv[sys.argv.index(_CMDLINE_FLAGS_SENTINEL) + 1:]) 293*7887bec8SAndroid Build Coastguard Worker 294*7887bec8SAndroid Build Coastguard Worker mode_overrides = [] 295*7887bec8SAndroid Build Coastguard Worker for (pattern, mode) in args.mode_override: 296*7887bec8SAndroid Build Coastguard Worker try: 297*7887bec8SAndroid Build Coastguard Worker mode_overrides.append((pattern, int(mode, 8))) 298*7887bec8SAndroid Build Coastguard Worker except ValueError: 299*7887bec8SAndroid Build Coastguard Worker logging.error("invalid octal permissions: %s", mode) 300*7887bec8SAndroid Build Coastguard Worker sys.exit(1) 301*7887bec8SAndroid Build Coastguard Worker 302*7887bec8SAndroid Build Coastguard Worker if not os.path.isabs(args.dist_dir): 303*7887bec8SAndroid Build Coastguard Worker # BUILD_WORKSPACE_DIRECTORY is the root of the Bazel workspace containing 304*7887bec8SAndroid Build Coastguard Worker # this binary target. 305*7887bec8SAndroid Build Coastguard Worker # https://docs.bazel.build/versions/main/user-manual.html#run 306*7887bec8SAndroid Build Coastguard Worker args.dist_dir = os.path.join( 307*7887bec8SAndroid Build Coastguard Worker os.environ.get("BUILD_WORKSPACE_DIRECTORY"), args.dist_dir) 308*7887bec8SAndroid Build Coastguard Worker 309*7887bec8SAndroid Build Coastguard Worker files = files_to_dist("*_dist_manifest.txt") 310*7887bec8SAndroid Build Coastguard Worker archives = files_to_dist("*_dist_archives_manifest.txt") 311*7887bec8SAndroid Build Coastguard Worker copy_files_to_dist_dir(files, archives, mode_overrides, **vars(args)) 312*7887bec8SAndroid Build Coastguard Worker 313*7887bec8SAndroid Build Coastguard Worker 314*7887bec8SAndroid Build Coastguard Workerif __name__ == "__main__": 315*7887bec8SAndroid Build Coastguard Worker main() 316