blob: a519d99f2102b5d2c34ee6e3cdec073aa76993e2 [file] [log] [blame]
#!/bin/bash
# Copyright 2021 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.
function usage() {
cat <<EOF
$0 [options] -- clippy-driver-arguments...
Options:
--help | -h : print help and exit
--output FILE : clippy file to output (required)
--jq FILE : path to 'jq' (required)
--fail : clippy cause failure
--quiet : produce output without printing or failing
EOF
}
output=
jq=
driver_options=()
fail=0
quiet=0
# Extract options before --
prev_opt=
for opt
do
# handle --option arg
if test -n "$prev_opt"
then
eval "$prev_opt"=\$opt
prev_opt=
shift
continue
fi
# Extract optarg from --opt=optarg
case "$opt" in
-*=*) optarg="${opt#*=}" ;; # remove-prefix, shortest-match
esac
case "$opt" in
--help|-h) usage ; exit ;;
--output) prev_opt=output ;;
--output=*) output="$optarg" ;;
--jq) prev_opt=jq ;;
--jq=*) jq="$optarg" ;;
--fail) fail=1 ;;
--quiet) quiet=1 ;;
# stop option processing
--) shift; break ;;
# Forward all other options to clippy-driver
*) driver_options+=( "$opt" ) ;;
esac
shift
done
test -z "$prev_out" || { echo "Option is missing argument to set $prev_opt." ; exit 1;}
test -n "$output" || { echo "Error: --output required, but missing." ; exit 1 ;}
test -n "$jq" || { echo "Error: --jq required, but missing." ; exit 1 ;}
# After -- the remaining args are the clippy-driver command and args set
# in the clippy GN template.
filtered_driver_options=()
for opt in "${driver_options[@]}" "$@"
do
# Extract optarg from --opt=optarg
case "$opt" in
-*=*) optarg="${opt#*=}" ;; # remove-prefix, shortest-match
esac
case "$opt" in
# Same transformation done in 'build/rbe/local-only.sh'
--local-only=* ) filtered_driver_options+=( "$optarg" ) ;;
--remote* ) ;; # pseudoflag for RBE parameters, drop it
*) filtered_driver_options+=( "$opt" )
esac
done
# $deps_rspfile contains --externs for direct dependencies
deps_rspfile="$output.deps"
transdeps=( $(sort -u "$output.transdeps") )
# Rewrite --externs to use rmetas where possible.
# Use rmetas where they exist, to avoid requiring local copies of full rlibs.
# Remote-build rlibs do not need to be downloaded, only their .rmeta are needed.
# Assume $deps_rspfile is formatted with one --extern per line.
while read line
do
case "$line" in
--extern=*=*.rlib)
mapping="${line#--extern=}" # remove prefix (shortest-match)
lib_name="${mapping%%=*}" # remove suffix to get lib name (longest-match)
lib_path="${mapping#*=}" # remove prefix to get lib path (shortest-match)
rmeta="${lib_path/.rlib/.rmeta}"
# If the .rmeta exists, use it.
if [[ -r "$rmeta" ]]
then echo "--extern=$lib_name=$rmeta"
else
echo "Expecting $rmeta to exist, but did not find it." >&2
exit 1
fi
;;
*) # No change for all other cases, including --extern=...=*.so
echo "$line"
;;
esac
done < "$deps_rspfile" > "$deps_rspfile.alt"
command=(
"${filtered_driver_options[@]}"
-Zno_codegen
@"$deps_rspfile.alt"
"${transdeps[@]}"
--emit metadata="$output.rmeta"
--error-format=json
--json=diagnostic-rendered-ansi
)
RUSTC_LOG=error "${command[@]}" 2>"$output"
result="$?"
# clean-up temporary files
[[ "$result" != 0 ]] || {
rm -f "$deps_rspfile.alt"
}
# Print any detected lints if --quiet wasn't passed
if [[ "$quiet" = 0 ]]; then
"$jq" -sre '.[] | select((.level == "error") or (.level == "warning")) | .rendered' "$output" || cat "$output" >&2
fi
# Only fail the build with a nonzero exit code if --fail was passed
if [[ "$fail" = 1 ]]; then
exit "$result"
fi