Add shell script linting with shellcheck for better portability

This commit is contained in:
Damien Duportal 2019-05-10 17:24:06 +02:00 committed by Traefiker Bot
parent ab60e702d2
commit 886a6bdbe0
15 changed files with 87 additions and 57 deletions

View file

@ -5,4 +5,4 @@ ci_retry make validate
if [ -n "$SHOULD_TEST" ]; then ci_retry make test-unit; fi if [ -n "$SHOULD_TEST" ]; then ci_retry make test-unit; fi
if [ -n "$SHOULD_TEST" ]; then make -j${N_MAKE_JOBS} crossbinary-default-parallel; fi if [ -n "$SHOULD_TEST" ]; then make -j"${N_MAKE_JOBS}" crossbinary-default-parallel; fi

View file

@ -3,9 +3,10 @@ set -e
export DOCKER_VERSION=17.03.1 export DOCKER_VERSION=17.03.1
# shellcheck source=/dev/null
source .semaphoreci/vars source .semaphoreci/vars
if [ -z "${PULL_REQUEST_NUMBER}" ]; then SHOULD_TEST="-*-"; else TEMP_STORAGE=$(curl --silent https://patch-diff.githubusercontent.com/raw/containous/traefik/pull/${PULL_REQUEST_NUMBER}.diff | patch --dry-run -p1 -R); fi if [ -z "${PULL_REQUEST_NUMBER}" ]; then SHOULD_TEST="-*-"; else TEMP_STORAGE=$(curl --silent https://patch-diff.githubusercontent.com/raw/containous/traefik/pull/"${PULL_REQUEST_NUMBER}".diff | patch --dry-run -p1 -R); fi
if [ -n "$TEMP_STORAGE" ]; then SHOULD_TEST=$(echo "$TEMP_STORAGE" | grep -Ev '(.md|.yaml|.yml)' || :); fi if [ -n "$TEMP_STORAGE" ]; then SHOULD_TEST=$(echo "$TEMP_STORAGE" | grep -Ev '(.md|.yaml|.yml)' || :); fi

View file

@ -24,8 +24,8 @@ function ci_retry {
until [ $n -ge $NRETRY ] until [ $n -ge $NRETRY ]
do do
"$@" && break "$@" && break
n=$[$n+1] n=$((n+1))
echo "$@ failed, attempt ${n}/${NRETRY}" echo "${*} failed, attempt ${n}/${NRETRY}"
sleep $NSLEEP sleep $NSLEEP
done done
@ -34,4 +34,3 @@ function ci_retry {
} }
export -f ci_retry export -f ci_retry

View file

@ -96,10 +96,12 @@ test-integration: $(PRE_TARGET)
## Validate code and docs ## Validate code and docs
validate-files: $(PRE_TARGET) validate-files: $(PRE_TARGET)
$(if $(PRE_TARGET),$(DOCKER_RUN_TRAEFIK)) ./script/make.sh generate validate-lint validate-misspell $(if $(PRE_TARGET),$(DOCKER_RUN_TRAEFIK)) ./script/make.sh generate validate-lint validate-misspell
bash $(CURDIR)/script/validate-shell-script.sh
## Validate code, docs, and vendor ## Validate code, docs, and vendor
validate: $(PRE_TARGET) validate: $(PRE_TARGET)
$(if $(PRE_TARGET),$(DOCKER_RUN_TRAEFIK)) ./script/make.sh generate validate-lint validate-misspell validate-vendor $(if $(PRE_TARGET),$(DOCKER_RUN_TRAEFIK)) ./script/make.sh generate validate-lint validate-misspell validate-vendor
bash $(CURDIR)/script/validate-shell-script.sh
## Clean up static directory and build a Docker Traefik image ## Clean up static directory and build a Docker Traefik image
build-image: binary build-image: binary

View file

@ -43,7 +43,7 @@ $ ls dist/
traefik* traefik*
``` ```
The following targets can be executed outside Docker (we don't recommend that): The following targets can be executed outside Docker by setting the variable `PRE_TARGET` to an empty string (we don't recommend that):
- `test-unit` - `test-unit`
- `test-integration` - `test-integration`

View file

@ -8,9 +8,9 @@ fi
rm -f dist/traefik rm -f dist/traefik
FLAGS="" FLAGS=()
if [ -n "$VERBOSE" ]; then if [ -n "$VERBOSE" ]; then
FLAGS="${FLAGS} -v" FLAGS+=(-v)
fi fi
if [ -z "$VERSION" ]; then if [ -z "$VERSION" ]; then
@ -26,7 +26,7 @@ if [ -z "$DATE" ]; then
fi fi
# Build binaries # Build binaries
CGO_ENABLED=0 GOGC=off go build $FLAGS -ldflags "-s -w \ CGO_ENABLED=0 GOGC=off go build "${FLAGS[@]}" -ldflags "-s -w \
-X github.com/containous/traefik/pkg/version.Version=$VERSION \ -X github.com/containous/traefik/pkg/version.Version=$VERSION \
-X github.com/containous/traefik/pkg/version.Codename=$CODENAME \ -X github.com/containous/traefik/pkg/version.Codename=$CODENAME \
-X github.com/containous/traefik/pkg/version.BuildDate=$DATE" \ -X github.com/containous/traefik/pkg/version.BuildDate=$DATE" \

View file

@ -27,12 +27,12 @@ GO_BUILD_OPT="-s -w -X ${GIT_REPO_URL}.Version=${VERSION} -X ${GIT_REPO_URL}.Cod
# Build amd64 binaries # Build amd64 binaries
OS_PLATFORM_ARG=(linux windows darwin) OS_PLATFORM_ARG=(linux windows darwin)
OS_ARCH_ARG=(amd64) OS_ARCH_ARG=(amd64)
for OS in ${OS_PLATFORM_ARG[@]}; do for OS in "${OS_PLATFORM_ARG[@]}"; do
BIN_EXT='' BIN_EXT=''
if [ "$OS" == "windows" ]; then if [ "$OS" == "windows" ]; then
BIN_EXT='.exe' BIN_EXT='.exe'
fi fi
for ARCH in ${OS_ARCH_ARG[@]}; do for ARCH in "${OS_ARCH_ARG[@]}"; do
echo "Building binary for ${OS}/${ARCH}..." echo "Building binary for ${OS}/${ARCH}..."
GOARCH=${ARCH} GOOS=${OS} CGO_ENABLED=0 ${GO_BUILD_CMD} "${GO_BUILD_OPT}" -o "dist/traefik_${OS}-${ARCH}${BIN_EXT}" ./cmd/traefik/ GOARCH=${ARCH} GOOS=${OS} CGO_ENABLED=0 ${GO_BUILD_CMD} "${GO_BUILD_OPT}" -o "dist/traefik_${OS}-${ARCH}${BIN_EXT}" ./cmd/traefik/
done done
@ -41,8 +41,8 @@ done
# Build arm64 binaries # Build arm64 binaries
OS_PLATFORM_ARG=(linux) OS_PLATFORM_ARG=(linux)
OS_ARCH_ARG=(arm64) OS_ARCH_ARG=(arm64)
for OS in ${OS_PLATFORM_ARG[@]}; do for OS in "${OS_PLATFORM_ARG[@]}"; do
for ARCH in ${OS_ARCH_ARG[@]}; do for ARCH in "${OS_ARCH_ARG[@]}"; do
echo "Building binary for ${OS}/${ARCH}..." echo "Building binary for ${OS}/${ARCH}..."
GOARCH=${ARCH} GOOS=${OS} CGO_ENABLED=0 ${GO_BUILD_CMD} "${GO_BUILD_OPT}" -o "dist/traefik_${OS}-${ARCH}" ./cmd/traefik/ GOARCH=${ARCH} GOOS=${OS} CGO_ENABLED=0 ${GO_BUILD_CMD} "${GO_BUILD_OPT}" -o "dist/traefik_${OS}-${ARCH}" ./cmd/traefik/
done done

View file

@ -8,12 +8,16 @@ else
exit 0 exit 0
fi fi
SCRIPT_DIR="$( cd "$( dirname "${0}" )" && pwd -P)"
git config --global user.email "$TRAEFIKER_EMAIL" git config --global user.email "$TRAEFIKER_EMAIL"
git config --global user.name "Traefiker" git config --global user.name "Traefiker"
# load ssh key # load ssh key
echo "Loading key..." echo "Loading key..."
openssl aes-256-cbc -K $encrypted_f9e835a425bc_key -iv $encrypted_f9e835a425bc_iv -in .travis/traefiker_rsa.enc -out ~/.ssh/traefiker_rsa -d ${encrypted_f9e835a425bc_key:?}
${encrypted_f9e835a425bc_iv:?}
openssl aes-256-cbc -K "${encrypted_f9e835a425bc_key}" -iv "${encrypted_f9e835a425bc_iv}" -in .travis/traefiker_rsa.enc -out ~/.ssh/traefiker_rsa -d
eval "$(ssh-agent -s)" eval "$(ssh-agent -s)"
chmod 600 ~/.ssh/traefiker_rsa chmod 600 ~/.ssh/traefiker_rsa
ssh-add ~/.ssh/traefiker_rsa ssh-add ~/.ssh/traefiker_rsa
@ -21,14 +25,14 @@ ssh-add ~/.ssh/traefiker_rsa
# update traefik-library-image repo (official Docker image) # update traefik-library-image repo (official Docker image)
echo "Updating traefik-library-imag repo..." echo "Updating traefik-library-imag repo..."
git clone git@github.com:containous/traefik-library-image.git git clone git@github.com:containous/traefik-library-image.git
cd traefik-library-image cd "${SCRIPT_DIR}"/traefik-library-image
./updatev2.sh $VERSION "${SCRIPT_DIR}"/traefik-library-image/updatev2.sh "${VERSION}"
git add -A git add -A
echo $VERSION | git commit --file - echo "${VERSION}" | git commit --file -
echo $VERSION | git tag -a $VERSION --file - echo "${VERSION}" | git tag -a "${VERSION}" --file -
git push -q --follow-tags -u origin master > /dev/null 2>&1 git push -q --follow-tags -u origin master > /dev/null 2>&1
cd .. cd "${SCRIPT_DIR}"
rm -Rf traefik-library-image/ rm -Rf traefik-library-image/
echo "Deployed" echo "Deployed"

View file

@ -11,20 +11,21 @@ DEFAULT_BUNDLES=(
test-integration test-integration
) )
SCRIPT_DIR="$(cd "$(dirname "${0}")" && pwd -P)"
bundle() { bundle() {
local bundle="$1"; shift local bundle="$1"; shift
echo "---> Making bundle: $(basename "$bundle") (in $DEST)" echo "---> Making bundle: $(basename "$bundle") (in $SCRIPT_DIR)"
source "script/$bundle" "$@" # shellcheck source=/dev/null
source "${SCRIPT_DIR}/$bundle"
} }
if [ $# -lt 1 ]; then if [ $# -lt 1 ]; then
bundles=(${DEFAULT_BUNDLES[@]}) bundles=${DEFAULT_BUNDLES[*]}
else else
bundles=($@) bundles=${*}
fi fi
for bundle in ${bundles[@]}; do for bundle in ${bundles[*]}; do
export DEST=.
ABS_DEST="$(cd "$DEST" && pwd -P)"
bundle "$bundle" bundle "$bundle"
echo echo
done done

View file

@ -1,28 +1,26 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
SCRIPT_DIR="$( cd "$( dirname "${0}" )" && pwd -P)"; export SCRIPT_DIR
export DEST=. export DEST=.
TESTFLAGS="${TESTFLAGS} -test.timeout=20m -check.v" TESTFLAGS+=("-test.timeout=20m" -check.v)
if [ -n "$VERBOSE" ]; then if [ -n "$VERBOSE" ]; then
TESTFLAGS="${TESTFLAGS} -v" TESTFLAGS+=(-v)
elif [ -n "$VERBOSE_INTEGRATION" ]; then elif [ -n "$VERBOSE_INTEGRATION" ]; then
TESTFLAGS="${TESTFLAGS} -v" TESTFLAGS+=(-v)
fi fi
cd integration cd integration
echo "Testing against" echo "Testing against..."
docker version docker version
if [ -n "$TEST_CONTAINER" ]; then if [ -n "$TEST_CONTAINER" ]; then
echo "Testing from container…" echo "Testing from container…"
CGO_ENABLED=0 go test -integration -container $TESTFLAGS CGO_ENABLED=0 go test -integration -container "${TESTFLAGS[@]}"
fi fi
if [ -n "$TEST_HOST" ]; then if [ -n "$TEST_HOST" ]; then
echo "Testing from host…" echo "Testing from host…"
CGO_ENABLED=0 go test -integration -host $TESTFLAGS CGO_ENABLED=0 go test -integration -host "${TESTFLAGS[@]}"
fi fi

View file

@ -11,17 +11,17 @@ GREEN=$'\033[32m'
TEXTRESET=$'\033[0m' # reset the foreground colour TEXTRESET=$'\033[0m' # reset the foreground colour
# -failfast -timeout=5m # -failfast -timeout=5m
TESTFLAGS="-cover -coverprofile=cover.out ${TESTFLAGS}" TESTFLAGS=(-cover "-coverprofile=cover.out" "${TESTFLAGS}")
if [ -n "$VERBOSE" ]; then if [ -n "$VERBOSE" ]; then
TESTFLAGS="${TESTFLAGS} -v" TESTFLAGS+=(-v)
elif [ -n "$VERBOSE_UNIT" ]; then elif [ -n "$VERBOSE_UNIT" ]; then
TESTFLAGS="${TESTFLAGS} -v" TESTFLAGS+=(-v)
fi fi
set +e set +e
go test ${TESTFLAGS} ./pkg/... go test "${TESTFLAGS[@]}" ./pkg/...
CODE=$? CODE=$?
if [ ${CODE} != 0 ]; then if [ ${CODE} != 0 ]; then

View file

@ -13,11 +13,11 @@ docker pull $CERT_IMAGE
# Fetch the latest certificates. # Fetch the latest certificates.
ID=$(docker run -d $CERT_IMAGE sh -c "apk --update upgrade && apk add ca-certificates && update-ca-certificates") ID=$(docker run -d $CERT_IMAGE sh -c "apk --update upgrade && apk add ca-certificates && update-ca-certificates")
docker logs -f $ID docker logs -f "${ID}"
docker wait $ID docker wait "${ID}"
# Update the local certificates. # Update the local certificates.
docker cp $ID:/etc/ssl/certs/ca-certificates.crt . docker cp "${ID}":/etc/ssl/certs/ca-certificates.crt "${SCRIPT_DIR}"
# Cleanup. # Cleanup.
docker rm -f $ID docker rm -f "${ID}"

View file

@ -3,12 +3,12 @@
HACK_DIR="$( cd "$( dirname "${0}" )" && pwd -P)"; export HACK_DIR HACK_DIR="$( cd "$( dirname "${0}" )" && pwd -P)"; export HACK_DIR
REPO_ROOT=${HACK_DIR}/.. REPO_ROOT=${HACK_DIR}/..
${REPO_ROOT}/vendor/k8s.io/code-generator/generate-groups.sh \ "${REPO_ROOT}"/vendor/k8s.io/code-generator/generate-groups.sh \
all \ all \
github.com/containous/traefik/pkg/provider/kubernetes/crd/generated \ github.com/containous/traefik/pkg/provider/kubernetes/crd/generated \
github.com/containous/traefik/pkg/provider/kubernetes/crd \ github.com/containous/traefik/pkg/provider/kubernetes/crd \
traefik:v1alpha1 \ traefik:v1alpha1 \
--go-header-file ${HACK_DIR}/boilerplate.go.tmpl \ --go-header-file "${HACK_DIR}"/boilerplate.go.tmpl \
$@ "$@"
deepcopy-gen --input-dirs github.com/containous/traefik/pkg/config -O zz_generated.deepcopy --go-header-file ${HACK_DIR}/boilerplate.go.tmpl deepcopy-gen --input-dirs github.com/containous/traefik/pkg/config -O zz_generated.deepcopy --go-header-file "${HACK_DIR}"/boilerplate.go.tmpl

View file

@ -1,8 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
IFS=$'\n' SCRIPT_DIR="$( cd "$( dirname "${0}" )" && pwd -P)"
files=( $( git ls-files 'docs/*.md' *.md ) ) files=()
unset IFS while IFS='' read -r line; do files+=("$line"); done < <(git ls-files "${SCRIPT_DIR}"/../'docs/*.md' "${SCRIPT_DIR}"/../*.md)
errors=() errors=()
for f in "${files[@]}"; do for f in "${files[@]}"; do

24
script/validate-shell-script.sh Executable file
View file

@ -0,0 +1,24 @@
#!/usr/bin/env bash
set -eu -o pipefail
script_dir="$( cd "$( dirname "${0}" )" && pwd -P)"
if command -v shellcheck
then
# The list of shell script come from the (grep ...) command, feeding the loop
while IFS= read -r script_to_check
do
# The shellcheck command are run in background, to have an overview of the linter (instead of a fail at first issue)
shellcheck "${script_to_check}" &
done < <( # Search all the repository for sh and bash shebangs, excluding .js and .md files
# the folders ".git" and "vendor" are also ignored
grep -rI '#!/' "${script_dir}"/.. \
| grep 'sh' | grep -v '.js' | grep -v '.md' \
| grep -v '.git/' | grep -v 'vendor/' \
| cut -d':' -f1
)
wait # Wait for all background command to be completed
else
echo "== Command shellcheck not found in your PATH. No shell script checked."
fi