kubernetes/hack/make-rules/helpers/cache_go_dirs.sh
Antonio Ojea 2fee0c45e6 skip hack/tools/vendor folder
The makefiles scripts create a variable with all the go files
that are part of the Kubernetes source tree, including staging.

As today, this variable has a size of < 100kb

wc .make/all_go_dirs.mk
2326  2326 98905 .make/all_go_dirs.mk

This variable is passed as argument in the Makefiles, where it
is expanded. In Linux, there is a limit to the max size of
the arguments MAX_ARG_STRLEN.

If the arguments go above 128k, you get a nice:

execvp: /usr/bin/env: Argument list too long

If you, for whatever reason, do some go mod vendor inside the
hack/tools folder, these files will be added to the variable
and most probably you'll go above the limit and get that error.

Then, you'll learn a lot about Makefils, shell expansion, strace,
execpve, ARG_MAX and MAX_ARG_STRLEN,until you realize what is
the real problem :).
2021-08-26 20:02:43 +02:00

76 lines
2.4 KiB
Bash
Executable File

#!/usr/bin/env bash
# Copyright 2014 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# This script finds, caches, and prints a list of all directories that hold
# *.go files. If any directory is newer than the cache, re-find everything and
# update the cache. Otherwise use the cached file.
set -o errexit
set -o nounset
set -o pipefail
if [[ -z "${1:-}" ]]; then
echo "usage: $0 <cache-file>"
exit 1
fi
CACHE="$1"; shift
trap 'rm -f "${CACHE}"' HUP INT TERM ERR
# This is a partial 'find' command. The caller is expected to pass the
# remaining arguments.
#
# Example:
# kfind -type f -name foobar.go
function kfind() {
# We want to include the "special" vendor directories which are actually
# part of the Kubernetes source tree (./staging/*) but we need them to be
# named as their ./vendor/* equivalents. Also, we do not want all of
# ./vendor , ./hack/tools/vendor or even all of ./vendor/k8s.io.
find -H . \
\( \
-not \( \
\( \
-name '_*' -o \
-name '.[^.]*' -o \
\( \
-name 'vendor' \
-type d \
\) \
\) -prune \
\) \
\) \
"$@" \
| sed 's|^./staging/src|vendor|'
}
# It's *significantly* faster to check whether any directories are newer than
# the cache than to blindly rebuild it.
if [[ -f "${CACHE}" && -n "${CACHE}" ]]; then
N=$(kfind -type d -newer "${CACHE}" -print -quit | wc -l)
if [[ "${N}" == 0 ]]; then
cat "${CACHE}"
exit
fi
fi
mkdir -p "$(dirname "${CACHE}")"
kfind -type f -name \*.go \
| sed 's|/[^/]*$||' \
| sed 's|^./||' \
| LC_ALL=C sort -u \
| tee "${CACHE}"