diff --git a/Dockerfile b/Dockerfile index 1d5da3a7ee4..e2700c3c6fa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -377,6 +377,10 @@ ENV PATH="${PATH}:/node_modules/.bin" ENV PATH="${PATH}:/usr/lib/go/bin" ENV PATH="${PATH}:${DART_SDK}/bin:/root/.pub-cache/bin" +# File to store linter versions +ENV VERSION_FILE="/action/linterVersions.txt" +RUN mkdir /action + # Initialize Terrascan # Initialize ChkTeX config file RUN terrascan init \ @@ -386,6 +390,12 @@ ENTRYPOINT ["/action/lib/linter.sh"] FROM base_image as slim +# Run to build version file and validate image +ENV IMAGE="slim" +COPY scripts/linterVersions.sh / +RUN /linterVersions.sh \ + && rm -rfv /linterVersions.sh + ################################### # Copy linter configuration files # ################################### @@ -396,11 +406,6 @@ COPY TEMPLATES /action/lib/.automation ################################# COPY lib /action/lib -ENV IMAGE="slim" - -# Run to build version file and validate image -RUN ACTIONS_RUNNER_DEBUG=true WRITE_LINTER_VERSIONS_FILE=true IMAGE="${IMAGE}" /action/lib/linter.sh - # Set build metadata here so we don't invalidate the container image cache if we # change the values of these arguments ARG BUILD_DATE @@ -460,6 +465,12 @@ RUN --mount=type=secret,id=GITHUB_TOKEN /install-pwsh.sh && rm -rf /install-pwsh COPY scripts/install-arm-ttk.sh / RUN --mount=type=secret,id=GITHUB_TOKEN /install-arm-ttk.sh && rm -rf /install-arm-ttk.sh +# Run to build version file and validate image again because we installed more linters +ENV IMAGE="standard" +COPY scripts/linterVersions.sh / +RUN /linterVersions.sh \ + && rm -rfv /linterVersions.sh + ################################### # Copy linter configuration files # ################################### @@ -470,11 +481,6 @@ COPY TEMPLATES /action/lib/.automation ################################# COPY lib /action/lib -ENV IMAGE="standard" - -# Run to build version file and validate image again because we installed more linters -RUN ACTIONS_RUNNER_DEBUG=true WRITE_LINTER_VERSIONS_FILE=true IMAGE="${IMAGE}" /action/lib/linter.sh - # Set build metadata here so we don't invalidate the container image cache if we # change the values of these arguments ARG BUILD_DATE diff --git a/docs/add-new-linter.md b/docs/add-new-linter.md index 6c9bbbc3b7f..4578ae32efc 100644 --- a/docs/add-new-linter.md +++ b/docs/add-new-linter.md @@ -96,6 +96,6 @@ new tool, it should include: - If the tool needs to take into account special cases: - Provide new runtime validation checks in `lib/validation.sh`. - - Customize the logic to get the installed version of the tool: `lib/linterVersions.sh` + - Customize the logic to get the installed version of the tool: `scripts/linterVersions.sh` - Provide custom logic to load configuration files: `lib/linterRules.sh` - Provide custom logic for test cases and to run the tool: `lib/worker.sh` diff --git a/lib/functions/linterVersions.sh b/lib/functions/linterVersions.sh deleted file mode 100755 index 2a6576fbf68..00000000000 --- a/lib/functions/linterVersions.sh +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env bash - -GetLinterVersions() { - debug "WRITE_LINTER_VERSIONS_FILE: ${WRITE_LINTER_VERSIONS_FILE}" - - if [ "${WRITE_LINTER_VERSIONS_FILE}" = "true" ]; then - debug "Building linter version file: ${VERSION_FILE}" - if BuildLinterVersions "${VERSION_FILE}" "${LINTER_NAMES_ARRAY[@]}"; then - info "Linter version file built correctly." - exit - else - fatal "Error while building the versions file." - fi - else - debug "Skipping versions file build..." - fi - - if ! cat "${VERSION_FILE}"; then - fatal "Failed to view version file: ${VERSION_FILE}." - fi -} -################################################################################ -#### Function BuildLinterVersions ############################################## -BuildLinterVersions() { - VERSION_FILE="${1}" && shift - LINTER_ARRAY=("$@") - - # Start with an empty file. We might have built this file in a previous build - # stage, so we start fresh here. - rm -rfv "${VERSION_FILE}" - - debug "Building linter version file ${VERSION_FILE} for the following linters: ${LINTER_ARRAY[*]}..." - - ########################################################## - # Go through the array of linters and print version info # - ########################################################## - for LINTER in "${LINTER_ARRAY[@]}"; do - if [ -n "${LINTER}" ]; then - - # Some linters need to account for special commands to get their version - - if [[ ${LINTER} == "arm-ttk" ]]; then - GET_VERSION_CMD="$(grep -iE 'version' "/usr/bin/arm-ttk" | xargs 2>&1)" - # Some linters don't support a "get version" command - elif [[ ${LINTER} == "bash-exec" ]] || [[ ${LINTER} == "gherkin-lint" ]]; then - GET_VERSION_CMD="Version command not supported" - elif [[ ${LINTER} == "checkstyle" ]] || [[ ${LINTER} == "google-java-format" ]]; then - GET_VERSION_CMD="$(java -jar "/usr/bin/${LINTER}" --version 2>&1)" - elif [[ ${LINTER} == "clippy" ]]; then - GET_VERSION_CMD="$(cargo-clippy --version 2>&1)" - elif [[ ${LINTER} == "editorconfig-checker" ]]; then - GET_VERSION_CMD="$(${LINTER} -version)" - elif [[ ${LINTER} == "kubeconform" ]]; then - GET_VERSION_CMD="$(${LINTER} -v)" - elif [[ ${LINTER} == "lintr" ]]; then - # Need specific command for lintr (--slave is deprecated in R 4.0 and replaced by --no-echo) - GET_VERSION_CMD="$(R --slave -e "r_ver <- R.Version()\$version.string; \ - lintr_ver <- packageVersion('lintr'); \ - glue::glue('lintr { lintr_ver } on { r_ver }')")" - elif [[ ${LINTER} == "protolint" ]] || [[ ${LINTER} == "gitleaks" ]]; then - GET_VERSION_CMD="$(${LINTER} version)" - elif [[ ${LINTER} == "lua" ]]; then - GET_VERSION_CMD="$("${LINTER}" -v 2>&1)" - elif [[ ${LINTER} == "renovate-config-validator" ]]; then - GET_VERSION_CMD="$(renovate --version 2>&1)" - elif [[ ${LINTER} == "terrascan" ]]; then - GET_VERSION_CMD="$("${LINTER}" version 2>&1)" - else - # Unset TF_LOG_LEVEL so that the version file doesn't contain debug log when running - # commands that read TF_LOG_LEVEL or TFLINT_LOG, which are likely set to DEBUG when - # building the versions file - GET_VERSION_CMD="$( - unset TF_LOG_LEVEL - unset TFLINT_LOG - "${LINTER}" --version 2>&1 - )" - fi - - ERROR_CODE=$? - - if [ ${ERROR_CODE} -ne 0 ]; then - fatal "[${LINTER}]: Failed to get version info. Exit code: ${ERROR_CODE}. Output: ${GET_VERSION_CMD}" - else - info "Successfully found version for ${LINTER}: ${GET_VERSION_CMD}" - if ! echo "${LINTER}: ${GET_VERSION_CMD}" >>"${VERSION_FILE}" 2>&1; then - fatal "Failed to write data to file!" - fi - fi - fi - done -} diff --git a/lib/functions/validation.sh b/lib/functions/validation.sh index 555edfb9863..a789649c89b 100755 --- a/lib/functions/validation.sh +++ b/lib/functions/validation.sh @@ -16,7 +16,6 @@ function ValidateBooleanConfigurationVariables() { ValidateBooleanVariable "TEST_CASE_RUN" "${TEST_CASE_RUN}" ValidateBooleanVariable "USE_FIND_ALGORITHM" "${USE_FIND_ALGORITHM}" ValidateBooleanVariable "VALIDATE_ALL_CODEBASE" "${VALIDATE_ALL_CODEBASE}" - ValidateBooleanVariable "WRITE_LINTER_VERSIONS_FILE" "${WRITE_LINTER_VERSIONS_FILE}" ValidateBooleanVariable "YAML_ERROR_ON_WARNING" "${YAML_ERROR_ON_WARNING}" } diff --git a/lib/linter.sh b/lib/linter.sh index 71548365ff7..5d2303c6530 100755 --- a/lib/linter.sh +++ b/lib/linter.sh @@ -47,8 +47,6 @@ source /action/lib/functions/detectFiles.sh # Source the function script(s) # shellcheck source=/dev/null source /action/lib/functions/linterRules.sh # Source the function script(s) # shellcheck source=/dev/null -source /action/lib/functions/linterVersions.sh # Source the function script(s) -# shellcheck source=/dev/null source /action/lib/functions/log.sh # Source the function script(s) # shellcheck source=/dev/null source /action/lib/functions/updateSSL.sh # Source the function script(s) @@ -133,9 +131,6 @@ VALIDATE_ALL_CODEBASE="${VALIDATE_ALL_CODEBASE:-"true"}" declare -l YAML_ERROR_ON_WARNING YAML_ERROR_ON_WARNING="${YAML_ERROR_ON_WARNING:-false}" -declare -l WRITE_LINTER_VERSIONS_FILE -WRITE_LINTER_VERSIONS_FILE="${WRITE_LINTER_VERSIONS_FILE:-"false"}" - ValidateBooleanConfigurationVariables ########### @@ -159,8 +154,6 @@ LINTER_RULES_PATH="${LINTER_RULES_PATH:-.github/linters}" # Linter rules directo RAW_FILE_ARRAY=() # Array of all files that were changed # shellcheck disable=SC2034 # Variable is referenced in other scripts TEST_CASE_FOLDER='test/linters' # Folder for test cases we should always ignore -# shellcheck disable=SC2034 # Variable is referenced in other scripts -VERSION_FILE='/action/lib/functions/linterVersions.txt' # File to store linter versions # Set the log level TF_LOG_LEVEL="info" @@ -211,7 +204,6 @@ JAVASCRIPT_ES_FILE_NAME="${JAVASCRIPT_ES_CONFIG_FILE:-.eslintrc.yml}" # shellcheck disable=SC2034 # Variable is referenced indirectly JAVASCRIPT_DEFAULT_STYLE="${JAVASCRIPT_DEFAULT_STYLE:-standard}" JAVASCRIPT_STYLE_NAME='' # Variable for the style -JAVASCRIPT_STYLE='' # Variable for the style # shellcheck disable=SC2034 # Variable is referenced indirectly JAVASCRIPT_STANDARD_FILE_NAME="${JAVASCRIPT_ES_CONFIG_FILE:-.eslintrc.yml}" # shellcheck disable=SC2034 # Variable is referenced indirectly @@ -275,7 +267,6 @@ TSX_FILE_NAME="${TYPESCRIPT_ES_CONFIG_FILE:-.eslintrc.yml}" # shellcheck disable=SC2034 # Variable is referenced indirectly TYPESCRIPT_DEFAULT_STYLE="${TYPESCRIPT_DEFAULT_STYLE:-ts-standard}" TYPESCRIPT_STYLE_NAME='' # Variable for the style -TYPESCRIPT_STYLE='' # Variable for the style # shellcheck disable=SC2034 # Variable is referenced indirectly TYPESCRIPT_ES_FILE_NAME="${TYPESCRIPT_ES_CONFIG_FILE:-.eslintrc.yml}" # shellcheck disable=SC2034 # Variable is referenced indirectly @@ -292,11 +283,9 @@ JAVASCRIPT_DEFAULT_STYLE=$(echo "${JAVASCRIPT_DEFAULT_STYLE}" | tr '[:upper:]' ' if [ "${JAVASCRIPT_DEFAULT_STYLE}" == "prettier" ]; then # Set to prettier JAVASCRIPT_STYLE_NAME='JAVASCRIPT_PRETTIER' - JAVASCRIPT_STYLE='prettier' else # Default to standard JAVASCRIPT_STYLE_NAME='JAVASCRIPT_STANDARD' - JAVASCRIPT_STYLE='standard' fi ################################################# @@ -310,11 +299,9 @@ TYPESCRIPT_DEFAULT_STYLE=$(echo "${TYPESCRIPT_DEFAULT_STYLE}" | tr '[:upper:]' ' if [ "${TYPESCRIPT_DEFAULT_STYLE}" == "prettier" ]; then # Set to prettier TYPESCRIPT_STYLE_NAME='TYPESCRIPT_PRETTIER' - TYPESCRIPT_STYLE='prettier' else # Default to standard TYPESCRIPT_STYLE_NAME='TYPESCRIPT_STANDARD' - TYPESCRIPT_STYLE='ts-standard' fi ################## @@ -334,86 +321,6 @@ LANGUAGE_ARRAY=('ANSIBLE' 'ARM' 'BASH' 'BASH_EXEC' 'CHECKOV' 'CLANG_FORMAT' 'TERRAFORM_FMT' 'TERRAFORM_TFLINT' 'TERRAFORM_TERRASCAN' 'TERRAGRUNT' 'TSX' 'TYPESCRIPT_ES' "${TYPESCRIPT_STYLE_NAME}" 'XML' 'YAML') -############################## -# Linter command names array # -############################## -declare -A LINTER_NAMES_ARRAY -LINTER_NAMES_ARRAY['ANSIBLE']="ansible-lint" -LINTER_NAMES_ARRAY['ARM']="arm-ttk" -LINTER_NAMES_ARRAY['BASH']="shellcheck" -LINTER_NAMES_ARRAY['BASH_EXEC']="bash-exec" -LINTER_NAMES_ARRAY['CHECKOV']="checkov" -LINTER_NAMES_ARRAY['CLANG_FORMAT']="clang-format" -LINTER_NAMES_ARRAY['CLOJURE']="clj-kondo" -LINTER_NAMES_ARRAY['CLOUDFORMATION']="cfn-lint" -LINTER_NAMES_ARRAY['COFFEESCRIPT']="coffeelint" -LINTER_NAMES_ARRAY['CPP']="cpplint" -LINTER_NAMES_ARRAY['CSHARP']="dotnet" -LINTER_NAMES_ARRAY['CSS']="stylelint" -LINTER_NAMES_ARRAY['DART']="dart" -LINTER_NAMES_ARRAY['DOCKERFILE_HADOLINT']="hadolint" -LINTER_NAMES_ARRAY['EDITORCONFIG']="editorconfig-checker" -LINTER_NAMES_ARRAY['ENV']="dotenv-linter" -LINTER_NAMES_ARRAY['GITHUB_ACTIONS']="actionlint" -LINTER_NAMES_ARRAY['GITLEAKS']="gitleaks" -LINTER_NAMES_ARRAY['GHERKIN']="gherkin-lint" -LINTER_NAMES_ARRAY['GO']="golangci-lint" -LINTER_NAMES_ARRAY['GO_MODULES']="${LINTER_NAMES_ARRAY['GO']}" -LINTER_NAMES_ARRAY['GOOGLE_JAVA_FORMAT']="google-java-format" -LINTER_NAMES_ARRAY['GROOVY']="npm-groovy-lint" -LINTER_NAMES_ARRAY['HTML']="htmlhint" -LINTER_NAMES_ARRAY['JAVA']="checkstyle" -LINTER_NAMES_ARRAY['JAVASCRIPT_ES']="eslint" -LINTER_NAMES_ARRAY["${JAVASCRIPT_STYLE_NAME}"]="${JAVASCRIPT_STYLE}" -LINTER_NAMES_ARRAY['JSCPD']="jscpd" -LINTER_NAMES_ARRAY['JSON']="eslint" -LINTER_NAMES_ARRAY['JSONC']="eslint" -LINTER_NAMES_ARRAY['JSX']="eslint" -LINTER_NAMES_ARRAY['KOTLIN']="ktlint" -LINTER_NAMES_ARRAY['KUBERNETES_KUBECONFORM']="kubeconform" -LINTER_NAMES_ARRAY['LATEX']="chktex" -LINTER_NAMES_ARRAY['LUA']="lua" -LINTER_NAMES_ARRAY['MARKDOWN']="markdownlint" -LINTER_NAMES_ARRAY['NATURAL_LANGUAGE']="textlint" -LINTER_NAMES_ARRAY['OPENAPI']="spectral" -LINTER_NAMES_ARRAY['PERL']="perl" -LINTER_NAMES_ARRAY['PHP_BUILTIN']="php" -LINTER_NAMES_ARRAY['PHP_PHPCS']="phpcs" -LINTER_NAMES_ARRAY['PHP_PHPSTAN']="phpstan" -LINTER_NAMES_ARRAY['PHP_PSALM']="psalm" -LINTER_NAMES_ARRAY['POWERSHELL']="pwsh" -LINTER_NAMES_ARRAY['PROTOBUF']="protolint" -LINTER_NAMES_ARRAY['PYTHON_BLACK']="black" -LINTER_NAMES_ARRAY['PYTHON_PYLINT']="pylint" -LINTER_NAMES_ARRAY['PYTHON_FLAKE8']="flake8" -LINTER_NAMES_ARRAY['PYTHON_ISORT']="isort" -LINTER_NAMES_ARRAY['PYTHON_MYPY']="mypy" -LINTER_NAMES_ARRAY['R']="R" -LINTER_NAMES_ARRAY['RAKU']="raku" -LINTER_NAMES_ARRAY['RENOVATE']="renovate-config-validator" -LINTER_NAMES_ARRAY['RUBY']="rubocop" -LINTER_NAMES_ARRAY['RUST_2015']="rustfmt" -LINTER_NAMES_ARRAY['RUST_2018']="rustfmt" -LINTER_NAMES_ARRAY['RUST_2021']="rustfmt" -LINTER_NAMES_ARRAY['RUST_CLIPPY']="clippy" -LINTER_NAMES_ARRAY['SCALAFMT']="scalafmt" -LINTER_NAMES_ARRAY['SHELL_SHFMT']="shfmt" -LINTER_NAMES_ARRAY['SNAKEMAKE_LINT']="snakemake" -LINTER_NAMES_ARRAY['SNAKEMAKE_SNAKEFMT']="snakefmt" -LINTER_NAMES_ARRAY['STATES']="asl-validator" -LINTER_NAMES_ARRAY['SQL']="sql-lint" -LINTER_NAMES_ARRAY['SQLFLUFF']="sqlfluff" -LINTER_NAMES_ARRAY['TEKTON']="tekton-lint" -LINTER_NAMES_ARRAY['TERRAFORM_FMT']="terraform" -LINTER_NAMES_ARRAY['TERRAFORM_TFLINT']="tflint" -LINTER_NAMES_ARRAY['TERRAFORM_TERRASCAN']="terrascan" -LINTER_NAMES_ARRAY['TERRAGRUNT']="terragrunt" -LINTER_NAMES_ARRAY['TSX']="eslint" -LINTER_NAMES_ARRAY['TYPESCRIPT_ES']="eslint" -LINTER_NAMES_ARRAY["${TYPESCRIPT_STYLE_NAME}"]="${TYPESCRIPT_STYLE}" -LINTER_NAMES_ARRAY['XML']="xmllint" -LINTER_NAMES_ARRAY['YAML']="yamllint" - ########################## # Array of changed files # ########################## @@ -772,17 +679,6 @@ UpdateLoopsForImage() { fi done done - - # Remove from LINTER_NAMES_ARRAY - debug "Removing Linters from LINTER_NAMES_ARRAY for slim image..." - for REMOVE_LINTER in "${REMOVE_ARRAY[@]}"; do - for INDEX in "${!LINTER_NAMES_ARRAY[@]}"; do - if [[ ${INDEX} = "${REMOVE_LINTER}" ]]; then - debug "found item:[${REMOVE_LINTER}], removing linter..." - unset 'LINTER_NAMES_ARRAY[$INDEX]' - fi - done - done fi } @@ -837,10 +733,9 @@ SetupGithubComSshKeys ################################################ UpdateLoopsForImage -################################## -# Get and print all version info # -################################## -GetLinterVersions +if ! cat "${VERSION_FILE}"; then + fatal "Failed to view version file: ${VERSION_FILE}" +fi ####################### # Get GitHub Env Vars # diff --git a/scripts/linterVersions.sh b/scripts/linterVersions.sh new file mode 100755 index 00000000000..e371fb07eb0 --- /dev/null +++ b/scripts/linterVersions.sh @@ -0,0 +1,151 @@ +#!/usr/bin/env bash + +set -o errexit +set -o nounset +set -o pipefail + +############################## +# Linter command names array # +############################## +declare -A LINTER_NAMES_ARRAY +LINTER_NAMES_ARRAY['ANSIBLE']="ansible-lint" +LINTER_NAMES_ARRAY['BASH']="shellcheck" +LINTER_NAMES_ARRAY['BASH_EXEC']="bash-exec" +LINTER_NAMES_ARRAY['CHECKOV']="checkov" +LINTER_NAMES_ARRAY['CLANG_FORMAT']="clang-format" +LINTER_NAMES_ARRAY['CLOJURE']="clj-kondo" +LINTER_NAMES_ARRAY['CLOUDFORMATION']="cfn-lint" +LINTER_NAMES_ARRAY['COFFEESCRIPT']="coffeelint" +LINTER_NAMES_ARRAY['CPP']="cpplint" +LINTER_NAMES_ARRAY['CSS']="stylelint" +LINTER_NAMES_ARRAY['DART']="dart" +LINTER_NAMES_ARRAY['DOCKERFILE_HADOLINT']="hadolint" +LINTER_NAMES_ARRAY['EDITORCONFIG']="editorconfig-checker" +LINTER_NAMES_ARRAY['GITHUB_ACTIONS']="actionlint" +LINTER_NAMES_ARRAY['GITLEAKS']="gitleaks" +LINTER_NAMES_ARRAY['GHERKIN']="gherkin-lint" +LINTER_NAMES_ARRAY['GO']="golangci-lint" +LINTER_NAMES_ARRAY['GO_MODULES']="${LINTER_NAMES_ARRAY['GO']}" +LINTER_NAMES_ARRAY['GOOGLE_JAVA_FORMAT']="google-java-format" +LINTER_NAMES_ARRAY['GROOVY']="npm-groovy-lint" +LINTER_NAMES_ARRAY['HTML']="htmlhint" +LINTER_NAMES_ARRAY['JAVA']="checkstyle" +LINTER_NAMES_ARRAY['JAVASCRIPT_ES']="eslint" +LINTER_NAMES_ARRAY['JAVASCRIPT_PRETTIER']="prettier" +LINTER_NAMES_ARRAY['JAVASCRIPT_STANDARD']="standard" +LINTER_NAMES_ARRAY['JSCPD']="jscpd" +LINTER_NAMES_ARRAY['JSON']="eslint" +LINTER_NAMES_ARRAY['JSONC']="eslint" +LINTER_NAMES_ARRAY['JSX']="eslint" +LINTER_NAMES_ARRAY['KOTLIN']="ktlint" +LINTER_NAMES_ARRAY['KUBERNETES_KUBECONFORM']="kubeconform" +LINTER_NAMES_ARRAY['LATEX']="chktex" +LINTER_NAMES_ARRAY['LUA']="lua" +LINTER_NAMES_ARRAY['MARKDOWN']="markdownlint" +LINTER_NAMES_ARRAY['NATURAL_LANGUAGE']="textlint" +LINTER_NAMES_ARRAY['OPENAPI']="spectral" +LINTER_NAMES_ARRAY['PERL']="perl" +LINTER_NAMES_ARRAY['PHP_BUILTIN']="php" +LINTER_NAMES_ARRAY['PHP_PHPCS']="phpcs" +LINTER_NAMES_ARRAY['PHP_PHPSTAN']="phpstan" +LINTER_NAMES_ARRAY['PHP_PSALM']="psalm" +LINTER_NAMES_ARRAY['PROTOBUF']="protolint" +LINTER_NAMES_ARRAY['PYTHON_BLACK']="black" +LINTER_NAMES_ARRAY['PYTHON_PYLINT']="pylint" +LINTER_NAMES_ARRAY['PYTHON_FLAKE8']="flake8" +LINTER_NAMES_ARRAY['PYTHON_ISORT']="isort" +LINTER_NAMES_ARRAY['PYTHON_MYPY']="mypy" +LINTER_NAMES_ARRAY['R']="R" +LINTER_NAMES_ARRAY['RAKU']="raku" +LINTER_NAMES_ARRAY['RENOVATE']="renovate-config-validator" +LINTER_NAMES_ARRAY['RUBY']="rubocop" +LINTER_NAMES_ARRAY['SCALAFMT']="scalafmt" +LINTER_NAMES_ARRAY['SHELL_SHFMT']="shfmt" +LINTER_NAMES_ARRAY['SNAKEMAKE_LINT']="snakemake" +LINTER_NAMES_ARRAY['SNAKEMAKE_SNAKEFMT']="snakefmt" +LINTER_NAMES_ARRAY['STATES']="asl-validator" +LINTER_NAMES_ARRAY['SQL']="sql-lint" +LINTER_NAMES_ARRAY['SQLFLUFF']="sqlfluff" +LINTER_NAMES_ARRAY['TEKTON']="tekton-lint" +LINTER_NAMES_ARRAY['TERRAFORM_FMT']="terraform" +LINTER_NAMES_ARRAY['TERRAFORM_TFLINT']="tflint" +LINTER_NAMES_ARRAY['TERRAFORM_TERRASCAN']="terrascan" +LINTER_NAMES_ARRAY['TERRAGRUNT']="terragrunt" +LINTER_NAMES_ARRAY['TSX']="eslint" +LINTER_NAMES_ARRAY['TYPESCRIPT_ES']="eslint" +LINTER_NAMES_ARRAY['TYPESCRIPT_PRETTIER']="prettier" +LINTER_NAMES_ARRAY['TYPESCRIPT_STANDARD']="ts-standard" +LINTER_NAMES_ARRAY['XML']="xmllint" +LINTER_NAMES_ARRAY['YAML']="yamllint" + +if [[ "${IMAGE}" == "standard" ]]; then + LINTER_NAMES_ARRAY['ARM']="arm-ttk" + LINTER_NAMES_ARRAY['CSHARP']="dotnet" + LINTER_NAMES_ARRAY['ENV']="dotenv-linter" + LINTER_NAMES_ARRAY['POWERSHELL']="pwsh" + LINTER_NAMES_ARRAY['RUST_2015']="rustfmt" + LINTER_NAMES_ARRAY['RUST_2018']="rustfmt" + LINTER_NAMES_ARRAY['RUST_2021']="rustfmt" + LINTER_NAMES_ARRAY['RUST_CLIPPY']="clippy" +fi + +echo "Building linter version file: ${VERSION_FILE}" + +# Start with an empty file. We might have built this file in a previous build +# stage, so we start fresh here. +rm -rfv "${VERSION_FILE}" + +echo "Building linter version file ${VERSION_FILE} for the following linters: ${LINTER_NAMES_ARRAY[*]}..." + +for LINTER in "${LINTER_NAMES_ARRAY[@]}"; do + # Some linters need to account for special commands to get their version + + if [[ ${LINTER} == "arm-ttk" ]]; then + GET_VERSION_CMD="$(grep -iE 'version' "/usr/bin/arm-ttk" | xargs 2>&1)" + # Some linters don't support a "get version" command + elif [[ ${LINTER} == "bash-exec" ]] || [[ ${LINTER} == "gherkin-lint" ]]; then + GET_VERSION_CMD="Version command not supported" + elif [[ ${LINTER} == "checkstyle" ]] || [[ ${LINTER} == "google-java-format" ]]; then + GET_VERSION_CMD="$(java -jar "/usr/bin/${LINTER}" --version 2>&1)" + elif [[ ${LINTER} == "clippy" ]]; then + GET_VERSION_CMD="$(cargo-clippy --version 2>&1)" + elif [[ ${LINTER} == "editorconfig-checker" ]]; then + GET_VERSION_CMD="$(${LINTER} -version)" + elif [[ ${LINTER} == "kubeconform" ]]; then + GET_VERSION_CMD="$(${LINTER} -v)" + elif [[ ${LINTER} == "lintr" ]]; then + # Need specific command for lintr (--slave is deprecated in R 4.0 and replaced by --no-echo) + GET_VERSION_CMD="$(R --slave -e "r_ver <- R.Version()\$version.string; \ + lintr_ver <- packageVersion('lintr'); \ + glue::glue('lintr { lintr_ver } on { r_ver }')")" + elif [[ ${LINTER} == "protolint" ]] || [[ ${LINTER} == "gitleaks" ]]; then + GET_VERSION_CMD="$(${LINTER} version)" + elif [[ ${LINTER} == "lua" ]]; then + GET_VERSION_CMD="$("${LINTER}" -v 2>&1)" + elif [[ ${LINTER} == "renovate-config-validator" ]]; then + GET_VERSION_CMD="$(renovate --version 2>&1)" + elif [[ ${LINTER} == "terrascan" ]]; then + GET_VERSION_CMD="$("${LINTER}" version 2>&1)" + else + # Unset TF_LOG_LEVEL so that the version file doesn't contain debug log when running + # commands that read TF_LOG_LEVEL or TFLINT_LOG, which are likely set to DEBUG when + # building the versions file + GET_VERSION_CMD="$( + unset TF_LOG_LEVEL + unset TFLINT_LOG + "${LINTER}" --version 2>&1 + )" + fi + + ERROR_CODE=$? + if [ ${ERROR_CODE} -ne 0 ]; then + echo "[ERROR]: Failed to get version info for ${LINTER}. Exit code: ${ERROR_CODE}. Output: ${GET_VERSION_CMD}" + exit 1 + else + echo "Successfully found version for ${LINTER}: ${GET_VERSION_CMD}" + if ! echo "${LINTER}: ${GET_VERSION_CMD}" >>"${VERSION_FILE}" 2>&1; then + echo "[ERROR] Failed to write data to file!" + exit 1 + fi + fi +done diff --git a/test/inspec/super-linter/controls/super_linter.rb b/test/inspec/super-linter/controls/super_linter.rb index 402120ffcb4..43a6d7b296e 100644 --- a/test/inspec/super-linter/controls/super_linter.rb +++ b/test/inspec/super-linter/controls/super_linter.rb @@ -3,6 +3,15 @@ # PUll in env vars passed image = ENV["IMAGE"] +version_file_path = "/action/linterVersions.txt" + +control "super-linter-environment-variables" do + + describe os_env('VERSION_FILE') do + its('content') { should eq version_file_path } + end +end + ################################################## # Check to see all system packages are installed # ################################################## @@ -438,8 +447,7 @@ "/action/lib/functions/githubEvent.sh", "/action/lib/functions/linterCommands.sh", "/action/lib/functions/linterRules.sh", - "/action/lib/functions/linterVersions.sh", - "/action/lib/functions/linterVersions.txt", + version_file_path, "/action/lib/functions/log.sh", "/action/lib/functions/possum.sh", "/action/lib/functions/updateSSL.sh",