From fd674b23be4fa894c3baf48d07beffdbba32c251 Mon Sep 17 00:00:00 2001 From: Marco Ferrari Date: Mon, 29 Jan 2024 14:06:19 +0000 Subject: [PATCH] build: move linter verions logic outside runtime Move the logic to build the linter versions file outside the main runtime. There's no need to include it there because it's used only when building the image. Move the list of linters by name in linterVersions.sh because we don't need it in any other place. --- Dockerfile | 26 +-- docs/add-new-linter.md | 2 +- lib/functions/linterVersions.sh | 91 ----------- lib/functions/validation.sh | 1 - lib/linter.sh | 111 +------------ scripts/linterVersions.sh | 151 ++++++++++++++++++ .../super-linter/controls/super_linter.rb | 12 +- 7 files changed, 181 insertions(+), 213 deletions(-) delete mode 100755 lib/functions/linterVersions.sh create mode 100755 scripts/linterVersions.sh 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",