kubernetes/hooks/pre-commit
Eric Paris f54098fe00 Verify all flag usage does not use _
This works by defining two 'static' lists in hack. The first is the list
of all flags in the project which use a `-` or an `_` in their name. All
files being processed by verify-flags-underscore.py (or all files in the
repo if no filename arguments are given) will be searched for flag
declaration using a simple regex. Its not super smart. If a flag is
found which is not in the static list it will complain/reject the commit
until a human adds it to the list. If we do not keep a static list of
flags it takes >.2 seconds to find them 'all' at runtime. Since this is
run in pre-commit saving every part of a second helps.

After it finds all of the flags it runs all of the arguments (or all
files in repo if no arguments) looking for usage of those flags which
includes an `_`. There are lots of places where these are false
positives. For example we have a flag named oom-adj-score but the kernel
calls it oom_adj_score. To handle this we keep a second 'whitelist' of
lines which are allowed to use these flag names with an `_`.

Running the entire git repo looking for flags in every golang file and
looking in every single file for bad usage takes about 8.75 seconds.

Running it in the precommit hook where we only check things that changed
takes about .06 seconds.
2015-08-12 16:17:02 -04:00

160 lines
4.3 KiB
Bash
Executable File

#!/bin/bash
readonly reset=$(tput sgr0)
readonly red=$(tput bold; tput setaf 1)
readonly green=$(tput bold; tput setaf 2)
exit_code=0
echo -ne "Checking that it builds... "
if ! OUT=$("hack/build-go.sh" 2>&1); then
echo
echo "${red}${OUT}"
exit_code=1
else
echo "${green}OK"
fi
echo "${reset}"
echo -ne "Checking for files that need gofmt... "
files_need_gofmt=()
files=($(git diff --cached --name-only --diff-filter ACM | grep "\.go" | grep -v -e "third_party" -e "Godeps"))
for file in "${files[@]}"; do
# Check for files that fail gofmt.
diff="$(git show ":${file}" | gofmt -s -d 2>&1)"
if [[ -n "$diff" ]]; then
files_need_gofmt+=("${file}")
fi
done
if [[ "${#files_need_gofmt[@]}" -ne 0 ]]; then
echo "${red}ERROR!"
echo "Some files have not been gofmt'd. To fix these errors, "
echo "cut and paste the following:"
echo " gofmt -s -w ${files_need_gofmt[@]}"
exit_code=1
else
echo "${green}OK"
fi
echo "${reset}"
echo -ne "Checking for files that need boilerplate... "
out=($(hack/verify-boilerplate.sh))
if [[ $? -ne 0 ]]; then
echo "${red}ERROR!"
echo "Some files are missing the required boilerplate header"
echo "from hooks/boilerplate.txt:"
for f in "${out[@]}"; do
echo " ${f}"
done
exit_code=1
else
echo "${green}OK"
fi
echo "${reset}"
allfiles=($(git diff --cached --name-only --diff-filter ACM | grep -v -e "third_party" -e "Godeps"))
echo -ne "Checking for problems with flag names... "
invalid_flag_lines=$(hack/verify-flags-underscore.py "${allfiles[@]}")
if [[ "${invalid_flag_lines:-}" != "" ]]; then
echo "${red}ERROR!"
echo "There appear to be problems with the following"
for line in "${invalid_flag_lines[@]}"; do
echo " ${line}"
done
exit_code=1
else
echo "${green}OK"
fi
echo "${reset}"
echo -ne "Checking for API descriptions... "
files_need_description=()
# Check API schema definitions for field descriptions
for file in $(git diff --cached --name-only --diff-filter ACM | egrep "pkg/api/v.[^/]*/types\.go" | grep -v "third_party"); do
# Check for files with fields without description tags
descriptionless=$(hack/after-build/verify-description.sh "${file}")
if [[ "$descriptionless" != "" ]]; then
files_need_description+=("${file}")
fi
done
if [[ "${#files_need_description[@]}" -ne 0 ]]; then
echo "${red}ERROR!"
echo "Some API files are missing the required field descriptions."
echo "Add description tags to all non-inline fields in the following files:"
for file in "${files_need_description[@]}"; do
echo " ${file}"
done
exit_code=1
else
echo "${green}OK"
fi
echo "${reset}"
echo -ne "Checking for links in API descriptions... "
if ! hack/after-build/verify-linkcheck.sh > /dev/null; then
echo "${red}ERROR!"
echo "Some links in pkg/api/.*types.go are outdated. They require a manual fix."
exit_code=1
else
echo "${green}OK"
fi
echo "${reset}"
echo -ne "Checking for docs that need updating... "
if ! hack/after-build/verify-generated-docs.sh > /dev/null; then
echo "${red}ERROR!"
echo "Some docs are out of sync between CLI and markdown."
echo "To regenerate docs, run:"
echo " hack/update-generated-docs.sh"
exit_code=1
else
echo "${green}OK"
fi
echo "${reset}"
echo -ne "Checking for conversions that need updating... "
if ! hack/after-build/verify-generated-conversions.sh > /dev/null; then
echo "${red}ERROR!"
echo "Some conversions functions need regeneration."
echo "To regenerate conversions, run:"
echo " hack/update-generated-conversions.sh"
exit_code=1
else
echo "${green}OK"
fi
echo "${reset}"
echo -ne "Checking for deep-copies that need updating... "
if ! hack/after-build/verify-generated-deep-copies.sh > /dev/null; then
echo "${red}ERROR!"
echo "Some deep-copy functions need regeneration."
echo "To regenerate deep-copies, run:"
echo " hack/update-generated-deep-copies.sh"
exit_code=1
else
echo "${green}OK"
fi
echo "${reset}"
echo -ne "Checking for swagger spec that need updating... "
if ! hack/after-build/verify-swagger-spec.sh > /dev/null; then
echo "${red}ERROR!"
echo "Swagger spec needs to be updated."
echo "To regenerate the spec, run:"
echo " hack/update-swagger-spec.sh"
exit_code=1
else
echo "${green}OK"
fi
echo "${reset}"
if [[ "${exit_code}" != 0 ]]; then
echo "${red}Aborting commit${reset}"
fi
exit ${exit_code}
# ex: ts=2 sw=2 et filetype=sh