blob: 4c39191d6e2cbae10a6a6b381c7a7b9f93859a53 [file] [log] [blame]
#!/usr/bin/env fuchsia-vendored-python
# Copyright 2020 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import argparse
import json
import os
import re
import subprocess
import sys
# Golden file build API module.
GOLDEN_FILES_JSON = "golden_files.json"
DESCRIPTION = """
Reruns golden file checks in the current build, relying on the
"golden_files" build API module. That is, unless `--list` is passed, in
which case this command only prints out the associated goldens.
The goldens may be filtered by a substring of their source path (e.g., a
full source-relative directory) or by a regular expression; if no search
term is provided, all accessible golden files will be matched.
TODO(crbug.com/gn/301): This command may deal in stale metadata. Until this
bug is resolved, users must take care to make sure their build metadata is
up to data (e.g., via `fx gen`) before invoking this command.
"""
def main():
parser = argparse.ArgumentParser(
prog="fx check-goldens",
formatter_class=argparse.RawTextHelpFormatter,
description=DESCRIPTION,
)
parser.add_argument(
"--list",
help="Whether to just list the goldens instead of updating them",
action="store_true",
)
parser.add_argument(
"--regex",
help="if set, the search term will be matched as a regular expression",
action="store_true",
)
parser.add_argument(
"--all",
help="if set, includes otherwise ignored, dynamically-specified goldens (i.e., those specified via a build-time manifest)",
action="store_true",
)
parser.add_argument(
"search_term",
help="search term to match golden files against",
nargs="?",
)
args = parser.parse_args()
build_dir = os.path.relpath(os.getenv("FUCHSIA_BUILD_DIR"))
if build_dir is None:
print("FUCHSIA_BUILD_DIR not set")
return 1
golden_files_json = os.path.join(build_dir, GOLDEN_FILES_JSON)
if not os.path.exists(golden_files_json):
subprocess.check_call(["fx", "gen"])
with open(golden_files_json) as f:
entries = json.load(f)
# Account for comparisons given indirectly via build-time manifests,
# ensuring that they are built before proceeding.
if args.all:
manifests = []
for entry in entries:
if "comparison_manifest" in entry:
manifests.append(entry["comparison_manifest"])
if manifests:
subprocess.check_call(["fx", "build"] + manifests)
# Reload `entries`, as the JSON file may have been regenerated.
with open(golden_files_json) as f:
entries = json.load(f)
def is_match(filename):
if not args.search_term:
return True
if args.regex:
return re.search(args.search_term, filename) != None
return args.search_term in filename
stamps = []
matches = []
for entry in entries:
comparisons = []
if "comparisons" in entry:
comparisons = entry["comparisons"]
elif args.all:
manifest = os.path.join(build_dir, entry["comparison_manifest"])
with open(manifest) as f:
comparisons = json.load(f)
matched = False
for comparison in comparisons:
golden = comparison["golden"]
if is_match(golden):
matched = True
matches.append(golden)
if matched:
stamps.append(entry["stamp"])
if args.list:
print("\n".join(matches))
elif stamps:
subprocess.check_call(["fx", "build"] + stamps)
if __name__ == "__main__":
sys.exit(main())