From 83eca1df43450dc9b7bf67830d27cc7c485d9613 Mon Sep 17 00:00:00 2001 From: Marco Ferrari Date: Fri, 9 Feb 2024 19:43:58 +0100 Subject: [PATCH] fix: unset the log_level variable (#5249) - Super-linter uses the LOG_LEVEL variable to let the user configure the desired log level. Checkov and Renovate use a variable with the same name for the same purpose, but accept a different set of values, and exit with an error if it gets an unknown value for that variable. - Refactor the VERBOSE log level to the more commonly used INFO. Configuration validation will warn users if they use VERBOSE and instruct them to use INFO instead. This is not a breaking change because super-linter falls back on INFO if VERBOSE is set. - Remove the TRACE log level because we rarely used it. As with VERBOSE, configuration validation will warn the user. Fall back to DEBUG if the user configured LOG_LEVEL to VERBOSE. Close #5217 --- Makefile | 8 ++++- README.md | 2 +- lib/functions/detectFiles.sh | 10 +++--- lib/functions/log.sh | 2 -- lib/functions/validation.sh | 32 ++++++++++++++++--- lib/linter.sh | 17 +++++----- .../super-linter/controls/super_linter.rb | 4 +++ test/lib/buildFileListTest.sh | 2 -- test/lib/githubEventTest.sh | 2 -- test/lib/validationTest.sh | 27 ++++++++++++++-- test/run-super-linter-tests.sh | 9 +++++- 11 files changed, 85 insertions(+), 30 deletions(-) diff --git a/Makefile b/Makefile index 4be93d12..0d3ddca9 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ all: info docker test ## Run all targets. .PHONY: test -test: info validate-container-image-labels test-lib inspec lint-codebase test-default-config-files test-find lint-subset-files test-custom-ssl-cert test-non-default-workdir test-git-flags test-linters ## Run the test suite +test: info validate-container-image-labels test-lib inspec lint-codebase test-default-config-files test-find lint-subset-files test-custom-ssl-cert test-non-default-workdir test-git-flags test-log-level test-linters ## Run the test suite # if this session isn't interactive, then we don't want to allocate a # TTY, which would fail, but if it is interactive, we do want to attach @@ -291,6 +291,12 @@ test-linters-expect-failure: ## Run the linters test suite expecting failures $(SUPER_LINTER_TEST_CONTAINER_URL) \ "run_test_cases_expect_failure" +.phony: test-log-level +test-log-level: ## Run a test to check if there are conflicts with the LOG_LEVEL variable + $(CURDIR)/test/run-super-linter-tests.sh \ + $(SUPER_LINTER_TEST_CONTAINER_URL) \ + "run_test_cases_log_level" + .phony: build-dev-container-image build-dev-container-image: ## Build commit linter container image DOCKER_BUILDKIT=1 docker buildx build --load \ diff --git a/README.md b/README.md index b977fa34..86744f17 100644 --- a/README.md +++ b/README.md @@ -188,7 +188,7 @@ You can configure super-linter using the following environment variables: | **KUBERNETES_KUBECONFORM_OPTIONS** | `null` | Additional arguments to pass to the command-line when running **Kubernetes Kubeconform** (Example: --ignore-missing-schemas) | | **LINTER_RULES_PATH** | `.github/linters` | Directory for all linter configuration rules. | | **LOG_FILE** | `super-linter.log` | The filename for outputting logs. All output is sent to the log file regardless of `LOG_LEVEL`. | -| **LOG_LEVEL** | `VERBOSE` | How much output the script will generate to the console. One of `ERROR`, `WARN`, `NOTICE`, `VERBOSE`, `DEBUG` or `TRACE`. | +| **LOG_LEVEL** | `INFO` | How much output the script will generate to the console. One of `ERROR`, `WARN`, `NOTICE`, `INFO`, or `DEBUG`. | | **MARKDOWN_CONFIG_FILE** | `.markdown-lint.yml` | Filename for [Markdownlint configuration](https://github.com/DavidAnson/markdownlint#optionsconfig) (ex: `.markdown-lint.yml`, `.markdownlint.json`, `.markdownlint.yaml`) | | **MARKDOWN_CUSTOM_RULE_GLOBS** | `.markdown-lint/rules,rules/**` | Comma-separated list of [file globs](https://github.com/igorshubovych/markdownlint-cli#globbing) matching [custom Markdownlint rule files](https://github.com/DavidAnson/markdownlint/blob/main/doc/CustomRules.md). | | **MULTI_STATUS** | `true` | A status API is made for each language that is linted to make visual parsing easier. | diff --git a/lib/functions/detectFiles.sh b/lib/functions/detectFiles.sh index a82fe413..880c01f2 100755 --- a/lib/functions/detectFiles.sh +++ b/lib/functions/detectFiles.sh @@ -201,7 +201,7 @@ function IsValidShellScript() { FILE_EXTENSION="$(GetFileExtension "$FILE")" GET_FILE_TYPE_CMD="$(GetFileType "$FILE")" - trace "File:[${FILE}], File extension:[${FILE_EXTENSION}], File type: [${GET_FILE_TYPE_CMD}]" + debug "File:[${FILE}], File extension:[${FILE_EXTENSION}], File type: [${GET_FILE_TYPE_CMD}]" if [[ "${FILE_EXTENSION}" == "zsh" ]] || [[ ${GET_FILE_TYPE_CMD} == *"zsh script"* ]]; then @@ -227,7 +227,7 @@ function IsValidShellScript() { return 0 fi - trace "$FILE is NOT a supported shell script. Skipping" + debug "$FILE is NOT a supported shell script. Skipping" return 1 } @@ -240,15 +240,15 @@ function IsGenerated() { fi if ! grep -q "@generated" "$FILE"; then - trace "File:[${FILE}] is not generated, because it doesn't have @generated marker" + debug "File:[${FILE}] is not generated, because it doesn't have @generated marker" return 1 fi if grep -q "@not-generated" "$FILE"; then - trace "File:[${FILE}] is not-generated because it has @not-generated marker" + debug "File:[${FILE}] is not-generated because it has @not-generated marker" return 1 else - trace "File:[${FILE}] is generated because it has @generated marker" + debug "File:[${FILE}] is generated because it has @generated marker" return 0 fi } diff --git a/lib/functions/log.sh b/lib/functions/log.sh index 985aa5d6..7a23ee1e 100755 --- a/lib/functions/log.sh +++ b/lib/functions/log.sh @@ -85,7 +85,6 @@ log() { fi } -trace() { log "${LOG_TRACE:-}" "$*" "TRACE"; } debug() { log "${LOG_DEBUG:-}" "$*" "DEBUG"; } info() { log "${LOG_VERBOSE:-}" "$*" "INFO"; } notice() { log "${LOG_NOTICE:-}" "$*" "NOTICE"; } @@ -152,6 +151,5 @@ export -f info export -f log export -f notice export -f startGitHubActionsLogGroup -export -f trace export -f warn export -f writeGitHubActionsLogGroupMarker diff --git a/lib/functions/validation.sh b/lib/functions/validation.sh index a789649c..ade11ffd 100755 --- a/lib/functions/validation.sh +++ b/lib/functions/validation.sh @@ -259,15 +259,37 @@ function WarnIfVariableIsSet() { local INPUT_VARIABLE_NAME="${1}" if [ -n "${INPUT_VARIABLE:-}" ]; then - warn "${INPUT_VARIABLE_NAME} environment variable is set, it's deprecated, and super-linter will ignore it. Remove it from your configuration. This warning may turn in a fatal error in the future." + warn "${INPUT_VARIABLE_NAME} environment variable is set, it's deprecated, and super-linter will ignore it. Remove it from your configuration. This warning may turn in a fatal error in the future. For more information, see the upgrade guide: https://github.com/super-linter/super-linter/blob/main/docs/upgrade-guide.md" + fi +} + +function WarnIfDeprecatedValueForConfigurationVariableIsSet() { + local INPUT_VARIABLE_VALUE + INPUT_VARIABLE_VALUE="${1}" + shift + local DEPRECATED_VARIABLE_VALUE + DEPRECATED_VARIABLE_VALUE="${1}" + shift + local INPUT_VARIABLE_NAME + INPUT_VARIABLE_NAME="${1}" + shift + local VALUE_TO_UPDATE_TO + VALUE_TO_UPDATE_TO="${1}" + + if [[ "${INPUT_VARIABLE_VALUE}" == "${DEPRECATED_VARIABLE_VALUE}" ]]; then + warn "${INPUT_VARIABLE_NAME} is set to a deprecated value: ${DEPRECATED_VARIABLE_VALUE}. Set it to ${VALUE_TO_UPDATE_TO} instead. Falling back to ${VALUE_TO_UPDATE_TO}. This warning may turn in a fatal error in the future." fi } function ValidateDeprecatedVariables() { # The following variables have been deprecated in v6 - WarnIfVariableIsSet "${ERROR_ON_MISSING_EXEC_BIT}" "ERROR_ON_MISSING_EXEC_BIT" - WarnIfVariableIsSet "${EXPERIMENTAL_BATCH_WORKER}" "EXPERIMENTAL_BATCH_WORKER" - WarnIfVariableIsSet "${VALIDATE_JSCPD_ALL_CODEBASE}" "VALIDATE_JSCPD_ALL_CODEBASE" - WarnIfVariableIsSet "${VALIDATE_KOTLIN_ANDROID}" "VALIDATE_KOTLIN_ANDROID" + WarnIfVariableIsSet "${ERROR_ON_MISSING_EXEC_BIT:-}" "ERROR_ON_MISSING_EXEC_BIT" + WarnIfVariableIsSet "${EXPERIMENTAL_BATCH_WORKER:-}" "EXPERIMENTAL_BATCH_WORKER" + WarnIfVariableIsSet "${VALIDATE_JSCPD_ALL_CODEBASE:-}" "VALIDATE_JSCPD_ALL_CODEBASE" + WarnIfVariableIsSet "${VALIDATE_KOTLIN_ANDROID:-}" "VALIDATE_KOTLIN_ANDROID" + + # The following values have been deprecated in v6.1.0 + WarnIfDeprecatedValueForConfigurationVariableIsSet "${LOG_LEVEL}" "TRACE" "LOG_LEVEL" "DEBUG" + WarnIfDeprecatedValueForConfigurationVariableIsSet "${LOG_LEVEL}" "VERBOSE" "LOG_LEVEL" "INFO" } diff --git a/lib/linter.sh b/lib/linter.sh index 64263d8e..31772f34 100755 --- a/lib/linter.sh +++ b/lib/linter.sh @@ -13,30 +13,29 @@ IMAGE="${IMAGE:-standard}" # Version of the Super-l # Define these early, so we can use debug logging ASAP if needed # ################################################################## LOG_FILE="${LOG_FILE:-"super-linter.log"}" # Default log file name (located in GITHUB_WORKSPACE folder) -LOG_LEVEL="${LOG_LEVEL:-VERBOSE}" # Default log level (VERBOSE, DEBUG, TRACE) +LOG_LEVEL="${LOG_LEVEL:-"INFO"}" declare -l CREATE_LOG_FILE CREATE_LOG_FILE="${CREATE_LOG_FILE:-"false"}" if [[ ${ACTIONS_RUNNER_DEBUG} == true ]]; then LOG_LEVEL="DEBUG"; fi -# Boolean to see trace logs -LOG_TRACE=$(if [[ ${LOG_LEVEL} == "TRACE" ]]; then echo "true"; fi) -export LOG_TRACE # Boolean to see debug logs LOG_DEBUG=$(if [[ ${LOG_LEVEL} == "DEBUG" || ${LOG_LEVEL} == "TRACE" ]]; then echo "true"; fi) export LOG_DEBUG -# Boolean to see verbose logs (info function) -LOG_VERBOSE=$(if [[ ${LOG_LEVEL} == "VERBOSE" || ${LOG_LEVEL} == "DEBUG" || ${LOG_LEVEL} == "TRACE" ]]; then echo "true"; fi) +# Boolean to see info logs +LOG_VERBOSE=$(if [[ ${LOG_LEVEL} == "INFO" || ${LOG_LEVEL} == "VERBOSE" || ${LOG_LEVEL} == "DEBUG" || ${LOG_LEVEL} == "TRACE" ]]; then echo "true"; fi) export LOG_VERBOSE # Boolean to see notice logs -LOG_NOTICE=$(if [[ ${LOG_LEVEL} == "NOTICE" || ${LOG_LEVEL} == "VERBOSE" || ${LOG_LEVEL} == "DEBUG" || ${LOG_LEVEL} == "TRACE" ]]; then echo "true"; fi) +LOG_NOTICE=$(if [[ ${LOG_LEVEL} == "NOTICE" || ${LOG_LEVEL} == "INFO" || ${LOG_LEVEL} == "VERBOSE" || ${LOG_LEVEL} == "DEBUG" || ${LOG_LEVEL} == "TRACE" ]]; then echo "true"; fi) export LOG_NOTICE # Boolean to see warn logs -LOG_WARN=$(if [[ ${LOG_LEVEL} == "WARN" || ${LOG_LEVEL} == "NOTICE" || ${LOG_LEVEL} == "VERBOSE" || ${LOG_LEVEL} == "DEBUG" || ${LOG_LEVEL} == "TRACE" ]]; then echo "true"; fi) +LOG_WARN=$(if [[ ${LOG_LEVEL} == "WARN" || ${LOG_LEVEL} == "NOTICE" || ${LOG_LEVEL} == "INFO" || ${LOG_LEVEL} == "VERBOSE" || ${LOG_LEVEL} == "DEBUG" || ${LOG_LEVEL} == "TRACE" ]]; then echo "true"; fi) export LOG_WARN # Boolean to see error logs -LOG_ERROR=$(if [[ ${LOG_LEVEL} == "ERROR" || ${LOG_LEVEL} == "WARN" || ${LOG_LEVEL} == "NOTICE" || ${LOG_LEVEL} == "VERBOSE" || ${LOG_LEVEL} == "DEBUG" || ${LOG_LEVEL} == "TRACE" ]]; then echo "true"; fi) +LOG_ERROR=$(if [[ ${LOG_LEVEL} == "ERROR" || ${LOG_LEVEL} == "WARN" || ${LOG_LEVEL} == "NOTICE" || ${LOG_LEVEL} == "INFO" || ${LOG_LEVEL} == "VERBOSE" || ${LOG_LEVEL} == "DEBUG" || ${LOG_LEVEL} == "TRACE" ]]; then echo "true"; fi) export LOG_ERROR +unset LOG_LEVEL + ######################### # Source Function Files # ######################### diff --git a/test/inspec/super-linter/controls/super_linter.rb b/test/inspec/super-linter/controls/super_linter.rb index cde9636b..debe4f87 100644 --- a/test/inspec/super-linter/controls/super_linter.rb +++ b/test/inspec/super-linter/controls/super_linter.rb @@ -10,6 +10,10 @@ control "super-linter-environment-variables" do describe os_env("VERSION_FILE") do its("content") { should eq version_file_path } end + + describe os_env("IMAGE") do + its("content") { should match(/^(standard|slim)$/) } + end end ################################################## diff --git a/test/lib/buildFileListTest.sh b/test/lib/buildFileListTest.sh index cccdc638..f8f3b806 100755 --- a/test/lib/buildFileListTest.sh +++ b/test/lib/buildFileListTest.sh @@ -4,8 +4,6 @@ set -o errexit set -o nounset set -o pipefail -# shellcheck disable=SC2034 -LOG_TRACE="true" # shellcheck disable=SC2034 LOG_DEBUG="true" # shellcheck disable=SC2034 diff --git a/test/lib/githubEventTest.sh b/test/lib/githubEventTest.sh index d6273707..bc310c54 100755 --- a/test/lib/githubEventTest.sh +++ b/test/lib/githubEventTest.sh @@ -4,8 +4,6 @@ set -o errexit set -o nounset set -o pipefail -# shellcheck disable=SC2034 -LOG_TRACE="true" # shellcheck disable=SC2034 LOG_DEBUG="true" # shellcheck disable=SC2034 diff --git a/test/lib/validationTest.sh b/test/lib/validationTest.sh index 715ee638..6e2e6514 100755 --- a/test/lib/validationTest.sh +++ b/test/lib/validationTest.sh @@ -4,8 +4,6 @@ set -o errexit set -o nounset set -o pipefail -# shellcheck disable=SC2034 -LOG_TRACE="true" # shellcheck disable=SC2034 LOG_DEBUG="true" # shellcheck disable=SC2034 @@ -17,6 +15,10 @@ LOG_WARN="true" # shellcheck disable=SC2034 LOG_ERROR="true" +# Default log level +# shellcheck disable=SC2034 +LOG_LEVEL="DEBUG" + # shellcheck source=/dev/null source "lib/functions/log.sh" @@ -46,5 +48,26 @@ function IsUnsignedIntegerFailureTest() { notice "${FUNCTION_NAME} PASS" } +# In the current implementation, there is no return value to assert +function ValidateDeprecatedVariablesTest() { + FUNCTION_NAME="${FUNCNAME[0]}" + + ERROR_ON_MISSING_EXEC_BIT="true" \ + ValidateDeprecatedVariables + EXPERIMENTAL_BATCH_WORKER="true" \ + ValidateDeprecatedVariables + LOG_LEVEL="TRACE" \ + ValidateDeprecatedVariables + LOG_LEVEL="VERBOSE" \ + ValidateDeprecatedVariables + VALIDATE_JSCPD_ALL_CODEBASE="true" \ + ValidateDeprecatedVariables + VALIDATE_KOTLIN_ANDROID="true" \ + ValidateDeprecatedVariables + + notice "${FUNCTION_NAME} PASS" +} + IsUnsignedIntegerSuccessTest IsUnsignedIntegerFailureTest +ValidateDeprecatedVariablesTest diff --git a/test/run-super-linter-tests.sh b/test/run-super-linter-tests.sh index f0f96b21..10f08a55 100755 --- a/test/run-super-linter-tests.sh +++ b/test/run-super-linter-tests.sh @@ -7,7 +7,7 @@ set -o pipefail SUPER_LINTER_TEST_CONTAINER_URL="${1}" TEST_FUNCTION_NAME="${2}" -COMMAND_TO_RUN=(docker run -e ACTIONS_RUNNER_DEBUG=true -e DEFAULT_BRANCH=main -e ENABLE_GITHUB_ACTIONS_GROUP_TITLE=true -e JSCPD_CONFIG_FILE=".jscpd-test-linters.json" -e RENOVATE_SHAREABLE_CONFIG_PRESET_FILE_NAMES="default.json,hoge.json" -e RUN_LOCAL=true -e TEST_CASE_RUN=true -e TYPESCRIPT_STANDARD_TSCONFIG_FILE=".github/linters/tsconfig.json" -v "$(pwd):/tmp/lint") +COMMAND_TO_RUN=(docker run -e DEFAULT_BRANCH=main -e ENABLE_GITHUB_ACTIONS_GROUP_TITLE=true -e JSCPD_CONFIG_FILE=".jscpd-test-linters.json" -e RENOVATE_SHAREABLE_CONFIG_PRESET_FILE_NAMES="default.json,hoge.json" -e RUN_LOCAL=true -e TEST_CASE_RUN=true -e TYPESCRIPT_STANDARD_TSCONFIG_FILE=".github/linters/tsconfig.json" -v "$(pwd):/tmp/lint") run_test_cases_expect_failure() { COMMAND_TO_RUN+=(-e ANSIBLE_DIRECTORY="/test/linters/ansible/bad" -e CHECKOV_FILE_NAME=".checkov-test-linters-failure.yaml" -e FILTER_REGEX_INCLUDE=".*bad.*") @@ -18,9 +18,16 @@ run_test_cases_expect_success() { COMMAND_TO_RUN+=(-e ANSIBLE_DIRECTORY="/test/linters/ansible/good" -e CHECKOV_FILE_NAME=".checkov-test-linters-success.yaml" -e FILTER_REGEX_INCLUDE=".*good.*") } +run_test_cases_log_level() { + run_test_cases_expect_success + LOG_LEVEL="NOTICE" +} + # Run the test setup function ${TEST_FUNCTION_NAME} +COMMAND_TO_RUN+=(-e LOG_LEVEL="${LOG_LEVEL:-"DEBUG"}") + COMMAND_TO_RUN+=("${SUPER_LINTER_TEST_CONTAINER_URL}") declare -i EXPECTED_EXIT_CODE