diff --git a/Makefile b/Makefile index 0cf3b853..cc1feda5 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ all: info docker test ## Run all targets. .PHONY: test -test: info validate-container-image-labels docker-build-check docker-dev-container-build-check npm-audit test-lib inspec lint-codebase fix-codebase test-default-config-files test-actions-runner-debug test-actions-steps-debug test-runner-debug test-find lint-subset-files test-custom-ssl-cert test-non-default-workdir test-git-flags test-non-default-home-directory test-git-initial-commit test-git-merge-commit-push test-log-level test-use-find-and-ignore-gitignored-files test-linters-expect-failure-log-level-notice test-bash-exec-library-expect-success test-bash-exec-library-expect-failure test-save-super-linter-output test-save-super-linter-output-custom-path test-save-super-linter-custom-summary test-custom-gitleaks-log-level test-dont-save-super-linter-log-file test-dont-save-super-linter-output test-linters test-linters-fix-mode ## Run the test suite +test: info validate-container-image-labels docker-build-check docker-dev-container-build-check npm-audit test-lib inspec lint-codebase fix-codebase test-default-config-files test-actions-runner-debug test-actions-steps-debug test-runner-debug test-find lint-subset-files test-custom-ssl-cert test-non-default-workdir test-git-flags test-non-default-home-directory test-git-initial-commit test-git-merge-commit-push test-log-level test-use-find-and-ignore-gitignored-files test-linters-expect-failure-log-level-notice test-bash-exec-library-expect-success test-bash-exec-library-expect-failure test-save-super-linter-output test-save-super-linter-output-custom-path test-save-super-linter-custom-summary test-custom-gitleaks-log-level test-dont-save-super-linter-log-file test-dont-save-super-linter-output test-linter-command-options test-linters test-linters-fix-mode ## 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 @@ -608,6 +608,13 @@ test-dont-save-super-linter-output: ## Run super-linter without saving Super-lin "run_test_case_dont_save_super_linter_output" \ "$(IMAGE)" +.PHONY: test-linter-command-options +test-linter-command-options: ## Run super-linter passing options to linters + $(CURDIR)/test/run-super-linter-tests.sh \ + $(SUPER_LINTER_TEST_CONTAINER_URL) \ + "run_test_case_linter_command_options" \ + "$(IMAGE)" + .PHONY: docker-dev-container-build-check ## Run Docker build checks against the dev-container image docker-dev-container-build-check: DOCKER_BUILDKIT=1 docker buildx build --check \ diff --git a/lib/functions/linterCommands.sh b/lib/functions/linterCommands.sh index 4c659c80..e018632e 100755 --- a/lib/functions/linterCommands.sh +++ b/lib/functions/linterCommands.sh @@ -8,178 +8,7 @@ # shellcheck source=/dev/null source /action/lib/globals/linterCommandsOptions.sh -########################## -# Define linter commands # -########################## - -# These commands are reused across several languages -PRETTIER_COMMAND=(prettier) -DOTNET_FORMAT_COMMAND=(dotnet format) - -LINTER_COMMANDS_ARRAY_ANSIBLE=(ansible-lint -c "${ANSIBLE_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_ARM=(pwsh -NoProfile -NoLogo -Command "\"Import-Module ${ARM_TTK_PSD1} ; \\\${config} = \\\$(Import-PowerShellDataFile -Path ${ARM_LINTER_RULES}) ; Test-AzTemplate @config -TemplatePath '{}'; if (\\\${Error}.Count) { exit 1 }\"") -LINTER_COMMANDS_ARRAY_BASH=(shellcheck --color --rcfile "${BASH_LINTER_RULES}") -# This check and the BASH_SEVERITY variable are needed until Shellcheck supports -# setting severity using its config file. -# Ref: https://github.com/koalaman/shellcheck/issues/2178 -if [ -n "${BASH_SEVERITY}" ]; then - export BASH_SEVERITY - LINTER_COMMANDS_ARRAY_BASH+=(--severity="${BASH_SEVERITY}") -fi -LINTER_COMMANDS_ARRAY_BASH_EXEC=(bash-exec '{}') -if [ "${BASH_EXEC_IGNORE_LIBRARIES}" == 'true' ]; then - debug "Enabling bash-exec option to ignore shell library files." - LINTER_COMMANDS_ARRAY_BASH_EXEC+=('true') -fi -LINTER_COMMANDS_ARRAY_CHECKOV=(checkov --config-file "${CHECKOV_LINTER_RULES}") -if CheckovConfigurationFileContainsDirectoryOption "${CHECKOV_LINTER_RULES}"; then - # Consume the input as we do with ANSIBLE - debug "Consume the input of the Checkov command because we don't need to add it as an argument." - LINTER_COMMANDS_ARRAY_CHECKOV+=("&& echo \"Got the list of directories to lint from the configuration file: {}\"") -else - debug "Adding the '--directory' option to the Checkov command." - LINTER_COMMANDS_ARRAY_CHECKOV+=(--directory) -fi -LINTER_COMMANDS_ARRAY_CLANG_FORMAT=(clang-format --style=file:"${CLANG_FORMAT_LINTER_RULES}" --Werror) -LINTER_COMMANDS_ARRAY_CLOJURE=(clj-kondo --config "${CLOJURE_LINTER_RULES}" --lint) -LINTER_COMMANDS_ARRAY_CLOUDFORMATION=(cfn-lint --config-file "${CLOUDFORMATION_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_COFFEESCRIPT=(coffeelint -f "${COFFEESCRIPT_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_CPP=(cpplint) -LINTER_COMMANDS_ARRAY_CSHARP=("${DOTNET_FORMAT_COMMAND[@]}" whitespace --folder --exclude / --include "{/}") -LINTER_COMMANDS_ARRAY_CSS=(stylelint --config "${CSS_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_CSS_PRETTIER=("${PRETTIER_COMMAND[@]}") -LINTER_COMMANDS_ARRAY_DART=(dart analyze --fatal-infos --fatal-warnings) -LINTER_COMMANDS_ARRAY_DOCKERFILE_HADOLINT=(hadolint -c "${DOCKERFILE_HADOLINT_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_DOTNET_SLN_FORMAT_ANALYZERS=("${DOTNET_FORMAT_COMMAND[@]}" analyzers) -LINTER_COMMANDS_ARRAY_DOTNET_SLN_FORMAT_STYLE=("${DOTNET_FORMAT_COMMAND[@]}" style) -LINTER_COMMANDS_ARRAY_DOTNET_SLN_FORMAT_WHITESPACE=("${DOTNET_FORMAT_COMMAND[@]}" whitespace) -LINTER_COMMANDS_ARRAY_EDITORCONFIG=(editorconfig-checker -config "${EDITORCONFIG_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_ENV=(dotenv-linter) -LINTER_COMMANDS_ARRAY_GITHUB_ACTIONS=(actionlint -config-file "${GITHUB_ACTIONS_LINTER_RULES}") -if [ "${GITHUB_ACTIONS_COMMAND_ARGS}" != "null" ] && [ -n "${GITHUB_ACTIONS_COMMAND_ARGS}" ]; then - export GITHUB_ACTIONS_COMMAND_ARGS - AddOptionsToCommand "LINTER_COMMANDS_ARRAY_GITHUB_ACTIONS" "${GITHUB_ACTIONS_COMMAND_ARGS}" -fi -LINTER_COMMANDS_ARRAY_GITLEAKS=(gitleaks detect --no-banner --no-git --redact --config "${GITLEAKS_LINTER_RULES}" --verbose) -if [ -n "${GITLEAKS_LOG_LEVEL:-}" ]; then - export GITLEAKS_LOG_LEVEL - LINTER_COMMANDS_ARRAY_GITLEAKS+=("${GITLEAKS_LOG_LEVEL_OPTIONS[@]}" "${GITLEAKS_LOG_LEVEL}") - debug "Add log options to the Gitleaks command: ${LINTER_COMMANDS_ARRAY_GITLEAKS[*]}" -fi -LINTER_COMMANDS_ARRAY_GITLEAKS+=(--source) -LINTER_COMMANDS_ARRAY_GHERKIN=(gherkin-lint -c "${GHERKIN_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_GIT_COMMITLINT=(commitlint --verbose --cwd "{}") -if [[ -n "${GITHUB_BEFORE_SHA:-}" ]]; then - LINTER_COMMANDS_ARRAY_GIT_COMMITLINT+=(--from "${GITHUB_BEFORE_SHA}" --to "${GITHUB_SHA}") -else - LINTER_COMMANDS_ARRAY_GIT_COMMITLINT+=(--last) -fi -if [ "${ENABLE_COMMITLINT_STRICT_MODE:-}" == 'true' ]; then - LINTER_COMMANDS_ARRAY_GIT_COMMITLINT+=("${COMMITLINT_STRICT_MODE_OPTIONS[@]}") -fi -LINTER_COMMANDS_ARRAY_GIT_MERGE_CONFLICT_MARKERS=(git-merge-conflict-markers) -LINTER_COMMANDS_ARRAY_GO=(golangci-lint run -c "${GO_LINTER_RULES}" --fast) -LINTER_COMMANDS_ARRAY_GO_MODULES=(golangci-lint run --allow-parallel-runners -c "${GO_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_GO_RELEASER=(goreleaser check) -LINTER_COMMANDS_ARRAY_GOOGLE_JAVA_FORMAT=(java -jar /usr/bin/google-java-format) -LINTER_COMMANDS_ARRAY_GRAPHQL_PRETTIER=("${PRETTIER_COMMAND[@]}") -LINTER_COMMANDS_ARRAY_GROOVY=(npm-groovy-lint -c "${GROOVY_LINTER_RULES}" --failon warning --no-insight) -LINTER_COMMANDS_ARRAY_HTML=(htmlhint --config "${HTML_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_HTML_PRETTIER=("${PRETTIER_COMMAND[@]}") -LINTER_COMMANDS_ARRAY_JAVA=(java -jar /usr/bin/checkstyle -c "${JAVA_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_JAVASCRIPT_ES=(eslint -c "${JAVASCRIPT_ES_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_JAVASCRIPT_PRETTIER=("${PRETTIER_COMMAND[@]}") -LINTER_COMMANDS_ARRAY_JAVASCRIPT_STANDARD=(standard "${JAVASCRIPT_STANDARD_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_JSCPD=(jscpd --config "${JSCPD_LINTER_RULES}") -JSCPD_GITIGNORE_OPTION="--gitignore" -if [[ "${IGNORE_GITIGNORED_FILES}" == "true" ]]; then - debug "IGNORE_GITIGNORED_FILES is ${IGNORE_GITIGNORED_FILES}. Enable Jscpd option to ignore files that Git ignores (${JSCPD_GITIGNORE_OPTION})" - # Users can also add the '"gitignore": true' option in their Jscpd config files to achieve the same functionality - # but we want to respect IGNORE_GITIGNORED_FILES - LINTER_COMMANDS_ARRAY_JSCPD+=("${JSCPD_GITIGNORE_OPTION}") -fi -LINTER_COMMANDS_ARRAY_JSON=(eslint -c "${JAVASCRIPT_ES_LINTER_RULES}" --ext '.json') -LINTER_COMMANDS_ARRAY_JSON_PRETTIER=("${PRETTIER_COMMAND[@]}") -LINTER_COMMANDS_ARRAY_JSONC=(eslint -c "${JAVASCRIPT_ES_LINTER_RULES}" --ext '.json5,.jsonc') -LINTER_COMMANDS_ARRAY_JSONC_PRETTIER=("${PRETTIER_COMMAND[@]}") -LINTER_COMMANDS_ARRAY_JSX=(eslint -c "${JSX_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_JSX_PRETTIER=("${PRETTIER_COMMAND[@]}") -LINTER_COMMANDS_ARRAY_KOTLIN=(ktlint "{/}") -LINTER_COMMANDS_ARRAY_KUBERNETES_KUBECONFORM=(kubeconform -strict) -if [ "${KUBERNETES_KUBECONFORM_OPTIONS}" != "null" ] && [ -n "${KUBERNETES_KUBECONFORM_OPTIONS}" ]; then - export KUBERNETES_KUBECONFORM_OPTIONS - AddOptionsToCommand "LINTER_COMMANDS_ARRAY_KUBERNETES_KUBECONFORM" "${KUBERNETES_KUBECONFORM_OPTIONS}" -fi -LINTER_COMMANDS_ARRAY_LATEX=(chktex -q -l "${LATEX_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_LUA=(luacheck --config "${LUA_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_MARKDOWN=(markdownlint -c "${MARKDOWN_LINTER_RULES}") -if [ -n "${MARKDOWN_CUSTOM_RULE_GLOBS}" ]; then - IFS="," read -r -a MARKDOWN_CUSTOM_RULE_GLOBS_ARRAY <<<"${MARKDOWN_CUSTOM_RULE_GLOBS}" - for glob in "${MARKDOWN_CUSTOM_RULE_GLOBS_ARRAY[@]}"; do - if [ -z "${LINTER_RULES_PATH}" ]; then - LINTER_COMMANDS_ARRAY_MARKDOWN+=(-r "${GITHUB_WORKSPACE}/${glob}") - else - LINTER_COMMANDS_ARRAY_MARKDOWN+=(-r "${GITHUB_WORKSPACE}/${LINTER_RULES_PATH}/${glob}") - fi - done -fi -LINTER_COMMANDS_ARRAY_MARKDOWN_PRETTIER=("${PRETTIER_COMMAND[@]}") -LINTER_COMMANDS_ARRAY_NATURAL_LANGUAGE=(textlint -c "${NATURAL_LANGUAGE_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_OPENAPI=(spectral lint -r "${OPENAPI_LINTER_RULES}" -D) -LINTER_COMMANDS_ARRAY_PERL=(perlcritic) -if [ "${PERL_PERLCRITIC_OPTIONS}" != "null" ] && [ -n "${PERL_PERLCRITIC_OPTIONS}" ]; then - export PERL_PERLCRITIC_OPTIONS - AddOptionsToCommand "LINTER_COMMANDS_ARRAY_PERL" "${PERL_PERLCRITIC_OPTIONS}" -fi -LINTER_COMMANDS_ARRAY_PHP_BUILTIN=(php -l -c "${PHP_BUILTIN_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_PHP_PHPCS=(phpcs --standard="${PHP_PHPCS_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_PHP_PHPSTAN=(phpstan analyse --no-progress --no-ansi --memory-limit 1G -c "${PHP_PHPSTAN_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_PHP_PSALM=(psalm --config="${PHP_PSALM_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_POWERSHELL=(Invoke-ScriptAnalyzer -EnableExit -Settings "${POWERSHELL_LINTER_RULES}" -Path '{}') -LINTER_COMMANDS_ARRAY_PROTOBUF=(protolint lint -config_path "${PROTOBUF_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_PYTHON_BLACK=(black --config "${PYTHON_BLACK_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_PYTHON_PYLINT=(pylint --rcfile "${PYTHON_PYLINT_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_PYTHON_FLAKE8=(flake8 --config="${PYTHON_FLAKE8_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_PYTHON_ISORT=(isort --sp "${PYTHON_ISORT_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_PYTHON_MYPY=(mypy --config-file "${PYTHON_MYPY_LINTER_RULES}" --install-types --non-interactive) -LINTER_COMMANDS_ARRAY_PYTHON_PYINK=(pyink --config "${PYTHON_PYINK_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_PYTHON_RUFF=(ruff check --config "${PYTHON_RUFF_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_R=(R --slave -e "\"lints <- lintr::lint('{}');print(lints);errors <- purrr::keep(lints, ~ .\\\$type == 'error');quit(save = 'no', status = if (length(errors) > 0) 1 else 0)\"") -LINTER_COMMANDS_ARRAY_RAKU=(raku) -LINTER_COMMANDS_ARRAY_RENOVATE=(renovate-config-validator --strict) -LINTER_COMMANDS_ARRAY_RUBY=(rubocop -c "${RUBY_LINTER_RULES}" --force-exclusion --ignore-unrecognized-cops) -LINTER_COMMANDS_ARRAY_RUST_2015=(rustfmt --edition 2015) -LINTER_COMMANDS_ARRAY_RUST_2018=(rustfmt --edition 2018) -LINTER_COMMANDS_ARRAY_RUST_2021=(rustfmt --edition 2021) -LINTER_COMMANDS_ARRAY_RUST_CLIPPY=(cargo clippy) -if [ -n "${RUST_CLIPPY_COMMAND_OPTIONS:-}" ]; then - export RUST_CLIPPY_COMMAND_OPTIONS - AddOptionsToCommand "LINTER_COMMANDS_ARRAY_RUST_CLIPPY" "${RUST_CLIPPY_COMMAND_OPTIONS}" -fi -LINTER_COMMANDS_ARRAY_SCALAFMT=(scalafmt --config "${SCALAFMT_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_SHELL_SHFMT=(shfmt) -LINTER_COMMANDS_ARRAY_SNAKEMAKE_LINT=(snakemake --lint -s) -LINTER_COMMANDS_ARRAY_SNAKEMAKE_SNAKEFMT=(snakefmt --config "${SNAKEMAKE_SNAKEFMT_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_STATES=(asl-validator --json-path) -LINTER_COMMANDS_ARRAY_SQLFLUFF=(sqlfluff) -LINTER_COMMANDS_ARRAY_TEKTON=(tekton-lint) -LINTER_COMMANDS_ARRAY_TERRAFORM_FMT=(terraform fmt) -LINTER_COMMANDS_ARRAY_TERRAFORM_TFLINT=("TF_DATA_DIR=\"/tmp/.terraform-TERRAFORM_TFLINT-{//}\"" tflint -c "${TERRAFORM_TFLINT_LINTER_RULES}" "--filter=\"{/}\"") -LINTER_COMMANDS_ARRAY_TERRAFORM_TERRASCAN=(terrascan scan -i terraform -t all -c "${TERRAFORM_TERRASCAN_LINTER_RULES}" -f) -LINTER_COMMANDS_ARRAY_TERRAGRUNT=(terragrunt hclfmt --terragrunt-check --terragrunt-log-level error --terragrunt-hclfmt-file) -LINTER_COMMANDS_ARRAY_TSX=(eslint -c "${TSX_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_TYPESCRIPT_ES=(eslint -c "${TYPESCRIPT_ES_LINTER_RULES}") -LINTER_COMMANDS_ARRAY_TYPESCRIPT_PRETTIER=("${PRETTIER_COMMAND[@]}") -LINTER_COMMANDS_ARRAY_TYPESCRIPT_STANDARD=(ts-standard --parser @typescript-eslint/parser --plugin @typescript-eslint/eslint-plugin --project "${TYPESCRIPT_STANDARD_TSCONFIG_FILE}") -LINTER_COMMANDS_ARRAY_VUE_PRETTIER=("${PRETTIER_COMMAND[@]}") -LINTER_COMMANDS_ARRAY_XML=(xmllint) -LINTER_COMMANDS_ARRAY_YAML=(yamllint -c "${YAML_LINTER_RULES}" -f parsable) -if [ "${YAML_ERROR_ON_WARNING}" == 'true' ]; then - LINTER_COMMANDS_ARRAY_YAML+=(--strict) -fi -LINTER_COMMANDS_ARRAY_YAML_PRETTIER=("${PRETTIER_COMMAND[@]}") - -function InitFixModeOptionsAndCommands() { +InitFixModeOptionsAndCommands() { local LANGUAGE="${1}" local FIX_MODE_VARIABLE_NAME="FIX_${LANGUAGE}" debug "Check if ${LANGUAGE} command needs check only mode or fix mode options or commands by checking if ${FIX_MODE_VARIABLE_NAME} variable is defined." @@ -259,3 +88,182 @@ AddOptionsToCommand() { unset -n COMMAND_ARRAY_NAME } + +########################## +# Define linter commands # +########################## + +# These commands are reused across several languages +PRETTIER_COMMAND=(prettier) +DOTNET_FORMAT_COMMAND=(dotnet format) + +LINTER_COMMANDS_ARRAY_ANSIBLE=(ansible-lint -c "${ANSIBLE_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_ARM=(pwsh -NoProfile -NoLogo -Command "\"Import-Module ${ARM_TTK_PSD1} ; \\\${config} = \\\$(Import-PowerShellDataFile -Path ${ARM_LINTER_RULES}) ; Test-AzTemplate @config -TemplatePath '{}'; if (\\\${Error}.Count) { exit 1 }\"") +LINTER_COMMANDS_ARRAY_BASH=(shellcheck --color --rcfile "${BASH_LINTER_RULES}") +# This check and the BASH_SEVERITY variable are needed until Shellcheck supports +# setting severity using its config file. +# Ref: https://github.com/koalaman/shellcheck/issues/2178 +if [ -n "${BASH_SEVERITY}" ]; then + export BASH_SEVERITY + LINTER_COMMANDS_ARRAY_BASH+=(--severity="${BASH_SEVERITY}") +fi +LINTER_COMMANDS_ARRAY_BASH_EXEC=(bash-exec '{}') +if [ "${BASH_EXEC_IGNORE_LIBRARIES}" == 'true' ]; then + debug "Enabling bash-exec option to ignore shell library files." + LINTER_COMMANDS_ARRAY_BASH_EXEC+=('true') +fi +LINTER_COMMANDS_ARRAY_CHECKOV=(checkov --config-file "${CHECKOV_LINTER_RULES}") +if CheckovConfigurationFileContainsDirectoryOption "${CHECKOV_LINTER_RULES}"; then + # Consume the input as we do with ANSIBLE + debug "Consume the input of the Checkov command because we don't need to add it as an argument." + LINTER_COMMANDS_ARRAY_CHECKOV+=("&& echo \"Got the list of directories to lint from the configuration file: {}\"") +else + debug "Adding the '--directory' option to the Checkov command." + LINTER_COMMANDS_ARRAY_CHECKOV+=(--directory) +fi +LINTER_COMMANDS_ARRAY_CLANG_FORMAT=(clang-format --style=file:"${CLANG_FORMAT_LINTER_RULES}" --Werror) +LINTER_COMMANDS_ARRAY_CLOJURE=(clj-kondo --config "${CLOJURE_LINTER_RULES}" --lint) +LINTER_COMMANDS_ARRAY_CLOUDFORMATION=(cfn-lint --config-file "${CLOUDFORMATION_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_COFFEESCRIPT=(coffeelint -f "${COFFEESCRIPT_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_CPP=(cpplint) +LINTER_COMMANDS_ARRAY_CSHARP=("${DOTNET_FORMAT_COMMAND[@]}" whitespace --folder --exclude / --include "{/}") +LINTER_COMMANDS_ARRAY_CSS=(stylelint --config "${CSS_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_CSS_PRETTIER=("${PRETTIER_COMMAND[@]}") +LINTER_COMMANDS_ARRAY_DART=(dart analyze --fatal-infos --fatal-warnings) +LINTER_COMMANDS_ARRAY_DOCKERFILE_HADOLINT=(hadolint -c "${DOCKERFILE_HADOLINT_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_DOTNET_SLN_FORMAT_ANALYZERS=("${DOTNET_FORMAT_COMMAND[@]}" analyzers) +LINTER_COMMANDS_ARRAY_DOTNET_SLN_FORMAT_STYLE=("${DOTNET_FORMAT_COMMAND[@]}" style) +LINTER_COMMANDS_ARRAY_DOTNET_SLN_FORMAT_WHITESPACE=("${DOTNET_FORMAT_COMMAND[@]}" whitespace) +LINTER_COMMANDS_ARRAY_EDITORCONFIG=(editorconfig-checker -config "${EDITORCONFIG_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_ENV=(dotenv-linter) +LINTER_COMMANDS_ARRAY_GITHUB_ACTIONS=(actionlint -config-file "${GITHUB_ACTIONS_LINTER_RULES}") +if [ "${GITHUB_ACTIONS_COMMAND_ARGS}" != "null" ] && [ -n "${GITHUB_ACTIONS_COMMAND_ARGS}" ]; then + export GITHUB_ACTIONS_COMMAND_ARGS + if ! AddOptionsToCommand "LINTER_COMMANDS_ARRAY_GITHUB_ACTIONS" "${GITHUB_ACTIONS_COMMAND_ARGS}"; then + fatal "Error while adding options to GitHub Actions command" + fi +fi +LINTER_COMMANDS_ARRAY_GITLEAKS=(gitleaks detect --no-banner --no-git --redact --config "${GITLEAKS_LINTER_RULES}" --verbose) +if [ -n "${GITLEAKS_LOG_LEVEL:-}" ]; then + export GITLEAKS_LOG_LEVEL + LINTER_COMMANDS_ARRAY_GITLEAKS+=("${GITLEAKS_LOG_LEVEL_OPTIONS[@]}" "${GITLEAKS_LOG_LEVEL}") + debug "Add log options to the Gitleaks command: ${LINTER_COMMANDS_ARRAY_GITLEAKS[*]}" +fi +LINTER_COMMANDS_ARRAY_GITLEAKS+=(--source) +LINTER_COMMANDS_ARRAY_GHERKIN=(gherkin-lint -c "${GHERKIN_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_GIT_COMMITLINT=(commitlint --verbose --cwd "{}") +if [[ -n "${GITHUB_BEFORE_SHA:-}" ]]; then + LINTER_COMMANDS_ARRAY_GIT_COMMITLINT+=(--from "${GITHUB_BEFORE_SHA}" --to "${GITHUB_SHA}") +else + LINTER_COMMANDS_ARRAY_GIT_COMMITLINT+=(--last) +fi +if [ "${ENABLE_COMMITLINT_STRICT_MODE:-}" == 'true' ]; then + LINTER_COMMANDS_ARRAY_GIT_COMMITLINT+=("${COMMITLINT_STRICT_MODE_OPTIONS[@]}") +fi +LINTER_COMMANDS_ARRAY_GIT_MERGE_CONFLICT_MARKERS=(git-merge-conflict-markers) +LINTER_COMMANDS_ARRAY_GO=(golangci-lint run -c "${GO_LINTER_RULES}" --fast) +LINTER_COMMANDS_ARRAY_GO_MODULES=(golangci-lint run --allow-parallel-runners -c "${GO_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_GO_RELEASER=(goreleaser check) +LINTER_COMMANDS_ARRAY_GOOGLE_JAVA_FORMAT=(java -jar /usr/bin/google-java-format) +LINTER_COMMANDS_ARRAY_GRAPHQL_PRETTIER=("${PRETTIER_COMMAND[@]}") +LINTER_COMMANDS_ARRAY_GROOVY=(npm-groovy-lint -c "${GROOVY_LINTER_RULES}" --failon warning --no-insight) +LINTER_COMMANDS_ARRAY_HTML=(htmlhint --config "${HTML_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_HTML_PRETTIER=("${PRETTIER_COMMAND[@]}") +LINTER_COMMANDS_ARRAY_JAVA=(java -jar /usr/bin/checkstyle -c "${JAVA_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_JAVASCRIPT_ES=(eslint -c "${JAVASCRIPT_ES_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_JAVASCRIPT_PRETTIER=("${PRETTIER_COMMAND[@]}") +LINTER_COMMANDS_ARRAY_JAVASCRIPT_STANDARD=(standard "${JAVASCRIPT_STANDARD_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_JSCPD=(jscpd --config "${JSCPD_LINTER_RULES}") +JSCPD_GITIGNORE_OPTION="--gitignore" +if [[ "${IGNORE_GITIGNORED_FILES}" == "true" ]]; then + debug "IGNORE_GITIGNORED_FILES is ${IGNORE_GITIGNORED_FILES}. Enable Jscpd option to ignore files that Git ignores (${JSCPD_GITIGNORE_OPTION})" + # Users can also add the '"gitignore": true' option in their Jscpd config files to achieve the same functionality + # but we want to respect IGNORE_GITIGNORED_FILES + LINTER_COMMANDS_ARRAY_JSCPD+=("${JSCPD_GITIGNORE_OPTION}") +fi +LINTER_COMMANDS_ARRAY_JSON=(eslint -c "${JAVASCRIPT_ES_LINTER_RULES}" --ext '.json') +LINTER_COMMANDS_ARRAY_JSON_PRETTIER=("${PRETTIER_COMMAND[@]}") +LINTER_COMMANDS_ARRAY_JSONC=(eslint -c "${JAVASCRIPT_ES_LINTER_RULES}" --ext '.json5,.jsonc') +LINTER_COMMANDS_ARRAY_JSONC_PRETTIER=("${PRETTIER_COMMAND[@]}") +LINTER_COMMANDS_ARRAY_JSX=(eslint -c "${JSX_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_JSX_PRETTIER=("${PRETTIER_COMMAND[@]}") +LINTER_COMMANDS_ARRAY_KOTLIN=(ktlint "{/}") +LINTER_COMMANDS_ARRAY_KUBERNETES_KUBECONFORM=(kubeconform -strict) +if [ "${KUBERNETES_KUBECONFORM_OPTIONS}" != "null" ] && [ -n "${KUBERNETES_KUBECONFORM_OPTIONS}" ]; then + export KUBERNETES_KUBECONFORM_OPTIONS + if ! AddOptionsToCommand "LINTER_COMMANDS_ARRAY_KUBERNETES_KUBECONFORM" "${KUBERNETES_KUBECONFORM_OPTIONS}"; then + fatal "Error while adding options to Kubeconform command" + fi +fi +LINTER_COMMANDS_ARRAY_LATEX=(chktex -q -l "${LATEX_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_LUA=(luacheck --config "${LUA_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_MARKDOWN=(markdownlint -c "${MARKDOWN_LINTER_RULES}") +if [ -n "${MARKDOWN_CUSTOM_RULE_GLOBS}" ]; then + IFS="," read -r -a MARKDOWN_CUSTOM_RULE_GLOBS_ARRAY <<<"${MARKDOWN_CUSTOM_RULE_GLOBS}" + for glob in "${MARKDOWN_CUSTOM_RULE_GLOBS_ARRAY[@]}"; do + if [ -z "${LINTER_RULES_PATH}" ]; then + LINTER_COMMANDS_ARRAY_MARKDOWN+=(-r "${GITHUB_WORKSPACE}/${glob}") + else + LINTER_COMMANDS_ARRAY_MARKDOWN+=(-r "${GITHUB_WORKSPACE}/${LINTER_RULES_PATH}/${glob}") + fi + done +fi +LINTER_COMMANDS_ARRAY_MARKDOWN_PRETTIER=("${PRETTIER_COMMAND[@]}") +LINTER_COMMANDS_ARRAY_NATURAL_LANGUAGE=(textlint -c "${NATURAL_LANGUAGE_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_OPENAPI=(spectral lint -r "${OPENAPI_LINTER_RULES}" -D) +LINTER_COMMANDS_ARRAY_PERL=(perlcritic) +if [ "${PERL_PERLCRITIC_OPTIONS}" != "null" ] && [ -n "${PERL_PERLCRITIC_OPTIONS}" ]; then + export PERL_PERLCRITIC_OPTIONS + if ! AddOptionsToCommand "LINTER_COMMANDS_ARRAY_PERL" "${PERL_PERLCRITIC_OPTIONS}"; then + fatal "Error while adding options to Perlcritic command" + fi +fi +LINTER_COMMANDS_ARRAY_PHP_BUILTIN=(php -l -c "${PHP_BUILTIN_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_PHP_PHPCS=(phpcs --standard="${PHP_PHPCS_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_PHP_PHPSTAN=(phpstan analyse --no-progress --no-ansi --memory-limit 1G -c "${PHP_PHPSTAN_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_PHP_PSALM=(psalm --config="${PHP_PSALM_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_POWERSHELL=(Invoke-ScriptAnalyzer -EnableExit -Settings "${POWERSHELL_LINTER_RULES}" -Path '{}') +LINTER_COMMANDS_ARRAY_PROTOBUF=(protolint lint -config_path "${PROTOBUF_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_PYTHON_BLACK=(black --config "${PYTHON_BLACK_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_PYTHON_PYLINT=(pylint --rcfile "${PYTHON_PYLINT_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_PYTHON_FLAKE8=(flake8 --config="${PYTHON_FLAKE8_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_PYTHON_ISORT=(isort --sp "${PYTHON_ISORT_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_PYTHON_MYPY=(mypy --config-file "${PYTHON_MYPY_LINTER_RULES}" --install-types --non-interactive) +LINTER_COMMANDS_ARRAY_PYTHON_PYINK=(pyink --config "${PYTHON_PYINK_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_PYTHON_RUFF=(ruff check --config "${PYTHON_RUFF_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_R=(R --slave -e "\"lints <- lintr::lint('{}');print(lints);errors <- purrr::keep(lints, ~ .\\\$type == 'error');quit(save = 'no', status = if (length(errors) > 0) 1 else 0)\"") +LINTER_COMMANDS_ARRAY_RAKU=(raku) +LINTER_COMMANDS_ARRAY_RENOVATE=(renovate-config-validator --strict) +LINTER_COMMANDS_ARRAY_RUBY=(rubocop -c "${RUBY_LINTER_RULES}" --force-exclusion --ignore-unrecognized-cops) +LINTER_COMMANDS_ARRAY_RUST_2015=(rustfmt --edition 2015) +LINTER_COMMANDS_ARRAY_RUST_2018=(rustfmt --edition 2018) +LINTER_COMMANDS_ARRAY_RUST_2021=(rustfmt --edition 2021) +LINTER_COMMANDS_ARRAY_RUST_CLIPPY=(cargo clippy) +if [ -n "${RUST_CLIPPY_COMMAND_OPTIONS:-}" ]; then + export RUST_CLIPPY_COMMAND_OPTIONS + if ! AddOptionsToCommand "LINTER_COMMANDS_ARRAY_RUST_CLIPPY" "${RUST_CLIPPY_COMMAND_OPTIONS}"; then + fatal "Error while adding options to Rust Clippy command" + fi +fi +LINTER_COMMANDS_ARRAY_SCALAFMT=(scalafmt --config "${SCALAFMT_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_SHELL_SHFMT=(shfmt) +LINTER_COMMANDS_ARRAY_SNAKEMAKE_LINT=(snakemake --lint -s) +LINTER_COMMANDS_ARRAY_SNAKEMAKE_SNAKEFMT=(snakefmt --config "${SNAKEMAKE_SNAKEFMT_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_STATES=(asl-validator --json-path) +LINTER_COMMANDS_ARRAY_SQLFLUFF=(sqlfluff) +LINTER_COMMANDS_ARRAY_TEKTON=(tekton-lint) +LINTER_COMMANDS_ARRAY_TERRAFORM_FMT=(terraform fmt) +LINTER_COMMANDS_ARRAY_TERRAFORM_TFLINT=("TF_DATA_DIR=\"/tmp/.terraform-TERRAFORM_TFLINT-{//}\"" tflint -c "${TERRAFORM_TFLINT_LINTER_RULES}" "--filter=\"{/}\"") +LINTER_COMMANDS_ARRAY_TERRAFORM_TERRASCAN=(terrascan scan -i terraform -t all -c "${TERRAFORM_TERRASCAN_LINTER_RULES}" -f) +LINTER_COMMANDS_ARRAY_TERRAGRUNT=(terragrunt hclfmt --terragrunt-check --terragrunt-log-level error --terragrunt-hclfmt-file) +LINTER_COMMANDS_ARRAY_TSX=(eslint -c "${TSX_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_TYPESCRIPT_ES=(eslint -c "${TYPESCRIPT_ES_LINTER_RULES}") +LINTER_COMMANDS_ARRAY_TYPESCRIPT_PRETTIER=("${PRETTIER_COMMAND[@]}") +LINTER_COMMANDS_ARRAY_TYPESCRIPT_STANDARD=(ts-standard --parser @typescript-eslint/parser --plugin @typescript-eslint/eslint-plugin --project "${TYPESCRIPT_STANDARD_TSCONFIG_FILE}") +LINTER_COMMANDS_ARRAY_VUE_PRETTIER=("${PRETTIER_COMMAND[@]}") +LINTER_COMMANDS_ARRAY_XML=(xmllint) +LINTER_COMMANDS_ARRAY_YAML=(yamllint -c "${YAML_LINTER_RULES}" -f parsable) +if [ "${YAML_ERROR_ON_WARNING}" == 'true' ]; then + LINTER_COMMANDS_ARRAY_YAML+=(--strict) +fi +LINTER_COMMANDS_ARRAY_YAML_PRETTIER=("${PRETTIER_COMMAND[@]}") diff --git a/lib/functions/worker.sh b/lib/functions/worker.sh index defd5859..19fd1cf0 100755 --- a/lib/functions/worker.sh +++ b/lib/functions/worker.sh @@ -149,7 +149,9 @@ function LintCodebase() { debug "PARALLEL_COMMAND for ${FILE_TYPE} after updating the working directory: ${PARALLEL_COMMAND[*]}" # shellcheck source=/dev/null - source /action/lib/functions/linterCommands.sh + if ! source /action/lib/functions/linterCommands.sh; then + fatal "Error while sourcing linter commands" + fi # Dynamically add arguments and commands to each linter command as needed if ! InitFixModeOptionsAndCommands "${FILE_TYPE}"; then fatal "Error while inizializing fix mode and check only options and commands before running linter for ${FILE_TYPE}" diff --git a/test/run-super-linter-tests.sh b/test/run-super-linter-tests.sh index d677249f..22d72a1f 100755 --- a/test/run-super-linter-tests.sh +++ b/test/run-super-linter-tests.sh @@ -191,6 +191,12 @@ run_test_case_gitleaks_custom_log_level() { COMMAND_TO_RUN+=(--env GITLEAKS_LOG_LEVEL="warn") } +run_test_case_linter_command_options() { + run_test_cases_expect_success + # Pick one arbitrary linter to pass options to + COMMAND_TO_RUN+=(--env KUBERNETES_KUBECONFORM_OPTIONS="-ignore-missing-schemas -schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json' --ignore-filename-pattern '.*tpl\.yaml'") +} + run_test_case_fix_mode() { VERIFY_FIX_MODE="true"