147 lines
5.3 KiB
Python
Executable File
147 lines
5.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# Copyright 2022 The Chromium Authors
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
"""Wrapper script to run action remotely through rewrapper with gn.
|
|
|
|
Also includes Chromium-specific input processors which don't make sense to
|
|
be reclient inbuilt input processors."""
|
|
|
|
import argparse
|
|
import json
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
from enum import Enum
|
|
|
|
_THIS_DIR = os.path.realpath(os.path.dirname(__file__))
|
|
_SRC_DIR = os.path.dirname(os.path.dirname(_THIS_DIR))
|
|
_MOJOM_DIR = os.path.join(_SRC_DIR, 'mojo', 'public', 'tools', 'mojom')
|
|
|
|
|
|
class CustomProcessor(Enum):
|
|
mojom_parser = 'mojom_parser'
|
|
|
|
def __str__(self):
|
|
return self.value
|
|
|
|
|
|
def _process_build_metadata_json(bm_file, input_roots, output_root, re_outputs,
|
|
processed_inputs):
|
|
"""Recursively find mojom_parser inputs from a build_metadata file."""
|
|
# Import Mojo-specific dep here so non-Mojo remote actions don't need it.
|
|
if _MOJOM_DIR not in sys.path:
|
|
sys.path.insert(0, _MOJOM_DIR)
|
|
from mojom_parser import RebaseAbsolutePath
|
|
|
|
if bm_file in processed_inputs:
|
|
return
|
|
|
|
processed_inputs.add(bm_file)
|
|
|
|
bm_dir = os.path.dirname(bm_file)
|
|
|
|
with open(bm_file) as f:
|
|
bm = json.load(f)
|
|
|
|
# All sources and corresponding module files are inputs.
|
|
for s in bm["sources"]:
|
|
src = os.path.normpath(os.path.join(bm_dir, s))
|
|
if src not in processed_inputs and os.path.exists(src):
|
|
processed_inputs.add(src)
|
|
src_module = os.path.join(
|
|
output_root,
|
|
RebaseAbsolutePath(os.path.abspath(src), input_roots) + "-module")
|
|
if src_module in re_outputs:
|
|
continue
|
|
if src_module not in processed_inputs and os.path.exists(src_module):
|
|
processed_inputs.add(src_module)
|
|
|
|
# Recurse into build_metadata deps.
|
|
for d in bm["deps"]:
|
|
dep = os.path.normpath(os.path.join(bm_dir, d))
|
|
_process_build_metadata_json(dep, input_roots, output_root, re_outputs,
|
|
processed_inputs)
|
|
|
|
|
|
def _get_mojom_parser_inputs(exec_root, output_files, extra_args):
|
|
"""Get mojom inputs by walking generated build_metadata files.
|
|
|
|
This is less complexity and disk I/O compared to parsing mojom files for
|
|
imports and finding all imports.
|
|
|
|
Start from the root build_metadata file passed to mojom_parser's
|
|
--check-imports flag.
|
|
"""
|
|
argparser = argparse.ArgumentParser()
|
|
argparser.add_argument('--check-imports', dest='check_imports', required=True)
|
|
argparser.add_argument('--output-root', dest='output_root', required=True)
|
|
argparser.add_argument('--input-root',
|
|
default=[],
|
|
action='append',
|
|
dest='input_root_paths')
|
|
mojom_parser_args, _ = argparser.parse_known_args(args=extra_args)
|
|
|
|
input_roots = list(map(os.path.abspath, mojom_parser_args.input_root_paths))
|
|
output_root = os.path.abspath(mojom_parser_args.output_root)
|
|
processed_inputs = set()
|
|
_process_build_metadata_json(mojom_parser_args.check_imports, input_roots,
|
|
output_root, output_files, processed_inputs)
|
|
|
|
# Rebase paths onto rewrapper exec root.
|
|
return map(lambda dep: os.path.normpath(os.path.relpath(dep, exec_root)),
|
|
processed_inputs)
|
|
|
|
|
|
def main():
|
|
# Set up argparser with some rewrapper flags.
|
|
argparser = argparse.ArgumentParser(description='rewrapper executor for gn',
|
|
allow_abbrev=False)
|
|
argparser.add_argument('--custom_processor',
|
|
type=CustomProcessor,
|
|
choices=list(CustomProcessor))
|
|
argparser.add_argument('rewrapper_path')
|
|
argparser.add_argument('--input_list_paths')
|
|
argparser.add_argument('--output_list_paths')
|
|
argparser.add_argument('--exec_root')
|
|
parsed_args, extra_args = argparser.parse_known_args()
|
|
|
|
# This script expects to be calling rewrapper.
|
|
args = [parsed_args.rewrapper_path]
|
|
|
|
# Get the output files list.
|
|
output_files = set()
|
|
with open(parsed_args.output_list_paths, 'r') as file:
|
|
for line in file:
|
|
output_files.add(line.rstrip('\n'))
|
|
|
|
# Scan for and add explicit inputs for rewrapper if necessary.
|
|
# These should be in a new input list paths file, as using --inputs can fail
|
|
# if the list is extremely large.
|
|
if parsed_args.custom_processor == CustomProcessor.mojom_parser:
|
|
root, ext = os.path.splitext(parsed_args.input_list_paths)
|
|
extra_inputs = _get_mojom_parser_inputs(parsed_args.exec_root, output_files,
|
|
extra_args)
|
|
extra_input_list_path = '%s__extra%s' % (root, ext)
|
|
with open(extra_input_list_path, 'w') as file:
|
|
with open(parsed_args.input_list_paths, 'r') as inputs:
|
|
file.write(inputs.read())
|
|
file.write("\n".join(extra_inputs))
|
|
args += ["--input_list_paths=%s" % extra_input_list_path]
|
|
else:
|
|
args += ["--input_list_paths=%s" % parsed_args.input_list_paths]
|
|
|
|
# Filter out --custom_processor= which is a flag for this script,
|
|
# and filter out --input_list_paths= because we replace it above.
|
|
# Pass on the rest of the args to rewrapper.
|
|
args_rest = filter(lambda arg: '--custom_processor=' not in arg, sys.argv[2:])
|
|
args += filter(lambda arg: '--input_list_paths=' not in arg, args_rest)
|
|
|
|
# Run rewrapper.
|
|
proc = subprocess.run(args)
|
|
return proc.returncode
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|