Move away from arrays to strings to fix several shellcheck-reported
issues. It isn't useful to expand the found files into arrays, because
only things that are checked are if the array is empty or the contents
of the first array item.
Fix also a shellcheck issue about using a literal string as regexp
match. It appears that the original reason for using a regexp was to
avoid specifying the directory in which the script is run. However, due
to the need of calling 'make generated_files', the directory is fixed
anyway, and the regexp can be left out.
Testing the change can be done with the following script which emulates
the different cases which the script can see. In the output the variable
'X' is the array and 'Z' is the string.
#!/bin/bash
set -o errexit
set -o nounset
set -o pipefail
function find_genfiles() {
find . \
\( \
-not \( \
\( \
-path ./_\* -o \
-path ./.\* \
\) -prune \
\) \
\) -name "$1"
}
# $1 = filename pattern as in "zz_generated.$1.go"
# $2 timestamp file
function newer() {
find_genfiles "$1" | while read -r F; do
if [[ "${F}" -nt "$2" ]]; then
echo "${F}"
fi
done
}
STAMP=stamp
mkdir -p xxx
touch xxx/foobar
touch "${STAMP}"
mkdir -p foo
touch foo/foobar
mkdir -p bar
touch bar/foobar
# two newer files
X=($(newer foobar "${STAMP}"))
if [[ "${#X[*]}" != 0 ]]; then
echo "X1:"
echo " ${X[*]:-(none)}"
fi
Z="$(newer foobar "${STAMP}")"
if [[ -n "$Z" ]]; then
echo "Z1:"
echo " ${Z}" | tr '\n' ' '
echo ""
fi
# no newer files
touch "${STAMP}"
X=($(newer foobar "${STAMP}"))
if [[ "${#X[*]}" != 0 ]]; then
echo "X2:"
echo " ${X[*]:-(none)}"
fi
Z="$(newer foobar "${STAMP}")"
if [[ -n "$Z" ]]; then
echo "Z2:"
echo " ${Z}" | tr '\n' ' '
echo ""
fi
# one newer file, name matches
touch "${STAMP}"
touch bar/foobar
X=($(newer foobar "${STAMP}"))
if [[ "${#X[@]}" != 1 || ! ( "${X[0]}" =~ "bar/foobar" ) ]]; then
echo "X3:"
echo " ${X[*]:-(none)}"
fi
Z="$(newer foobar "${STAMP}")"
if [[ -z "${Z}" || ${Z} != "./bar/foobar" ]]; then
echo "Z3:"
echo " ${Z:-(none)}" | tr '\n' ' '
echo ""
fi
# one newer file, name doesn't match
touch "${STAMP}"
touch foo/foobar
X=($(newer foobar "${STAMP}"))
if [[ "${#X[@]}" != 1 || ! ( "${X[0]}" =~ "bar/foobar" ) ]]; then
echo "X4:"
echo " ${X[*]:-(none)}"
fi
Z="$(newer foobar "${STAMP}")"
if [[ -z "${Z}" || ${Z} != "./bar/foobar" ]]; then
echo "Z4:"
echo " ${Z:-(none)}" | tr '\n' ' '
echo ""
fi
The expected output from running this script:
X1:
./bar/foobar ./foo/foobar
Z1:
./bar/foobar ./foo/foobar
X4:
./foo/foobar
Z4:
./foo/foobar
We already do this in hack/verify-generated-files.sh so we should do it
in verify-generated-files-remake.sh as well.
The idea is that any local changes made because of code generation
should not persist beyond the current run of the script.
Change-Id: I7af176773ae16c393dc2b46c006595243c9fa05b
'read' will not handle backslashes properly. 'read -r' is safer to use.
The find_genfiles() will not insert backslashes, so if there are any,
they will be from directory names.
The pattern used in the file is this:
echo " ${X[@]:-(none)}"
What happens is that the array is expanded to separate strings, and it
is checked if that's set (for the default value assignment). However,
the correct way is to check if the concatenated array string is set to
avoid a type mismatch:
echo " ${X[*]:-(none)}"
Tests show that at least bash 4.4.23 behaves the same:
X=(foo bar)
echo " ${X[@]:-(none)}"
echo " ${X[*]:-(none)}"
X=()
echo " ${X[@]:-(none)}"
echo " ${X[*]:-(none)}"
produces:
foo bar
foo bar
(none)
(none)
check in existing API rule violations;
the Make rule fails if generated violation report differs from the
checked-in violation file and prints error message;
add documentation.