diff --git a/.semaphoreci/job2.sh b/.semaphoreci/job2.sh index 68c21a281..f6d6939d3 100755 --- a/.semaphoreci/job2.sh +++ b/.semaphoreci/job2.sh @@ -5,4 +5,4 @@ ci_retry make validate 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 diff --git a/.semaphoreci/setup.sh b/.semaphoreci/setup.sh index 9eeec0b10..49ff70463 100755 --- a/.semaphoreci/setup.sh +++ b/.semaphoreci/setup.sh @@ -3,9 +3,10 @@ set -e export DOCKER_VERSION=17.03.1 +# shellcheck source=/dev/null 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 diff --git a/.semaphoreci/vars b/.semaphoreci/vars index 4f945f666..631289c78 100644 --- a/.semaphoreci/vars +++ b/.semaphoreci/vars @@ -24,8 +24,8 @@ function ci_retry { until [ $n -ge $NRETRY ] do "$@" && break - n=$[$n+1] - echo "$@ failed, attempt ${n}/${NRETRY}" + n=$((n+1)) + echo "${*} failed, attempt ${n}/${NRETRY}" sleep $NSLEEP done @@ -34,4 +34,3 @@ function ci_retry { } export -f ci_retry - diff --git a/Makefile b/Makefile index 42bd2012c..83bed6228 100644 --- a/Makefile +++ b/Makefile @@ -96,10 +96,12 @@ test-integration: $(PRE_TARGET) ## Validate code and docs validate-files: $(PRE_TARGET) $(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: $(PRE_TARGET) $(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 build-image: binary diff --git a/docs/content/contributing/building-testing.md b/docs/content/contributing/building-testing.md index c7b709901..99976f964 100644 --- a/docs/content/contributing/building-testing.md +++ b/docs/content/contributing/building-testing.md @@ -43,7 +43,7 @@ $ ls dist/ 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-integration` @@ -61,24 +61,24 @@ PRE_TARGET= make test-unit You need `go` v1.12+. !!! tip "Source Directory" - + It is recommended that you clone Traefik into the `~/go/src/github.com/containous/traefik` directory. This is the official golang workspace hierarchy that will allow dependencies to be properly resolved. !!! note "Environment" Set your `GOPATH` and `PATH` variable to be set to `~/go` via: - + ```bash export GOPATH=~/go export PATH=$PATH:$GOPATH/bin ``` - + For convenience, add `GOPATH` and `PATH` to your `.bashrc` or `.bash_profile` - + Verify your environment is setup properly by running `$ go env`. Depending on your OS and environment, you should see an output similar to: - + ```bash GOARCH="amd64" GOBIN="" diff --git a/script/binary b/script/binary index 79ce53e31..fde68641e 100755 --- a/script/binary +++ b/script/binary @@ -8,9 +8,9 @@ fi rm -f dist/traefik -FLAGS="" +FLAGS=() if [ -n "$VERBOSE" ]; then - FLAGS="${FLAGS} -v" + FLAGS+=(-v) fi if [ -z "$VERSION" ]; then @@ -26,7 +26,7 @@ if [ -z "$DATE" ]; then fi # 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.Codename=$CODENAME \ -X github.com/containous/traefik/pkg/version.BuildDate=$DATE" \ diff --git a/script/crossbinary-default b/script/crossbinary-default index e212207e2..1a8ad5e8b 100755 --- a/script/crossbinary-default +++ b/script/crossbinary-default @@ -27,12 +27,12 @@ GO_BUILD_OPT="-s -w -X ${GIT_REPO_URL}.Version=${VERSION} -X ${GIT_REPO_URL}.Cod # Build amd64 binaries OS_PLATFORM_ARG=(linux windows darwin) OS_ARCH_ARG=(amd64) -for OS in ${OS_PLATFORM_ARG[@]}; do +for OS in "${OS_PLATFORM_ARG[@]}"; do BIN_EXT='' if [ "$OS" == "windows" ]; then BIN_EXT='.exe' fi - for ARCH in ${OS_ARCH_ARG[@]}; do + for ARCH in "${OS_ARCH_ARG[@]}"; do 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/ done @@ -41,8 +41,8 @@ done # Build arm64 binaries OS_PLATFORM_ARG=(linux) OS_ARCH_ARG=(arm64) -for OS in ${OS_PLATFORM_ARG[@]}; do - for ARCH in ${OS_ARCH_ARG[@]}; do +for OS in "${OS_PLATFORM_ARG[@]}"; do + for ARCH in "${OS_ARCH_ARG[@]}"; do 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/ done diff --git a/script/deploy.sh b/script/deploy.sh index 6f67e99a6..5fd3f0b66 100755 --- a/script/deploy.sh +++ b/script/deploy.sh @@ -8,12 +8,16 @@ else exit 0 fi +SCRIPT_DIR="$( cd "$( dirname "${0}" )" && pwd -P)" + git config --global user.email "$TRAEFIKER_EMAIL" git config --global user.name "Traefiker" # load ssh 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)" chmod 600 ~/.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) echo "Updating traefik-library-imag repo..." git clone git@github.com:containous/traefik-library-image.git -cd traefik-library-image -./updatev2.sh $VERSION +cd "${SCRIPT_DIR}"/traefik-library-image +"${SCRIPT_DIR}"/traefik-library-image/updatev2.sh "${VERSION}" git add -A -echo $VERSION | git commit --file - -echo $VERSION | git tag -a $VERSION --file - +echo "${VERSION}" | git commit --file - +echo "${VERSION}" | git tag -a "${VERSION}" --file - git push -q --follow-tags -u origin master > /dev/null 2>&1 -cd .. +cd "${SCRIPT_DIR}" rm -Rf traefik-library-image/ -echo "Deployed" \ No newline at end of file +echo "Deployed" diff --git a/script/make.sh b/script/make.sh index 44e5d5746..cad63e6d4 100755 --- a/script/make.sh +++ b/script/make.sh @@ -11,20 +11,21 @@ DEFAULT_BUNDLES=( test-integration ) +SCRIPT_DIR="$(cd "$(dirname "${0}")" && pwd -P)" + bundle() { local bundle="$1"; shift - echo "---> Making bundle: $(basename "$bundle") (in $DEST)" - source "script/$bundle" "$@" + echo "---> Making bundle: $(basename "$bundle") (in $SCRIPT_DIR)" + # shellcheck source=/dev/null + source "${SCRIPT_DIR}/$bundle" } if [ $# -lt 1 ]; then - bundles=(${DEFAULT_BUNDLES[@]}) + bundles=${DEFAULT_BUNDLES[*]} else - bundles=($@) + bundles=${*} fi -for bundle in ${bundles[@]}; do - export DEST=. - ABS_DEST="$(cd "$DEST" && pwd -P)" +for bundle in ${bundles[*]}; do bundle "$bundle" echo done diff --git a/script/test-integration b/script/test-integration index 83aec30ed..9031a93e1 100755 --- a/script/test-integration +++ b/script/test-integration @@ -1,28 +1,26 @@ #!/usr/bin/env bash set -e -SCRIPT_DIR="$( cd "$( dirname "${0}" )" && pwd -P)"; export SCRIPT_DIR export DEST=. -TESTFLAGS="${TESTFLAGS} -test.timeout=20m -check.v" +TESTFLAGS+=("-test.timeout=20m" -check.v) if [ -n "$VERBOSE" ]; then - TESTFLAGS="${TESTFLAGS} -v" + TESTFLAGS+=(-v) elif [ -n "$VERBOSE_INTEGRATION" ]; then - TESTFLAGS="${TESTFLAGS} -v" + TESTFLAGS+=(-v) fi - cd integration -echo "Testing against…" +echo "Testing against..." docker version if [ -n "$TEST_CONTAINER" ]; then -echo "Testing from container…" -CGO_ENABLED=0 go test -integration -container $TESTFLAGS + echo "Testing from container…" + CGO_ENABLED=0 go test -integration -container "${TESTFLAGS[@]}" fi if [ -n "$TEST_HOST" ]; then -echo "Testing from host…" -CGO_ENABLED=0 go test -integration -host $TESTFLAGS + echo "Testing from host…" + CGO_ENABLED=0 go test -integration -host "${TESTFLAGS[@]}" fi diff --git a/script/test-unit b/script/test-unit index 0d11fcd93..5b5097cd3 100755 --- a/script/test-unit +++ b/script/test-unit @@ -11,17 +11,17 @@ GREEN=$'\033[32m' TEXTRESET=$'\033[0m' # reset the foreground colour # -failfast -timeout=5m -TESTFLAGS="-cover -coverprofile=cover.out ${TESTFLAGS}" +TESTFLAGS=(-cover "-coverprofile=cover.out" "${TESTFLAGS}") if [ -n "$VERBOSE" ]; then - TESTFLAGS="${TESTFLAGS} -v" + TESTFLAGS+=(-v) elif [ -n "$VERBOSE_UNIT" ]; then - TESTFLAGS="${TESTFLAGS} -v" + TESTFLAGS+=(-v) fi set +e -go test ${TESTFLAGS} ./pkg/... +go test "${TESTFLAGS[@]}" ./pkg/... CODE=$? if [ ${CODE} != 0 ]; then diff --git a/script/update-cert.sh b/script/update-cert.sh index 35c2cd825..5816df6cf 100755 --- a/script/update-cert.sh +++ b/script/update-cert.sh @@ -13,11 +13,11 @@ docker pull $CERT_IMAGE # Fetch the latest certificates. ID=$(docker run -d $CERT_IMAGE sh -c "apk --update upgrade && apk add ca-certificates && update-ca-certificates") -docker logs -f $ID -docker wait $ID +docker logs -f "${ID}" +docker wait "${ID}" # 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. -docker rm -f $ID +docker rm -f "${ID}" diff --git a/script/update-generated-crd-code.sh b/script/update-generated-crd-code.sh index d89eedc5e..9fddab5ba 100755 --- a/script/update-generated-crd-code.sh +++ b/script/update-generated-crd-code.sh @@ -3,12 +3,12 @@ HACK_DIR="$( cd "$( dirname "${0}" )" && pwd -P)"; export 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 \ github.com/containous/traefik/pkg/provider/kubernetes/crd/generated \ github.com/containous/traefik/pkg/provider/kubernetes/crd \ 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 diff --git a/script/validate-misspell b/script/validate-misspell index 0e5e7b655..c29770eac 100755 --- a/script/validate-misspell +++ b/script/validate-misspell @@ -1,8 +1,9 @@ #!/usr/bin/env bash -IFS=$'\n' -files=( $( git ls-files 'docs/*.md' *.md ) ) -unset IFS +SCRIPT_DIR="$( cd "$( dirname "${0}" )" && pwd -P)" +files=() +while IFS='' read -r line; do files+=("$line"); done < <(git ls-files "${SCRIPT_DIR}"/../'docs/*.md' "${SCRIPT_DIR}"/../*.md) + errors=() for f in "${files[@]}"; do diff --git a/script/validate-shell-script.sh b/script/validate-shell-script.sh new file mode 100755 index 000000000..befaebe59 --- /dev/null +++ b/script/validate-shell-script.sh @@ -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