Android: Refactor dep_operations -> //build/gn_ast
These scripts belong in //build and should not have deps on //tools.
This CL is more of a simple move, subsequent CLs may combine some common
code with gn_ast.py.
This refactor also makes dep_operations.py easier to use via the
shortcut: //build/gn_editor
Bug: 1486020
Fixed: 1486020
Change-Id: I3d186616517a9c53addb0ac2960c1af047d4bfe5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4885960
Auto-Submit: Peter Wen <wnwen@chromium.org>
Reviewed-by: Andrew Grieve <agrieve@chromium.org>
Commit-Queue: Peter Wen <wnwen@chromium.org>
Commit-Queue: Andrew Grieve <agrieve@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1201207}
diff --git a/build/android/gyp/bytecode_processor.py b/build/android/gyp/bytecode_processor.py
index 421b54e..e6c41c3 100755
--- a/build/android/gyp/bytecode_processor.py
+++ b/build/android/gyp/bytecode_processor.py
@@ -21,8 +21,8 @@
import action_helpers # build_utils adds //build to sys.path.
_SRC_PATH = pathlib.Path(build_utils.DIR_SOURCE_ROOT).resolve()
-sys.path.append(str(_SRC_PATH / 'tools/android/modularization/gn'))
-from dep_operations import NO_VALID_GN_STR
+sys.path.append(str(_SRC_PATH / 'build/gn_ast'))
+from gn_editor import NO_VALID_GN_STR
def _ShouldIgnoreDep(dep_name: str):
diff --git a/build/android/gyp/bytecode_processor.pydeps b/build/android/gyp/bytecode_processor.pydeps
index 78db0c4..a729800 100644
--- a/build/android/gyp/bytecode_processor.pydeps
+++ b/build/android/gyp/bytecode_processor.pydeps
@@ -9,13 +9,10 @@
../../../third_party/catapult/devil/devil/android/sdk/version_codes.py
../../../third_party/catapult/devil/devil/constants/__init__.py
../../../third_party/catapult/devil/devil/constants/exit_codes.py
-../../../tools/android/modularization/gn/dep_operations.py
-../../../tools/android/modularization/gn/json_gn_editor.py
-../../../tools/android/modularization/gn/utils.py
-../../../tools/android/python_utils/__init__.py
-../../../tools/android/python_utils/git_metadata_utils.py
-../../../tools/android/python_utils/subprocess_utils.py
../../action_helpers.py
+../../gn_ast/gn_editor.py
+../../gn_ast/json_gn_editor.py
+../../gn_ast/utils.py
../../gn_helpers.py
../list_java_targets.py
../pylib/__init__.py
diff --git a/build/android/gyp/util/build_utils.py b/build/android/gyp/util/build_utils.py
index 752aa21..938c7041 100644
--- a/build/android/gyp/util/build_utils.py
+++ b/build/android/gyp/util/build_utils.py
@@ -224,6 +224,7 @@
logging.info('CheckOutput: %s', ' '.join(args))
child = subprocess.Popen(args,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd, env=env)
+
stdout, stderr = child.communicate()
# For Python3 only:
diff --git a/build/android/gyp/util/dep_utils.py b/build/android/gyp/util/dep_utils.py
index c849df6..cbf8937 100644
--- a/build/android/gyp/util/dep_utils.py
+++ b/build/android/gyp/util/dep_utils.py
@@ -255,8 +255,8 @@
build_file_path = GnTargetToBuildFilePath(gn_target)
return [
- 'tools/android/modularization/gn/dep_operations.py', 'add', '--quiet',
- '--file', build_file_path, '--target', gn_target, '--deps'
+ 'build/gn_editor', 'add', '--quiet', '--file', build_file_path,
+ '--target', gn_target, '--deps'
] + missing_deps
diff --git a/tools/android/modularization/gn/dep_operations.py b/build/gn_ast/gn_editor.py
similarity index 95%
rename from tools/android/modularization/gn/dep_operations.py
rename to build/gn_ast/gn_editor.py
index 797a4d0..3b63ba8 100755
--- a/tools/android/modularization/gn/dep_operations.py
+++ b/build/gn_ast/gn_editor.py
@@ -18,15 +18,19 @@
import json_gn_editor
import utils
-_TOOLS_ANDROID_PATH = pathlib.Path(__file__).resolve().parents[2]
-if str(_TOOLS_ANDROID_PATH) not in sys.path:
- sys.path.append(str(_TOOLS_ANDROID_PATH))
-from python_utils import git_metadata_utils, subprocess_utils
+_SRC_PATH = pathlib.Path(__file__).resolve().parents[2]
-_SRC_PATH = git_metadata_utils.get_chromium_src_path()
-sys.path.append(str(_SRC_PATH / 'build' / 'android'))
+_BUILD_ANDROID_PATH = _SRC_PATH / 'build/android'
+if str(_BUILD_ANDROID_PATH) not in sys.path:
+ sys.path.append(str(_BUILD_ANDROID_PATH))
from pylib import constants
+_BUILD_ANDROID_GYP_PATH = _SRC_PATH / 'build/android/gyp'
+if str(_BUILD_ANDROID_GYP_PATH) not in sys.path:
+ sys.path.append(str(_BUILD_ANDROID_GYP_PATH))
+
+from util import build_utils
+
_GIT_IGNORE_STR = '(git ignored file) '
NO_VALID_GN_STR = 'No valid GN files found after filtering.'
@@ -177,13 +181,13 @@
# TODO: Ensure that the build server is not running.
logging.info(f'Running "gn gen" in output directory: {out_dir}')
- subprocess_utils.run_command(['gn', 'gen', '-C', out_dir, '--ide=json'])
+ build_utils.CheckOutput(['gn', 'gen', '-C', out_dir, '--ide=json'])
if args.all_java_deps:
assert not args.dep, '--all-java-target does not support passing deps.'
assert args.file, '--all-java-target requires passing --file.'
logging.info(f'Finding java deps under {out_dir}.')
- all_java_deps = subprocess_utils.run_command([
+ all_java_deps = build_utils.CheckOutput([
str(_SRC_PATH / 'build' / 'android' / 'list_java_targets.py'),
'--gn-labels', '-C', out_dir
]).split('\n')
@@ -264,7 +268,7 @@
def main():
parser = argparse.ArgumentParser(
- description='Add or remove deps programatically.')
+ prog='gn_editor', description='Add or remove deps programatically.')
common_args_parser = argparse.ArgumentParser(add_help=False)
common_args_parser.add_argument(
@@ -287,7 +291,7 @@
help='Skip files before this build file path (debugging).')
subparsers = parser.add_subparsers(
- help='Use subcommand -h to see full usage.')
+ required=True, help='Use subcommand -h to see full usage.')
add_parser = subparsers.add_parser(
'add',
@@ -375,7 +379,7 @@
logging.basicConfig(
level=level, format='%(levelname).1s %(relativeCreated)7d %(message)s')
- root = git_metadata_utils.get_chromium_src_path()
+ root = _SRC_PATH
if args.file:
build_filepaths = [os.path.relpath(args.file, root)]
else:
diff --git a/tools/android/modularization/gn/json_gn_editor.py b/build/gn_ast/json_gn_editor.py
similarity index 96%
rename from tools/android/modularization/gn/json_gn_editor.py
rename to build/gn_ast/json_gn_editor.py
index ce67e86..abafb63 100644
--- a/tools/android/modularization/gn/json_gn_editor.py
+++ b/build/gn_ast/json_gn_editor.py
@@ -20,12 +20,13 @@
from typing import Dict, Iterator, List, Optional, Tuple
-_TOOLS_ANDROID_PATH = pathlib.Path(__file__).resolve().parents[2]
-if str(_TOOLS_ANDROID_PATH) not in sys.path:
- sys.path.insert(0, str(_TOOLS_ANDROID_PATH))
-from python_utils import git_metadata_utils, subprocess_utils
+_SRC_PATH = pathlib.Path(__file__).resolve().parents[2]
-_SRC_PATH = git_metadata_utils.get_chromium_src_path()
+_BUILD_ANDROID_GYP_PATH = _SRC_PATH / 'build/android/gyp'
+if str(_BUILD_ANDROID_GYP_PATH) not in sys.path:
+ sys.path.append(str(_BUILD_ANDROID_GYP_PATH))
+
+from util import build_utils
# Refer to parse_tree.cc for GN AST implementation details:
# https://gn.googlesource.com/gn/+/refs/heads/main/src/gn/parse_tree.cc
@@ -52,10 +53,10 @@
f.write(contents)
-def _build_targets_output(out_dir: str,
- targets: List[str],
- should_print: Optional[bool] = None
- ) -> Optional[str]:
+def _build_targets_output(
+ out_dir: str,
+ targets: List[str],
+ should_print: Optional[bool] = None) -> Optional[str]:
env = os.environ.copy()
if should_print is None:
should_print = logging.getLogger().isEnabledFor(logging.DEBUG)
@@ -102,7 +103,7 @@
def _generate_project_json_content(out_dir: str) -> str:
- subprocess_utils.run_command(['gn', 'gen', '--ide=json', out_dir])
+ build_utils.CheckOutput(['gn', 'gen', '--ide=json', out_dir])
with open(os.path.join(out_dir, 'project.json')) as f:
return f.read()
@@ -118,7 +119,6 @@
class BuildFile:
"""Represents the contents of a BUILD.gn file."""
-
def __init__(self,
build_gn_path: str,
root_gn_path: pathlib.Path,
@@ -131,7 +131,7 @@
self._skip_write_content = dryrun
def __enter__(self):
- output = subprocess_utils.run_command(
+ output = build_utils.CheckOutput(
['gn', 'format', '--dump-tree=json', self._full_path])
self._content = json.loads(output)
self._original_content = json.dumps(self._content)
@@ -141,7 +141,6 @@
if not self._skip_write_content:
self.write_content_to_file()
-
# See: https://gist.github.com/sgraham/bd9ffee312f307d5f417019a9c0f0777
def _find_all(self, match_fn):
results = []
@@ -226,7 +225,6 @@
return name
def _find_all_list_assignments(self):
-
def match_list_assignments(node):
r"""Matches and returns the list being assigned.
@@ -558,6 +556,8 @@
def write_content_to_file(self) -> None:
current_content = json.dumps(self._content)
if current_content != self._original_content:
- subprocess_utils.run_command(
+ subprocess.run(
['gn', 'format', '--read-tree=json', self._full_path],
- cmd_input=current_content)
+ text=True,
+ check=True,
+ input=current_content)
diff --git a/tools/android/modularization/gn/json_gn_editor_test.py b/build/gn_ast/json_gn_editor_test.py
similarity index 100%
rename from tools/android/modularization/gn/json_gn_editor_test.py
rename to build/gn_ast/json_gn_editor_test.py
diff --git a/tools/android/modularization/gn/utils.py b/build/gn_ast/utils.py
similarity index 75%
rename from tools/android/modularization/gn/utils.py
rename to build/gn_ast/utils.py
index aa4049e3..05fe41b 100644
--- a/tools/android/modularization/gn/utils.py
+++ b/build/gn_ast/utils.py
@@ -6,12 +6,7 @@
import logging
import os
import pathlib
-import sys
-
-_TOOLS_ANDROID_PATH = pathlib.Path(__file__).resolve().parents[2]
-if str(_TOOLS_ANDROID_PATH) not in sys.path:
- sys.path.append(str(_TOOLS_ANDROID_PATH))
-from python_utils import subprocess_utils
+import subprocess
# These paths should be relative to repository root.
_BAD_FILES = [
@@ -35,6 +30,6 @@
def is_git_ignored(root: pathlib.Path, filepath: str) -> bool:
# The command git check-ignore exits with 0 if the path is ignored, 1 if it
# is not ignored.
- exit_code = subprocess_utils.run_command(
- ['git', 'check-ignore', '-q', filepath], cwd=root, exitcode_only=True)
+ exit_code = subprocess.run(['git', 'check-ignore', '-q', filepath],
+ cwd=root).returncode
return exit_code == 0
diff --git a/build/gn_editor b/build/gn_editor
new file mode 100755
index 0000000..ecf86e8
--- /dev/null
+++ b/build/gn_editor
@@ -0,0 +1,8 @@
+#!/bin/bash
+# Copyright 2023 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+base_dir=$(dirname "$0")
+
+exec python3 "$base_dir/gn_ast/gn_editor.py" "$@"