blob: c4d395c952bec67432fbd5a65e892e9579f50309 [file] [log] [blame]
#!/bin/bash
# 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.
#### CATEGORY=Source tree
### regenerates golden files in the source tree
## Usage: fx regen-goldens PATTERN ... [--list] [--reset] [FX_TEST_FLAGS]
##
## Regenerates golden files for tools that match the given substring patterns.
## If no patterns are provided, regenerates for all tools.
##
## --list List matching tools and their golden directories, and exit.
## --reset Delete existing goldens first. (See "Troubleshooting" below.)
##
## All other flags are forwarded to fx test. A useful one is -o/--output to
## show test output, which prints the filenames being regenerated.
##
## Examples:
##
## fx regen-goldens # regen all goldens
## fx regen-goldens fidlgen_ # regen fidlgen_* goldens
## fx regen-goldens fidlc -o # regen fidlc goldens, with verbose output
##
## Troubleshooting:
##
## Try passing the --reset flag if you encounter one of these situations:
##
## GN error, when goldens.txt is missing:
## ERROR at //build/testing/golden_test.gni:86:28: Could not read file.
## goldens_list = read_file("${invoker.goldens_dir}/goldens.txt", ...)
##
## Ninja error, when goldens.txt contains nonexistent files:
## ninja: error: '.../foo.golden', needed by 'host_x64/gen/.../foo.golden',
## missing and no known rule to make it
##
## Formatting error, when goldens have invalid syntax (e.g. from a merge conflict):
## ACTION //..._reformat_goldens(//build/toolchain:host_x64)
## /usr/bin/env /bin/sh -c \'.../rustfmt\'\ ...
## error: expected identifier, found `<<`
set -eo pipefail
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"/../lib/vars.sh || exit $?
fx-config-read
# Each tool $t has a NAME=${t%% *} and DIR=${t##* }, for which there must exist
# $(dirname $DIR)/BUILD.gn containing golden_test("${NAME}_golden_tests") with
# goldens_dir="$(basename $DIR)", and also group("tests") containing
# ":${NAME}_golden_tests($host_toolchain)". See //build/testing/golden_test.gni
# for more information about golden tests.
#
# Please keep this list sorted alphabetically.
readonly all_tools=(
"fidlc tools/fidl/fidlc/goldens"
"fidldoc tools/fidl/fidldoc/goldens"
"fidlgen_dart tools/fidl/fidlgen_dart/goldens"
"fidlgen_go tools/fidl/fidlgen_go/goldens"
"fidlgen_hlcpp tools/fidl/fidlgen_hlcpp/goldens"
"fidlgen_libfuzzer tools/fidl/fidlgen_libfuzzer/goldens"
"fidlgen_llcpp tools/fidl/fidlgen_llcpp/goldens"
"fidlgen_rust tools/fidl/fidlgen_rust/goldens"
"fidlgen_syzkaller tools/fidl/fidlgen_syzkaller/goldens"
"gidl tools/fidl/gidl/goldens"
)
# This environment variable is only set during tests.
# See //tools/devshell/tests/subcommands/fx_regen_goldens_test.
if [[ -z ${REGEN_GOLDENS_SKIP_CHECK+x} ]]; then
for t in "${all_tools[@]}"; do
dir=${t##* }
if ! [[ -d "$FUCHSIA_DIR/$dir" ]]; then
echo "WARNING: regen-goldens has invalid goldens dir '$dir'" >&2
fi
done
fi
tools=()
flags=()
list=false
reset=false
for arg in "$@"; do
case $arg in
-h|--help) fx-command-help; exit ;;
--list) list=true ;;
--reset) reset=true ;;
-*) flags+=("$arg") ;;
*)
found=false
for t in "${all_tools[@]}"; do
if [[ "${t%% *}" == *"$arg"* ]]; then
tools+=("$t")
found=true
fi
done
if [[ "$found" == false ]]; then
echo "No tools match the pattern '$arg'." >&2
echo "Run \`fx regen-goldens --list\` to see supported tools." >&2
exit 1
fi
;;
esac
done
if [[ "${#tools[@]}" -eq 0 ]]; then
tools=("${all_tools[@]}")
fi
if [[ $list == true ]]; then
{ IFS=$'\n'; lines=${tools[*]}; }
column -t <<< "$lines"
exit
fi
if [[ $reset == true ]]; then
for t in "${tools[@]}"; do
echo "Deleting goldens for: ${t%% *}"
dir="$FUCHSIA_DIR/${t##* }"
if ! [[ -d "$dir" ]]; then
echo "ERROR: directory not found: $dir" >&2
exit 1
fi
find "$dir" -maxdepth 1 -type f -name "*.golden" -delete
echo -n > "$dir/goldens.txt"
done
fi
tests=()
for t in "${tools[@]}"; do
tests+=("${t%% *}_golden_tests")
done
echo "Regenerating goldens for: ${tools[*]%% *}"
exit_code=0
"$(find_executable test)" "${tests[@]}" "${flags[@]}" -- --regen || exit_code=$?
# The fx test exit codes are defined in scripts/fxtest/lib/constants.dart.
case $exit_code in
2) # fatal error (all "Troubleshooting" examples exit with code 2)
if [[ $reset == false ]]; then
echo
echo "Hint: Try again with --reset: \`fx regen-goldens $* --reset\`"
fi
;;
3) # test not found
echo "Error: Could not find test targets needed to regenerate goldens"
with=()
for t in "${tools[@]}"; do
parent=$(dirname "${t##* }")
target="//$parent:${t%% *}_golden_tests"
if ! fx-command-run jq -e \
"any(.test.label | startswith(\"$target\"))" \
"$FUCHSIA_BUILD_DIR/tests.json" > /dev/null; then
with+=("--with" "//$parent:tests")
fi
done
if [[ ${#with[@]} -gt 0 ]]; then
echo "Hint: Try again after \`fx set ... ${with[*]}\`"
fi
;;
esac
exit $exit_code