8e908b221f
Test: ./build/make/tools/whichgit --modules out/target/product/coral/system.img Change-Id: Ibc6e208d75c8e68c8130dc9ba3fc7af51390691b
110 lines
3.9 KiB
Python
Executable file
110 lines
3.9 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
|
|
import argparse
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
|
|
def get_build_var(var):
|
|
return subprocess.run(["build/soong/soong_ui.bash","--dumpvar-mode", var],
|
|
check=True, capture_output=True, text=True).stdout.strip()
|
|
|
|
|
|
def get_sources(modules):
|
|
result = subprocess.run(["./prebuilts/build-tools/linux-x86/bin/ninja", "-f",
|
|
"out/combined-" + os.environ["TARGET_PRODUCT"] + ".ninja",
|
|
"-t", "inputs", "-d", ] + modules,
|
|
stderr=subprocess.STDOUT, stdout=subprocess.PIPE, check=False, text=True)
|
|
if result.returncode != 0:
|
|
sys.stderr.write(result.stdout)
|
|
sys.exit(1)
|
|
return set([f for f in result.stdout.split("\n") if not f.startswith("out/")])
|
|
|
|
|
|
def m_nothing():
|
|
result = subprocess.run(["build/soong/soong_ui.bash", "--build-mode", "--all-modules",
|
|
"--dir=" + os.getcwd(), "nothing"],
|
|
check=False, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, text=True)
|
|
if result.returncode != 0:
|
|
sys.stderr.write(result.stdout)
|
|
sys.exit(1)
|
|
|
|
|
|
def get_git_dirs():
|
|
text = subprocess.run(["repo","list"], check=True, capture_output=True, text=True).stdout
|
|
return [line.split(" : ")[0] + "/" for line in text.split("\n")]
|
|
|
|
|
|
def get_referenced_projects(git_dirs, files):
|
|
# files must be sorted
|
|
referenced_dirs = set()
|
|
prev_dir = None
|
|
for f in files:
|
|
# Optimization is ~5x speedup for large sets of files
|
|
if prev_dir:
|
|
if f.startswith(prev_dir):
|
|
referenced_dirs.add(d)
|
|
continue
|
|
for d in git_dirs:
|
|
if f.startswith(d):
|
|
referenced_dirs.add(d)
|
|
prev_dir = d
|
|
break
|
|
return [d[0:-1] for d in referenced_dirs]
|
|
|
|
|
|
def main(argv):
|
|
# Argument parsing
|
|
ap = argparse.ArgumentParser(description="List the required git projects for the given modules")
|
|
ap.add_argument("--products", nargs="*",
|
|
help="The TARGET_PRODUCT to check. If not provided just uses whatever has"
|
|
+ " already been built")
|
|
ap.add_argument("--variants", nargs="*",
|
|
help="The TARGET_BUILD_VARIANTS to check. If not provided just uses whatever has"
|
|
+ " already been built, or eng if --products is supplied")
|
|
ap.add_argument("--modules", nargs="*",
|
|
help="The build modules to check, or droid it not supplied")
|
|
ap.add_argument("--why", nargs="*",
|
|
help="Also print the input files used in these projects, or \"*\" for all")
|
|
args = ap.parse_args(argv[1:])
|
|
|
|
modules = args.modules if args.modules else ["droid"]
|
|
|
|
# Get the list of sources for all of the requested build combos
|
|
if not args.products and not args.variants:
|
|
sources = get_sources(modules)
|
|
else:
|
|
if not args.products:
|
|
sys.stderr.write("Error: --products must be supplied if --variants is supplied")
|
|
sys.exit(1)
|
|
sources = set()
|
|
build_num = 1
|
|
for product in args.products:
|
|
os.environ["TARGET_PRODUCT"] = product
|
|
variants = args.variants if args.variants else ["user", "userdebug", "eng"]
|
|
for variant in variants:
|
|
sys.stderr.write(f"Analyzing build {build_num} of {len(args.products)*len(variants)}\r")
|
|
os.environ["TARGET_BUILD_VARIANT"] = variant
|
|
m_nothing()
|
|
sources.update(get_sources(modules))
|
|
build_num += 1
|
|
sys.stderr.write("\n\n")
|
|
|
|
sources = sorted(sources)
|
|
|
|
# Print the list of git directories that has one or more of the sources in it
|
|
for project in sorted(get_referenced_projects(get_git_dirs(), sources)):
|
|
print(project)
|
|
if args.why:
|
|
if "*" in args.why or project in args.why:
|
|
prefix = project + "/"
|
|
for f in sources:
|
|
if f.startswith(prefix):
|
|
print(" " + f)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main(sys.argv))
|
|
|
|
|
|
# vim: set ts=2 sw=2 sts=2 expandtab nocindent tw=100:
|