From 91dc6d7234403576113cf4fa8d251b13f1a4108a Mon Sep 17 00:00:00 2001 From: Marco Ferrari Date: Mon, 12 Aug 2024 12:31:38 +0200 Subject: [PATCH] fix: add missing fix mode options and test cases (#5987) - Add missing fix mode options for: CLANG_FORMAT, ENV, GOOGLE_JAVA_FORMAT, NATURAL_LANGUAGE, PYTHON_ISORT, RUST_CLIPPY. - Refactor linter tests to make them shorter because there's no need to have big test files. - Refactor 'bad' linter tests for linters that support fix mode so they contain only automatically fixable issues. This is needed to avoid adding another set of 'bad' linter tests for fix mode. - Provide configuration files for linters that support fix mode and for which the default configuration is not suitable to enable fix mode: ansible-lint, ESLint, golangci-lint. - Add a test case for linter commands options for linters that support fix mode, to ensure that fix mode and check-only mode options have been defined. - Refactor the fix mode test to check if linters actually applied modifications to files. - Update documentation about adding test cases for linters that support fix mode. - Don't exit with a fatal error if VALIDATE_xxx is false when testing fix mode because not all linters support fix mode. To enable this, set the new FIX_MODE_TEST_CASE_RUN variable to true. --- .github/linters/.eslintrc.yml | 44 +++ .github/linters/.golangci.yml | 7 + .github/linters/.jscpd.json | 1 + Makefile | 15 +- README.md | 16 +- docs/add-new-linter.md | 11 +- lib/functions/validation.sh | 1 + lib/functions/worker.sh | 7 +- lib/globals/linterCommandsOptions.sh | 8 +- lib/linter.sh | 4 + test/lib/globalsLinterCommandsOptionsTest.sh | 44 +++ test/lib/linterCommandsTest.sh | 3 +- test/lib/linterRulesTest.sh | 7 +- .../linters-config/fix-mode/.ansible-lint.yml | 9 + test/linters-config/fix-mode/.eslintrc.yml | 44 +++ test/linters-config/fix-mode/.golangci.yml | 5 + .../ansible/bad/playbooks/ansible_bad_1.yml | 17 +- .../ansible/good/playbooks/ansible_good_1.yml | 2 +- test/linters/go/golang_bad_01.go | 8 +- .../go_modules_bad/golang_bad_01.go | 17 +- .../linters/javascript_es/javascript_bad_1.js | 201 +----------- .../javascript_es/javascript_good_1.js | 139 +-------- .../javascript_prettier/javascript_bad_1.js | 17 +- .../javascript_standard/javascript_bad_1.js | 200 +----------- test/linters/json/.dotfile_json_bad_2.json | 6 +- test/linters/json/json_bad_1.json | 6 +- test/linters/jsonc/json_bad_1.jsonc | 6 +- test/linters/jsx/jsx_bad_1.jsx | 4 +- test/linters/jsx/jsx_good_1.jsx | 3 + test/linters/markdown/markdown_bad_1.md | 17 +- test/linters/protobuf/protobuf_bad_1.proto | 10 +- test/linters/python_ruff/python_bad_1.py | 7 +- test/linters/rust_clippy/bad/src/main.rs | 7 +- test/linters/sqlfluff/sqlfluff_bad_1.sql | 4 +- test/linters/tsx/tsx_bad_1.tsx | 2 +- test/linters/tsx/tsx_good_1.tsx | 5 +- .../linters/typescript_es/typescript_bad_1.ts | 14 +- .../typescript_prettier/typescript_bad_1.ts | 2 - .../typescript_standard/typescript_bad_1.ts | 13 +- test/run-super-linter-tests.sh | 293 ++++++++++++------ test/testUtils.sh | 81 +++++ 41 files changed, 595 insertions(+), 712 deletions(-) create mode 100644 .github/linters/.eslintrc.yml create mode 100644 .github/linters/.golangci.yml create mode 100755 test/lib/globalsLinterCommandsOptionsTest.sh create mode 100644 test/linters-config/fix-mode/.ansible-lint.yml create mode 100644 test/linters-config/fix-mode/.eslintrc.yml create mode 100644 test/linters-config/fix-mode/.golangci.yml diff --git a/.github/linters/.eslintrc.yml b/.github/linters/.eslintrc.yml new file mode 100644 index 00000000..31282eb8 --- /dev/null +++ b/.github/linters/.eslintrc.yml @@ -0,0 +1,44 @@ +--- +env: + browser: true + es6: true + jest: true + node: true + +extends: + - "eslint:recommended" + +ignorePatterns: + - "!.*" + - "**/node_modules/.*" + +parser: '@typescript-eslint/parser' + +plugins: + - '@typescript-eslint' + +# Don't set the jsonSyntax parser option for JSON, JSON5, and JSONC +# so we can use eslint-plugin-jsonc to automatically fix issues +# in tests, otherwise ESLint reports parsing errors and stops +overrides: + - files: + - "*.json" + extends: + - plugin:jsonc/recommended-with-json + parser: jsonc-eslint-parser + - files: + - "*.jsonc" + extends: + - plugin:jsonc/recommended-with-jsonc + parser: jsonc-eslint-parser + - files: + - "*.json5" + extends: + - plugin:jsonc/recommended-with-json5 + parser: jsonc-eslint-parser + - files: + - "*.jsx" + - "*.tsx" + extends: + - plugin:react/recommended +... diff --git a/.github/linters/.golangci.yml b/.github/linters/.golangci.yml new file mode 100644 index 00000000..3843b1cb --- /dev/null +++ b/.github/linters/.golangci.yml @@ -0,0 +1,7 @@ +--- +# This file is only used in tests +# TODO: move in a dedicated directory in test/linters-config +linters: + enable: + - gofmt +... diff --git a/.github/linters/.jscpd.json b/.github/linters/.jscpd.json index 3999d690..be12186d 100644 --- a/.github/linters/.jscpd.json +++ b/.github/linters/.jscpd.json @@ -38,6 +38,7 @@ "**/test/linters/typescript_es/**", "**/test/linters/typescript_prettier/**", "**/test/linters/typescript_standard/**", + "**/test/linters-config/**", "**/github_conf/**", "**/workflows/cd.yml", "**/workflows/ci.yml" diff --git a/Makefile b/Makefile index 87a265a2..d29a2a42 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 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-linters test-linters-fix-mode-expect-success ## Run the test suite +test: info validate-container-image-labels docker-build-check docker-dev-container-build-check 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-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 @@ -318,6 +318,14 @@ test-globals-languages: ## Test globals/languages.sh --entrypoint /tmp/lint/test/lib/globalsLanguagesTest.sh \ $(SUPER_LINTER_TEST_CONTAINER_URL) +.PHONY: test-globals-linter-command-options +test-globals-linter-command-options: ## Test globals/LinterCommandsOptions.sh + docker run \ + -v "$(CURDIR):/tmp/lint" \ + -w /tmp/lint \ + --entrypoint /tmp/lint/test/lib/globalsLinterCommandsOptionsTest.sh \ + $(SUPER_LINTER_TEST_CONTAINER_URL) + .PHONY: test-linter-rules test-linter-rules: ## Test linterRules.sh docker run \ @@ -416,14 +424,13 @@ test-non-default-home-directory: ## Test a non-default HOME directory "run_test_cases_non_default_home" \ "$(IMAGE)" -.PHONY: test-linters-fix-mode-expect-success -test-linters-fix-mode-expect-success: ## Run the linters test suite (fix mode) expecting successes +.PHONY: test-linters-fix-mode +test-linters-fix-mode: ## Run the linters test suite (fix mode) $(CURDIR)/test/run-super-linter-tests.sh \ $(SUPER_LINTER_TEST_CONTAINER_URL) \ "run_test_case_fix_mode" \ "$(IMAGE)" - .PHONY: test-linters test-linters: test-linters-expect-success test-linters-expect-failure ## Run the linters test suite diff --git a/README.md b/README.md index 0ac0ac9e..a37b8181 100644 --- a/README.md +++ b/README.md @@ -234,7 +234,7 @@ You can configure Super-linter using the following environment variables: | **FIX_RUST_2015** | `false` | Option to enable fix mode for `RUST_2015`. | | **FIX_RUST_2018** | `false` | Option to enable fix mode for `RUST_2018`. | | **FIX_RUST_2021** | `false` | Option to enable fix mode for `RUST_2021`. | -| **FIX_RUST_CLIPPY** | `false` | Option to enable fix mode for `RUST_CLIPPY`. | +| **FIX_RUST_CLIPPY** | `false` | Option to enable fix mode for `RUST_CLIPPY`. When `FIX_RUST_CLIPPY` is `true`, Clippy is allowed to fix issues in the workspace even if there are unstaged and staged changes in the workspace. | | **FIX_SCALAFMT** | `false` | Option to enable fix mode for `SCALAFMT`. | | **FIX_SHELL_SHFMT** | `false` | Option to enable fix mode for `SHELL_SHFMT`. | | **FIX_SNAKEMAKE_SNAKEFMT** | `false` | Option to enable fix mode for `SNAKEMAKE_SNAKEFMT`. | @@ -421,6 +421,20 @@ Super-linter supports the following locations to deliver fixes: - If you're running Super-linter locally, you can commit the changes as you would with any other change in your working directory. +### Fix mode for ansible-lint + +ansible-lint requires that the `yaml` rule is enabled to for the ansible-lint +fix mode to work. The default ansible-lint configuration that Super-linter ships +disables the `yaml` rule because it might not be compatible with yamllint. If +you need to enable the ansible-lint fix mode, provide an ansible-lint +configuration that doesn't ignore the `yaml` rule. + +### Fix mode file and directory ownership + +When fix mode is enabled, some linters and formatters don't maintain the +original file or directory ownership, and use the user that Super-linter uses +to run the linter or formatter. + ## Configure linters Super-linter provides default configurations for some linters in the [`TEMPLATES/`](TEMPLATES/) diff --git a/docs/add-new-linter.md b/docs/add-new-linter.md index bfb8a3dc..be2d8c2c 100644 --- a/docs/add-new-linter.md +++ b/docs/add-new-linter.md @@ -7,11 +7,16 @@ new tool, it should include: - `README.md` - Provide test cases: - 1. Create the `test/linters/` directory. + 1. Create the `test/linters/` directory. 2. Provide at least one test case with a file that is supposed to pass validation, - with the right file extension if needed: `test/linters//-good` + with the right file extension if needed: `test/linters//-good` 3. Provide at least one test case with a file that is supposed to fail validation, - with the right file extension if needed: `test/linters//-bad` + with the right file extension if needed: `test/linters//-bad`. + If the linter supports fix mode, the test case supposed to fail validation + should only contain violations that the fix mode can automatically fix. + Avoid test cases that fail only because of syntax errors, when possible. + 4. If the linter supports check-only mode or fix mode, add the `` + to the `LANGUAGES_WITH_FIX_MODE` array in `test/testUtils.sh` - Update the test suite to check for installed packages, the commands that your new tool needs in the `PATH`, and the expected version command: diff --git a/lib/functions/validation.sh b/lib/functions/validation.sh index 1b6932e2..79b9c152 100755 --- a/lib/functions/validation.sh +++ b/lib/functions/validation.sh @@ -7,6 +7,7 @@ function ValidateBooleanConfigurationVariables() { ValidateBooleanVariable "DISABLE_ERRORS" "${DISABLE_ERRORS}" ValidateBooleanVariable "ENABLE_GITHUB_ACTIONS_GROUP_TITLE" "${ENABLE_GITHUB_ACTIONS_GROUP_TITLE}" ValidateBooleanVariable "ENABLE_GITHUB_ACTIONS_STEP_SUMMARY" "${ENABLE_GITHUB_ACTIONS_STEP_SUMMARY}" + ValidateBooleanVariable "FIX_MODE_TEST_CASE_RUN" "${FIX_MODE_TEST_CASE_RUN}" ValidateBooleanVariable "IGNORE_GENERATED_FILES" "${IGNORE_GENERATED_FILES}" ValidateBooleanVariable "IGNORE_GITIGNORED_FILES" "${IGNORE_GITIGNORED_FILES}" ValidateBooleanVariable "LOG_DEBUG" "${LOG_DEBUG}" diff --git a/lib/functions/worker.sh b/lib/functions/worker.sh index f43443d4..e730f91a 100755 --- a/lib/functions/worker.sh +++ b/lib/functions/worker.sh @@ -15,7 +15,12 @@ function LintCodebase() { unset -n VALIDATE_LANGUAGE return 0 else - fatal "Don't disable any validation when running in test mode. VALIDATE_${FILE_TYPE} is set to: ${VALIDATE_LANGUAGE}. Set it to: true" + if [[ "${FIX_MODE_TEST_CASE_RUN}" == "true" ]]; then + debug "Don't fail the test even if VALIDATE_${FILE_TYPE} is set to ${VALIDATE_LANGUAGE} because ${FILE_TYPE} might not support fix mode" + return 0 + else + fatal "Don't disable any validation when running in test mode. VALIDATE_${FILE_TYPE} is set to: ${VALIDATE_LANGUAGE}. Set it to: true" + fi fi fi diff --git a/lib/globals/linterCommandsOptions.sh b/lib/globals/linterCommandsOptions.sh index 5572a5bc..d92204b3 100755 --- a/lib/globals/linterCommandsOptions.sh +++ b/lib/globals/linterCommandsOptions.sh @@ -35,10 +35,12 @@ STANDARD_FIX_MODE_OPTIONS=(--fix) # Define configuration options to enable "fix mode". # Not all linters and formatters support this. ANSIBLE_FIX_MODE_OPTIONS=(--fix) +CLANG_FORMAT_FIX_MODE_OPTIONS=(-i) CSS_FIX_MODE_OPTIONS=(--fix) -ENV_FIX_MODE_OPTIONS=(fix) +ENV_FIX_MODE_OPTIONS=(fix --no-backup) GO_FIX_MODE_OPTIONS=("${GOLANGCI_LINT_FIX_MODE_OPTIONS[@]}") GO_MODULES_FIX_MODE_OPTIONS=("${GOLANGCI_LINT_FIX_MODE_OPTIONS[@]}") +GOOGLE_JAVA_FORMAT_FIX_MODE_OPTIONS=(--replace) GROOVY_FIX_MODE_OPTIONS=(--fix) JAVASCRIPT_ES_FIX_MODE_OPTIONS=("${ESLINT_FIX_MODE_OPTIONS[@]}") JAVASCRIPT_PRETTIER_FIX_MODE_OPTIONS=("${PRETTIER_FIX_MODE_OPTIONS[@]}") @@ -47,11 +49,13 @@ JSON_FIX_MODE_OPTIONS=("${ESLINT_FIX_MODE_OPTIONS[@]}") JSONC_FIX_MODE_OPTIONS=("${ESLINT_FIX_MODE_OPTIONS[@]}") JSX_FIX_MODE_OPTIONS=("${ESLINT_FIX_MODE_OPTIONS[@]}") MARKDOWN_FIX_MODE_OPTIONS=(--fix) +NATURAL_LANGUAGE_FIX_MODE_OPTIONS=(--fix) POWERSHELL_FIX_MODE_OPTIONS=(-Fix) PROTOBUF_FIX_MODE_OPTIONS=(-fix) +PYTHON_ISORT_FIX_MODE_OPTIONS=(--overwrite-in-place) PYTHON_RUFF_FIX_MODE_OPTIONS=(--fix) RUBY_FIX_MODE_OPTIONS=(--autocorrect) -RUST_CLIPPY_FIX_MODE_OPTIONS=(--fix) +RUST_CLIPPY_FIX_MODE_OPTIONS=(--fix --allow-dirty --allow-staged) SHELL_SHFMT_FIX_MODE_OPTIONS=(--write) SQLFLUFF_FIX_MODE_OPTIONS=(fix) TSX_FIX_MODE_OPTIONS=("${ESLINT_FIX_MODE_OPTIONS[@]}") diff --git a/lib/linter.sh b/lib/linter.sh index 899a63c3..a62ade59 100755 --- a/lib/linter.sh +++ b/lib/linter.sh @@ -113,6 +113,10 @@ declare -l TEST_CASE_RUN TEST_CASE_RUN="${TEST_CASE_RUN:-"false"}" export TEST_CASE_RUN +declare -l FIX_MODE_TEST_CASE_RUN +FIX_MODE_TEST_CASE_RUN="${FIX_MODE_TEST_CASE_RUN:-"false"}" +export FIX_MODE_TEST_CASE_RUN + # We want a lowercase value declare -l USE_FIND_ALGORITHM USE_FIND_ALGORITHM="${USE_FIND_ALGORITHM:-false}" diff --git a/test/lib/globalsLinterCommandsOptionsTest.sh b/test/lib/globalsLinterCommandsOptionsTest.sh new file mode 100755 index 00000000..ed0decb6 --- /dev/null +++ b/test/lib/globalsLinterCommandsOptionsTest.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +set -o errexit +set -o nounset +set -o pipefail + +# Default log level +# shellcheck disable=SC2034 +LOG_LEVEL="DEBUG" + +# shellcheck source=/dev/null +source "lib/functions/log.sh" + +# shellcheck source=/dev/null +source "test/testUtils.sh" + +# The sqlfluff command needs this, but we don't want to make this test +# dependant on other files +# shellcheck disable=SC2034 +SQLFLUFF_LINTER_RULES="SQLFLUFF_LINTER_RULES" + +# shellcheck source=/dev/null +source "lib/globals/linterCommandsOptions.sh" + +LanguagesWithFixModeTest() { + local FUNCTION_NAME + FUNCTION_NAME="${FUNCNAME[0]}" + info "${FUNCTION_NAME} start" + + for LANGUAGE in "${LANGUAGES_WITH_FIX_MODE[@]}"; do + local FIX_MODE_OPTIONS_VARIABLE_NAME="${LANGUAGE}_FIX_MODE_OPTIONS" + local CHECK_ONLY_MODE_OPTIONS_VARIABLE_NAME="${LANGUAGE}_CHECK_ONLY_MODE_OPTIONS" + if [[ -v "${FIX_MODE_OPTIONS_VARIABLE_NAME}" ]] || + [[ -v "${CHECK_ONLY_MODE_OPTIONS_VARIABLE_NAME}" ]]; then + debug "${LANGUAGE} has check-only mode or fix mode options as expected" + else + fatal "${LANGUAGE} is in the list of languages that support fix mode, but neither check-only mode, nor fix mode options were found" + fi + done + + notice "${FUNCTION_NAME} PASS" +} + +LanguagesWithFixModeTest diff --git a/test/lib/linterCommandsTest.sh b/test/lib/linterCommandsTest.sh index 24b450b0..22807af6 100755 --- a/test/lib/linterCommandsTest.sh +++ b/test/lib/linterCommandsTest.sh @@ -32,13 +32,12 @@ BASH_EXEC_IGNORE_LIBRARIES="false" GITHUB_WORKSPACE="$(pwd)" # shellcheck disable=SC2034 IGNORE_GITIGNORED_FILES="false" -LINTER_RULES_PATH="TEMPLATES" # shellcheck disable=SC2034 TYPESCRIPT_STANDARD_TSCONFIG_FILE=".github/linters/tsconfig.json" # shellcheck disable=SC2034 YAML_ERROR_ON_WARNING="false" for LANGUAGE in "${LANGUAGE_ARRAY_FOR_LINTER_RULES[@]}"; do - GetLinterRules "${LANGUAGE}" "${LINTER_RULES_PATH}" + GetLinterRules "${LANGUAGE}" "TEMPLATES" done ValidateValidationVariables diff --git a/test/lib/linterRulesTest.sh b/test/lib/linterRulesTest.sh index 75978311..0732138e 100755 --- a/test/lib/linterRulesTest.sh +++ b/test/lib/linterRulesTest.sh @@ -43,7 +43,12 @@ function GetLinterRulesTest() { GetLinterRules "${LANGUAGE}" "${DEFAULT_RULES_LOCATION}" done - local EXPECTED_TEST_LANGUAGE_LINTER_RULES="${DEFAULT_RULES_LOCATION}/${TEST_LANGUAGE_FILE_NAME}" + local EXPECTED_TEST_LANGUAGE_LINTER_RULES="${GITHUB_WORKSPACE}" + if [[ -n "${LINTER_RULES_PATH:-}" ]]; then + EXPECTED_TEST_LANGUAGE_LINTER_RULES="${EXPECTED_TEST_LANGUAGE_LINTER_RULES}/${LINTER_RULES_PATH}" + fi + EXPECTED_TEST_LANGUAGE_LINTER_RULES="${EXPECTED_TEST_LANGUAGE_LINTER_RULES}/${TEST_LANGUAGE_FILE_NAME}" + if [[ "${TEST_LANGUAGE_LINTER_RULES}" == "${EXPECTED_TEST_LANGUAGE_LINTER_RULES}" ]]; then debug "TEST_LANGUAGE_LINTER_RULES (${TEST_LANGUAGE_LINTER_RULES}) matches the expected value (${EXPECTED_TEST_LANGUAGE_LINTER_RULES})" else diff --git a/test/linters-config/fix-mode/.ansible-lint.yml b/test/linters-config/fix-mode/.ansible-lint.yml new file mode 100644 index 00000000..bcbfc8c4 --- /dev/null +++ b/test/linters-config/fix-mode/.ansible-lint.yml @@ -0,0 +1,9 @@ +--- +# Customize the ansible-lint configuration file because fix mode needs the +# yaml rule not to be disabled, but we disable the yaml rule in the default +# ansible-lint configuration +parseable: true +quiet: true +use_default_rules: true +verbosity: 1 +... diff --git a/test/linters-config/fix-mode/.eslintrc.yml b/test/linters-config/fix-mode/.eslintrc.yml new file mode 100644 index 00000000..31282eb8 --- /dev/null +++ b/test/linters-config/fix-mode/.eslintrc.yml @@ -0,0 +1,44 @@ +--- +env: + browser: true + es6: true + jest: true + node: true + +extends: + - "eslint:recommended" + +ignorePatterns: + - "!.*" + - "**/node_modules/.*" + +parser: '@typescript-eslint/parser' + +plugins: + - '@typescript-eslint' + +# Don't set the jsonSyntax parser option for JSON, JSON5, and JSONC +# so we can use eslint-plugin-jsonc to automatically fix issues +# in tests, otherwise ESLint reports parsing errors and stops +overrides: + - files: + - "*.json" + extends: + - plugin:jsonc/recommended-with-json + parser: jsonc-eslint-parser + - files: + - "*.jsonc" + extends: + - plugin:jsonc/recommended-with-jsonc + parser: jsonc-eslint-parser + - files: + - "*.json5" + extends: + - plugin:jsonc/recommended-with-json5 + parser: jsonc-eslint-parser + - files: + - "*.jsx" + - "*.tsx" + extends: + - plugin:react/recommended +... diff --git a/test/linters-config/fix-mode/.golangci.yml b/test/linters-config/fix-mode/.golangci.yml new file mode 100644 index 00000000..e6dd6cad --- /dev/null +++ b/test/linters-config/fix-mode/.golangci.yml @@ -0,0 +1,5 @@ +--- +linters: + enable: + - gofmt +... diff --git a/test/linters/ansible/bad/playbooks/ansible_bad_1.yml b/test/linters/ansible/bad/playbooks/ansible_bad_1.yml index f4570c18..ae010a2a 100644 --- a/test/linters/ansible/bad/playbooks/ansible_bad_1.yml +++ b/test/linters/ansible/bad/playbooks/ansible_bad_1.yml @@ -1,8 +1,11 @@ --- -- name: Remove temp files - become: true - file: - path: "{{ item }}" - state: absent - with_items: - - "/tmp/test-1" +- name: Test playbook + hosts: all + tasks: + - name: Remove temp files + become: true + file: + path: "{{ item }}" + state: absent + with_items: + - "/tmp/test-1" diff --git a/test/linters/ansible/good/playbooks/ansible_good_1.yml b/test/linters/ansible/good/playbooks/ansible_good_1.yml index d9c8a5c2..7d7da3cd 100644 --- a/test/linters/ansible/good/playbooks/ansible_good_1.yml +++ b/test/linters/ansible/good/playbooks/ansible_good_1.yml @@ -8,4 +8,4 @@ path: "{{ item }}" state: absent with_items: - - "/tmp/test-1" + - /tmp/test-1 diff --git a/test/linters/go/golang_bad_01.go b/test/linters/go/golang_bad_01.go index 370c8c5f..e69badb3 100644 --- a/test/linters/go/golang_bad_01.go +++ b/test/linters/go/golang_bad_01.go @@ -1,3 +1,7 @@ -if len(in) == 0 { - return "", fmt.Errorf("Input is empty") +package main + +import "fmt" + +func main() { +fmt.Println("hello world") } diff --git a/test/linters/go_modules/go_modules_bad/golang_bad_01.go b/test/linters/go_modules/go_modules_bad/golang_bad_01.go index e2487d09..e69badb3 100644 --- a/test/linters/go_modules/go_modules_bad/golang_bad_01.go +++ b/test/linters/go_modules/go_modules_bad/golang_bad_01.go @@ -1,18 +1,7 @@ package main -import ( - "github.com/go-playground/validator/v10" - "github.com/labstack/echo/v4" -) +import "fmt" -if len(in) == 0 { - return "", fmt.Errorf("Input is empty") +func main() { +fmt.Println("hello world") } - -x := 0 -{ - var x int - x++ -} - -fmt.Println(x) diff --git a/test/linters/javascript_es/javascript_bad_1.js b/test/linters/javascript_es/javascript_bad_1.js index 3379e608..66e8f898 100644 --- a/test/linters/javascript_es/javascript_bad_1.js +++ b/test/linters/javascript_es/javascript_bad_1.js @@ -1,199 +1,10 @@ -var http = require('http') -var createHandler = require('github-webhook-handler') +var teamId = "teamId" +var booleanTest = false; -var handler = createHandler({ - path: /webhook, secret : (process.env.SECRET) }) - -var userArray = ['user1'] -here is some garbage = that - -var teamDescription = Team of Robots -var teamPrivacy = 'closed' // closed (visible) / secret (hidden) are options here - -var teamName = process.env.GHES_TEAM_NAME -var teamAccess = 'pull' // pull,push,admin options here -var teamId = '' - -var orgRepos = [] - -// var creator = "" - -var foo = someFunction(); - var bar = a + 1; - - http.createServer(function (req, res) { - handler(req, res, function (err) { - console.log(err) - res.statusCode = 404 - res.end('no such location') - }) - }).listen(3000) - -handler.on('error', function (err) { - console.await.error('Error:', err.message) - }) - -handler.on('repository', function (event) { - if (event.payload.action === 'created') { - const repo = event.payload.repository.full_name - console.log(repo) - const org = event.payload.repository.owner.login - getTeamID(org) - setTimeout(checkTeamIDVariable, 1000) - } - }) - -handler.on('team', function (event) { - // TODO user events such as being removed from team or org - if (event.payload.action === 'deleted') { - // const name = event.payload.team.name - const org = event.payload.organization.login - getRepositories(org) - setTimeout(checkReposVariable, 5000) - } else if (event.payload.action === 'removed_from_repository') { - const org = event.payload.organization.login - getTeamID(org) - // const repo = event.payload.repository.full_name - setTimeout(checkTeamIDVariable, 1000) - } - }) - -function getTeamID(org) { - const https = require('https') - - const options = { - hostname: (process.env.GHE_HOST), - port: 443 - path: '/api/v3/orgs/' + org + '/teams', - method: 'GET', - headers: { - Authorization: 'token ' + (process.env.GHE_TOKEN), - 'Content-Type': 'application/json' - } - } - - req.on('error, (error) => { - console.error(error) - }) - -req.end() -} - -function checkTeamIDVariable(repo) { - if (typeof teamId != 'undefined') { - addTeamToRepo(repo, teamId) +function checkTeamIDVariable(teamId, booleanTest) { + if (typeof teamId != "undefined" || Boolean(!!booleanTest)) { + console.log(teamId) } } -function checkReposVariable(org) { - if (typeof orgRepos !== 'undefined') { - // for(var repo of orgRepos) { - // addTeamToRepo(repo, teamId) - // } - reCreateTeam(org) - } -} - -function addTeamToRepo(repo, teamId) { - const https = require('https') - const data = JSON.stringify({ - permission: teamAccess - }) - - const options = { - hostname: (process.env.GHE_HOST), - port: 443, - path: '/api/v3/teams/' + teamId + '/repos/' + repo, - method: 'PUT', - headers: { - Authorization: 'token ' + (process.env.GHE_TOKEN), - 'Content-Type': 'application/json', - 'Content-Length': data.length - } - } - let body = [] - - const req = https.request(options, (res) => { - res.on('data', (chunk) => { - - body.push(chunk) - - }).on('end', () => { - - body = Buffer.concat(body).toString() - console.log(res.statusCode) - console.log('added team to ' + repo) - }) - }) - - req.on('error', (error) => { - console.error(error) - }) - - req.write(data) - req.end() -} - -function reCreateTeam(org) { - const https = require('https') - const data = JSON.stringify({ - name: teamName, - description: teamDescription, - privacy: teamPrivacy - maintainers: userArray, - repo_names: orgRepos - }) - - const options = { - hostname: (process.env.GHE_HOST), - port: 443 - path: '/api/v3/orgs/' + org + '/teams', - method: 'POST', - headers: { - Authorization: 'token ' + (process.env.GHE_TOKEN), - 'Content-Type': 'application/json', - 'Content-Length': data.length - } - } - // const body = [] - const req = https.request(options, (res) => { - if (res.statusCode !== 201) { - console.log('Status code: ' + res.statusCode) - console.log('Added ' + teamName + ' to ' + org + ' Failed') - res.on('data', function (chunk) { - console.log('BODY: ' + chunk) - }) - } else { - console.log('Added ' + teamName ' to ' + org) - } - }) - - req.on('error', (error) => { - console.error(error) - }) - - req.write(data) - req.end() -} - -function getRepositories(org) { - orgRepos = [] - - const https = require('https') - - const options = { - hostname: (process.env.GHE_HOST), - port: '443', - path: '/api/v3/orgs/' + org + "/repos", - method: 'GET', - headers: { - Authorization: 'token ' + (process.env.GHE_TOKEN), - 'Content-Type': 'application/json' - } - } - - req.on('error', (error) => { - console.error(error) - }) - req.end() -} +checkTeamIDVariable(teamId, booleanTest) diff --git a/test/linters/javascript_es/javascript_good_1.js b/test/linters/javascript_es/javascript_good_1.js index 58dc8bfb..97198b86 100644 --- a/test/linters/javascript_es/javascript_good_1.js +++ b/test/linters/javascript_es/javascript_good_1.js @@ -1,137 +1,10 @@ -const http = require('http') -const createHandler = require('github-webhook-handler') -const handler = createHandler({ path: '/webhook', secret: (process.env.SECRET) }) +var teamId = "teamId" +var booleanTest = false; -const userArray = ['user1'] - -const teamDescription = 'Team of Robots' -const teamPrivacy = 'closed' // closed (visible) / secret (hidden) are options here - -const teamName = process.env.GHES_TEAM_NAME -const teamAccess = 'pull' // pull,push,admin options here -const teamId = '' - -// var creator = "" - -http.createServer(function (req, res) { - handler(req, res, function (err) { - console.log(err) - res.statusCode = 404 - res.end('no such location') - }) -}).listen(3000) - -handler.on('error', function (err) { - console.error('Error:', err.message) -}) - -handler.on('repository', function (event) { - if (event.payload.action === 'created') { - const repo = event.payload.repository.full_name - console.log(repo) - setTimeout(checkTeamIDVariable, 1000) - } -}) - -handler.on('team', function (event) { - // TODO user events such as being removed from team or org - if (event.payload.action === 'deleted') { - // const name = event.payload.team.name - setTimeout(checkReposVariable, 5000) - } else if (event.payload.action === 'removed_from_repository') { - // const repo = event.payload.repository.full_name - setTimeout(checkTeamIDVariable, 1000) - } -}) - -function checkTeamIDVariable (repo) { - if (typeof teamId !== 'undefined') { - addTeamToRepo(repo, teamId) +function checkTeamIDVariable(teamId, booleanTest) { + if (typeof teamId != "undefined" || booleanTest) { + console.log(teamId) } } -function checkReposVariable (org) { - if (typeof orgRepos !== 'undefined') { - // for(var repo of orgRepos) { - // addTeamToRepo(repo, teamId) - // } - reCreateTeam(org) - } -} - -function addTeamToRepo (repo, teamId) { - const https = require('https') - const data = JSON.stringify({ - permission: teamAccess - }) - - const options = { - hostname: (process.env.GHE_HOST), - port: 443, - path: '/api/v3/teams/' + teamId + '/repos/' + repo, - method: 'PUT', - headers: { - Authorization: 'token ' + (process.env.GHE_TOKEN), - 'Content-Type': 'application/json', - 'Content-Length': data.length - } - } - let body = [] - const req = https.request(options, (res) => { - res.on('data', (chunk) => { - body.push(chunk) - }).on('end', () => { - body = Buffer.concat(body).toString() - console.log(res.statusCode) - console.log('added team to ' + repo) - }) - }) - - req.on('error', (error) => { - console.error(error) - }) - - req.write(data) - req.end() -} - -function reCreateTeam (org) { - const https = require('https') - const data = JSON.stringify({ - name: teamName, - description: teamDescription, - privacy: teamPrivacy, - maintainers: userArray - }) - - const options = { - hostname: (process.env.GHE_HOST), - port: 443, - path: '/api/v3/orgs/' + org + '/teams', - method: 'POST', - headers: { - Authorization: 'token ' + (process.env.GHE_TOKEN), - 'Content-Type': 'application/json', - 'Content-Length': data.length - } - } - // const body = [] - const req = https.request(options, (res) => { - if (res.statusCode !== 201) { - console.log('Status code: ' + res.statusCode) - console.log('Added ' + teamName + ' to ' + org + ' Failed') - res.on('data', function (chunk) { - console.log('BODY: ' + chunk) - }) - } else { - console.log('Added ' + teamName + ' to ' + org) - } - }) - - req.on('error', (error) => { - console.error(error) - }) - - req.write(data) - req.end() -} +checkTeamIDVariable(teamId, booleanTest) diff --git a/test/linters/javascript_prettier/javascript_bad_1.js b/test/linters/javascript_prettier/javascript_bad_1.js index 98e5ee29..13345350 100644 --- a/test/linters/javascript_prettier/javascript_bad_1.js +++ b/test/linters/javascript_prettier/javascript_bad_1.js @@ -1,12 +1,8 @@ var http = require('http') var createHandler = require( 'github-webhook-handler') -var handler = createHandler( { path : /webhook, secret : (process.env.SECRET) }) +var userArray = ['user1'] -var userArray = [ 'user1' ] -here is some garbage = that - -var teamDescription = Team of Robots var teamPrivacy = 'closed' // closed (visible) / secret (hidden) are options here var teamName = process.env.GHES_TEAM_NAME @@ -62,8 +58,7 @@ function getTeamID (org) { const options = { hostname: (process.env.GHE_HOST), - port: 443 - path: '/api/v3/orgs/' + org + '/teams', + port: 443, method: 'GET', headers: { Authorization: 'token ' + (process.env.GHE_TOKEN), @@ -84,7 +79,7 @@ function getTeamID (org) { }) }) - req.on('error, (error) => { + req.on('error', (error) => { console.error(error) }) @@ -151,14 +146,14 @@ function reCreateTeam (org) { const data = JSON.stringify({ name: teamName, description: teamDescription, - privacy: teamPrivacy + privacy: teamPrivacy, maintainers: userArray, repo_names: orgRepos }) const options = { hostname: (process.env.GHE_HOST), - port: 443 + port: 443, path: '/api/v3/orgs/' + org + '/teams', method: 'POST', headers: { @@ -176,7 +171,7 @@ function reCreateTeam (org) { console.log('BODY: ' + chunk) }) } else { - console.log('Added ' + teamName ' to ' + org) + console.log('Added ' + teamName + ' to ' + org) } }) diff --git a/test/linters/javascript_standard/javascript_bad_1.js b/test/linters/javascript_standard/javascript_bad_1.js index 3379e608..89624628 100644 --- a/test/linters/javascript_standard/javascript_bad_1.js +++ b/test/linters/javascript_standard/javascript_bad_1.js @@ -1,199 +1,9 @@ -var http = require('http') -var createHandler = require('github-webhook-handler') +var teamId = "teamId" -var handler = createHandler({ - path: /webhook, secret : (process.env.SECRET) }) - -var userArray = ['user1'] -here is some garbage = that - -var teamDescription = Team of Robots -var teamPrivacy = 'closed' // closed (visible) / secret (hidden) are options here - -var teamName = process.env.GHES_TEAM_NAME -var teamAccess = 'pull' // pull,push,admin options here -var teamId = '' - -var orgRepos = [] - -// var creator = "" - -var foo = someFunction(); - var bar = a + 1; - - http.createServer(function (req, res) { - handler(req, res, function (err) { - console.log(err) - res.statusCode = 404 - res.end('no such location') - }) - }).listen(3000) - -handler.on('error', function (err) { - console.await.error('Error:', err.message) - }) - -handler.on('repository', function (event) { - if (event.payload.action === 'created') { - const repo = event.payload.repository.full_name - console.log(repo) - const org = event.payload.repository.owner.login - getTeamID(org) - setTimeout(checkTeamIDVariable, 1000) - } - }) - -handler.on('team', function (event) { - // TODO user events such as being removed from team or org - if (event.payload.action === 'deleted') { - // const name = event.payload.team.name - const org = event.payload.organization.login - getRepositories(org) - setTimeout(checkReposVariable, 5000) - } else if (event.payload.action === 'removed_from_repository') { - const org = event.payload.organization.login - getTeamID(org) - // const repo = event.payload.repository.full_name - setTimeout(checkTeamIDVariable, 1000) - } - }) - -function getTeamID(org) { - const https = require('https') - - const options = { - hostname: (process.env.GHE_HOST), - port: 443 - path: '/api/v3/orgs/' + org + '/teams', - method: 'GET', - headers: { - Authorization: 'token ' + (process.env.GHE_TOKEN), - 'Content-Type': 'application/json' - } - } - - req.on('error, (error) => { - console.error(error) - }) - -req.end() -} - -function checkTeamIDVariable(repo) { - if (typeof teamId != 'undefined') { - addTeamToRepo(repo, teamId) +function checkTeamIDVariable(teamId) { + if (typeof teamId != "undefined") { + console.log(teamId) } } -function checkReposVariable(org) { - if (typeof orgRepos !== 'undefined') { - // for(var repo of orgRepos) { - // addTeamToRepo(repo, teamId) - // } - reCreateTeam(org) - } -} - -function addTeamToRepo(repo, teamId) { - const https = require('https') - const data = JSON.stringify({ - permission: teamAccess - }) - - const options = { - hostname: (process.env.GHE_HOST), - port: 443, - path: '/api/v3/teams/' + teamId + '/repos/' + repo, - method: 'PUT', - headers: { - Authorization: 'token ' + (process.env.GHE_TOKEN), - 'Content-Type': 'application/json', - 'Content-Length': data.length - } - } - let body = [] - - const req = https.request(options, (res) => { - res.on('data', (chunk) => { - - body.push(chunk) - - }).on('end', () => { - - body = Buffer.concat(body).toString() - console.log(res.statusCode) - console.log('added team to ' + repo) - }) - }) - - req.on('error', (error) => { - console.error(error) - }) - - req.write(data) - req.end() -} - -function reCreateTeam(org) { - const https = require('https') - const data = JSON.stringify({ - name: teamName, - description: teamDescription, - privacy: teamPrivacy - maintainers: userArray, - repo_names: orgRepos - }) - - const options = { - hostname: (process.env.GHE_HOST), - port: 443 - path: '/api/v3/orgs/' + org + '/teams', - method: 'POST', - headers: { - Authorization: 'token ' + (process.env.GHE_TOKEN), - 'Content-Type': 'application/json', - 'Content-Length': data.length - } - } - // const body = [] - const req = https.request(options, (res) => { - if (res.statusCode !== 201) { - console.log('Status code: ' + res.statusCode) - console.log('Added ' + teamName + ' to ' + org + ' Failed') - res.on('data', function (chunk) { - console.log('BODY: ' + chunk) - }) - } else { - console.log('Added ' + teamName ' to ' + org) - } - }) - - req.on('error', (error) => { - console.error(error) - }) - - req.write(data) - req.end() -} - -function getRepositories(org) { - orgRepos = [] - - const https = require('https') - - const options = { - hostname: (process.env.GHE_HOST), - port: '443', - path: '/api/v3/orgs/' + org + "/repos", - method: 'GET', - headers: { - Authorization: 'token ' + (process.env.GHE_TOKEN), - 'Content-Type': 'application/json' - } - } - - req.on('error', (error) => { - console.error(error) - }) - req.end() -} +checkTeamIDVariable(teamId) diff --git a/test/linters/json/.dotfile_json_bad_2.json b/test/linters/json/.dotfile_json_bad_2.json index 096c082a..88dbd29a 100644 --- a/test/linters/json/.dotfile_json_bad_2.json +++ b/test/linters/json/.dotfile_json_bad_2.json @@ -1,12 +1,14 @@ { "arrow_spacing": { - "level": ["ignore"] + "level": [ + "ignore" + ] }, "foo": "bar", "foo": "baz", "braces_spacing": { "level": 'ignore', - "spaces": 0 + "spaces": 0, "empty_object_spaces": 0 } } diff --git a/test/linters/json/json_bad_1.json b/test/linters/json/json_bad_1.json index 096c082a..88dbd29a 100644 --- a/test/linters/json/json_bad_1.json +++ b/test/linters/json/json_bad_1.json @@ -1,12 +1,14 @@ { "arrow_spacing": { - "level": ["ignore"] + "level": [ + "ignore" + ] }, "foo": "bar", "foo": "baz", "braces_spacing": { "level": 'ignore', - "spaces": 0 + "spaces": 0, "empty_object_spaces": 0 } } diff --git a/test/linters/jsonc/json_bad_1.jsonc b/test/linters/jsonc/json_bad_1.jsonc index f90d345e..6029d92e 100644 --- a/test/linters/jsonc/json_bad_1.jsonc +++ b/test/linters/jsonc/json_bad_1.jsonc @@ -1,11 +1,13 @@ { "arrow_spacing": { - "level": ["ignore"] + "level": [ + "ignore" + ] }, // more test "braces_spacing": { "level": 'ignore', - "spaces": 0 + "spaces": 0, "empty_object_spaces": 0 } } diff --git a/test/linters/jsx/jsx_bad_1.jsx b/test/linters/jsx/jsx_bad_1.jsx index cb96f0fe..618c7ed3 100644 --- a/test/linters/jsx/jsx_bad_1.jsx +++ b/test/linters/jsx/jsx_bad_1.jsx @@ -1 +1,3 @@ -const element =

Hello, world! +import React from 'react'; + +var Hello = diff --git a/test/linters/jsx/jsx_good_1.jsx b/test/linters/jsx/jsx_good_1.jsx index f19f0a8f..6c773f98 100644 --- a/test/linters/jsx/jsx_good_1.jsx +++ b/test/linters/jsx/jsx_good_1.jsx @@ -1 +1,4 @@ +import React from 'react'; + const element =

Hello, world!

; +console.log(element) diff --git a/test/linters/markdown/markdown_bad_1.md b/test/linters/markdown/markdown_bad_1.md index 6599ac74..b9e5395c 100644 --- a/test/linters/markdown/markdown_bad_1.md +++ b/test/linters/markdown/markdown_bad_1.md @@ -1,20 +1,15 @@ -## Bad Markdown +# Bad Markdown This is just standard good markdown. -###### Second level header - -This header does **NOT** follow the step down from `level 1`. +## Second level header - Here it *is* - Some more indention - why so much? -``` -ls -la -``` - -# Walk away - We're all done **here**. -- [Link Action]https://github.com + +- [Link Action] + +[ Link Action ](https://github.com) diff --git a/test/linters/protobuf/protobuf_bad_1.proto b/test/linters/protobuf/protobuf_bad_1.proto index b42980ba..9dd4def3 100644 --- a/test/linters/protobuf/protobuf_bad_1.proto +++ b/test/linters/protobuf/protobuf_bad_1.proto @@ -1,6 +1,5 @@ syntax = "proto3"; -// A broken example of the official reference -// See https://developers.google.com/protocol-buffers/docs/reference/proto3-spec#proto_file + package examplePb; option java_package = "com.example.foo"; @@ -34,14 +33,7 @@ message outer { message AccountForAdmin {} message SpecialEndOfSupport {} required inner inner_message = 7; - group Result = 8 { - string url = 9; - } - repeated group Result = 10 { - } repeated inner paper = 11; - repeated group Regular = 12 { - } } service SearchApi { rpc search (SearchRequest) returns (SearchResponse) {}; diff --git a/test/linters/python_ruff/python_bad_1.py b/test/linters/python_ruff/python_bad_1.py index 93bc7e92..8ab9699e 100644 --- a/test/linters/python_ruff/python_bad_1.py +++ b/test/linters/python_ruff/python_bad_1.py @@ -1,4 +1,5 @@ -a=1;b=2 -c=a+b -BROKEN_VAR=BROKEN_VAR +import pandas +import numpy as np + +c = 1 + 2 print(c) diff --git a/test/linters/rust_clippy/bad/src/main.rs b/test/linters/rust_clippy/bad/src/main.rs index ccc88353..7c138b9b 100644 --- a/test/linters/rust_clippy/bad/src/main.rs +++ b/test/linters/rust_clippy/bad/src/main.rs @@ -1,4 +1,7 @@ +use std::fs::OpenOptions; +use std::os::unix::fs::OpenOptionsExt; + fn main() { - let x = 3.14; - let _y = 1_f64 / x; + let mut options = OpenOptions::new(); + options.mode(644); } diff --git a/test/linters/sqlfluff/sqlfluff_bad_1.sql b/test/linters/sqlfluff/sqlfluff_bad_1.sql index 82e1f3eb..6a80ab34 100644 --- a/test/linters/sqlfluff/sqlfluff_bad_1.sql +++ b/test/linters/sqlfluff/sqlfluff_bad_1.sql @@ -1 +1,3 @@ -DELETE from person; +SELECT + a +FROM foo AS zoo; diff --git a/test/linters/tsx/tsx_bad_1.tsx b/test/linters/tsx/tsx_bad_1.tsx index a6f6738f..ee723bb8 100644 --- a/test/linters/tsx/tsx_bad_1.tsx +++ b/test/linters/tsx/tsx_bad_1.tsx @@ -1 +1 @@ -var foo = bar as +var Hello = diff --git a/test/linters/tsx/tsx_good_1.tsx b/test/linters/tsx/tsx_good_1.tsx index ac5b8f4f..6c773f98 100644 --- a/test/linters/tsx/tsx_good_1.tsx +++ b/test/linters/tsx/tsx_good_1.tsx @@ -1 +1,4 @@ -var foo = bar as foo; +import React from 'react'; + +const element =

Hello, world!

; +console.log(element) diff --git a/test/linters/typescript_es/typescript_bad_1.ts b/test/linters/typescript_es/typescript_bad_1.ts index 1b484c9f..66e8f898 100644 --- a/test/linters/typescript_es/typescript_bad_1.ts +++ b/test/linters/typescript_es/typescript_bad_1.ts @@ -1,8 +1,10 @@ -const spiderman = (person: String) => { - return 'Hello, ' + person; +var teamId = "teamId" +var booleanTest = false; + +function checkTeamIDVariable(teamId, booleanTest) { + if (typeof teamId != "undefined" || Boolean(!!booleanTest)) { + console.log(teamId) + } } -var handler = createHandler( { path : /webhook, secret : (process.env.SECRET) }) - -let user = 1; -console.log(spiderman(user)); +checkTeamIDVariable(teamId, booleanTest) diff --git a/test/linters/typescript_prettier/typescript_bad_1.ts b/test/linters/typescript_prettier/typescript_bad_1.ts index c9c15a5c..39327f1e 100644 --- a/test/linters/typescript_prettier/typescript_bad_1.ts +++ b/test/linters/typescript_prettier/typescript_bad_1.ts @@ -6,7 +6,5 @@ const spiderman = (person: String) => { return 'Hello, ' + person; } -var handler = createHandler( { path : /webhook, secret : (process.env.SECRET) }) - let user = 1; console.log(spiderman(user)); diff --git a/test/linters/typescript_standard/typescript_bad_1.ts b/test/linters/typescript_standard/typescript_bad_1.ts index c9c15a5c..f69cfcd4 100644 --- a/test/linters/typescript_standard/typescript_bad_1.ts +++ b/test/linters/typescript_standard/typescript_bad_1.ts @@ -1,12 +1,11 @@ enum Test { - Hoo = 'hoo' + Hoo = "hoo" } -const spiderman = (person: String) => { - return 'Hello, ' + person; +const spiderman = (person: string): string => { + return `Hello, ${person}` } -var handler = createHandler( { path : /webhook, secret : (process.env.SECRET) }) - -let user = 1; -console.log(spiderman(user)); +const user = "Peter Parker" +console.log(spiderman(user)) +console.log(Test.Hoo) diff --git a/test/run-super-linter-tests.sh b/test/run-super-linter-tests.sh index b01bc0fe..1f9a9da1 100755 --- a/test/run-super-linter-tests.sh +++ b/test/run-super-linter-tests.sh @@ -10,7 +10,7 @@ source "test/testUtils.sh" SUPER_LINTER_TEST_CONTAINER_URL="${1}" TEST_FUNCTION_NAME="${2}" SUPER_LINTER_CONTAINER_IMAGE_TYPE="${3}" -echo "Super-linter container image type: ${SUPER_LINTER_CONTAINER_IMAGE_TYPE}" +debug "Super-linter container image type: ${SUPER_LINTER_CONTAINER_IMAGE_TYPE}" DEFAULT_BRANCH="main" @@ -22,8 +22,13 @@ ignore_test_cases() { COMMAND_TO_RUN+=(-e FILTER_REGEX_EXCLUDE=".*(/test/linters/|CHANGELOG.md).*") } +configure_typescript_for_test_cases() { + COMMAND_TO_RUN+=(--env TYPESCRIPT_STANDARD_TSCONFIG_FILE=".github/linters/tsconfig.json") +} + configure_linters_for_test_cases() { - COMMAND_TO_RUN+=(-e TEST_CASE_RUN=true -e JSCPD_CONFIG_FILE=".jscpd-test-linters.json" -e RENOVATE_SHAREABLE_CONFIG_PRESET_FILE_NAMES="default.json,hoge.json" -e TYPESCRIPT_STANDARD_TSCONFIG_FILE=".github/linters/tsconfig.json") + COMMAND_TO_RUN+=(-e TEST_CASE_RUN=true -e JSCPD_CONFIG_FILE=".jscpd-test-linters.json" -e RENOVATE_SHAREABLE_CONFIG_PRESET_FILE_NAMES="default.json,hoge.json") + configure_typescript_for_test_cases } run_test_cases_expect_failure() { @@ -68,7 +73,9 @@ run_test_case_bash_exec_library_expect_success() { initialize_git_repository_and_test_args() { local GIT_REPOSITORY_PATH="${1}" # shellcheck disable=SC2064 # Once the path is set, we don't expect it to change - trap "rm -fr '${GIT_REPOSITORY_PATH}'" EXIT + trap "sudo rm -fr '${GIT_REPOSITORY_PATH}'" EXIT + + debug "GIT_REPOSITORY_PATH: ${GIT_REPOSITORY_PATH}" local GITHUB_EVENT_FILE_PATH="${2}" @@ -87,7 +94,13 @@ initialize_git_repository_and_test_args() { COMMAND_TO_RUN+=(-e GITHUB_EVENT_PATH="/tmp/lint/$(basename "${GITHUB_EVENT_FILE_PATH}")") COMMAND_TO_RUN+=(-e MULTI_STATUS=false) COMMAND_TO_RUN+=(-e VALIDATE_ALL_CODEBASE=false) - COMMAND_TO_RUN+=(-e VALIDATE_JSON=true) +} + +initialize_github_sha() { + local GIT_REPOSITORY_PATH="${1}" + local TEST_GITHUB_SHA + TEST_GITHUB_SHA="$(git -C "${GIT_REPOSITORY_PATH}" rev-parse HEAD)" + COMMAND_TO_RUN+=(-e GITHUB_SHA="${TEST_GITHUB_SHA}") } run_test_case_git_initial_commit() { @@ -95,10 +108,8 @@ run_test_case_git_initial_commit() { GIT_REPOSITORY_PATH="$(mktemp -d)" initialize_git_repository_and_test_args "${GIT_REPOSITORY_PATH}" "test/data/github-event/github-event-push.json" - - local TEST_GITHUB_SHA - TEST_GITHUB_SHA="$(git -C "${GIT_REPOSITORY_PATH}" rev-parse HEAD)" - COMMAND_TO_RUN+=(-e GITHUB_SHA="${TEST_GITHUB_SHA}") + initialize_github_sha "${GIT_REPOSITORY_PATH}" + COMMAND_TO_RUN+=(-e VALIDATE_JSON=true) } run_test_case_merge_commit_push() { @@ -128,9 +139,8 @@ run_test_case_merge_commit_push() { git -C "${GIT_REPOSITORY_PATH}" log --all --graph --abbrev-commit --decorate --format=oneline - local TEST_GITHUB_SHA - TEST_GITHUB_SHA="$(git -C "${GIT_REPOSITORY_PATH}" rev-parse HEAD)" - COMMAND_TO_RUN+=(-e GITHUB_SHA="${TEST_GITHUB_SHA}") + initialize_github_sha "${GIT_REPOSITORY_PATH}" + COMMAND_TO_RUN+=(-e VALIDATE_JSON=true) } run_test_case_use_find_and_ignore_gitignored_files() { @@ -155,46 +165,54 @@ run_test_case_custom_summary() { } run_test_case_fix_mode() { - run_test_cases_expect_success CREATE_LOG_FILE="true" SAVE_SUPER_LINTER_OUTPUT="true" - COMMAND_TO_RUN+=(--env FIX_ANSIBLE="true") - COMMAND_TO_RUN+=(--env FIX_CLANG_FORMAT="true") - COMMAND_TO_RUN+=(--env FIX_CSHARP="true") - COMMAND_TO_RUN+=(--env FIX_CSS="true") - COMMAND_TO_RUN+=(--env FIX_ENV="true") - COMMAND_TO_RUN+=(--env FIX_GO_MODULES="true") - COMMAND_TO_RUN+=(--env FIX_GO="true") - COMMAND_TO_RUN+=(--env FIX_GOOGLE_JAVA_FORMAT="true") - COMMAND_TO_RUN+=(--env FIX_GROOVY="true") - COMMAND_TO_RUN+=(--env FIX_JAVASCRIPT_ES="true") - COMMAND_TO_RUN+=(--env FIX_JAVASCRIPT_PRETTIER="true") - COMMAND_TO_RUN+=(--env FIX_JAVASCRIPT_STANDARD="true") - COMMAND_TO_RUN+=(--env FIX_JSON="true") - COMMAND_TO_RUN+=(--env FIX_JSONC="true") - COMMAND_TO_RUN+=(--env FIX_JSX="true") - COMMAND_TO_RUN+=(--env FIX_MARKDOWN="true") - COMMAND_TO_RUN+=(--env FIX_POWERSHELL="true") - COMMAND_TO_RUN+=(--env FIX_PROTOBUF="true") - COMMAND_TO_RUN+=(--env FIX_PYTHON_BLACK="true") - COMMAND_TO_RUN+=(--env FIX_PYTHON_ISORT="true") - COMMAND_TO_RUN+=(--env FIX_PYTHON_RUFF="true") - COMMAND_TO_RUN+=(--env FIX_RUBY="true") - COMMAND_TO_RUN+=(--env FIX_RUST_2015="true") - COMMAND_TO_RUN+=(--env FIX_RUST_2018="true") - COMMAND_TO_RUN+=(--env FIX_RUST_2021="true") - # Temporarily disable fix mode for rust clippy due to a dependency on another PR - # COMMAND_TO_RUN+=(--env FIX_RUST_CLIPPY="true") - COMMAND_TO_RUN+=(--env FIX_SCALAFMT="true") - COMMAND_TO_RUN+=(--env FIX_SHELL_SHFMT="true") - COMMAND_TO_RUN+=(--env FIX_SNAKEMAKE_SNAKEFMT="true") - COMMAND_TO_RUN+=(--env FIX_SQLFLUFF="true") - COMMAND_TO_RUN+=(--env FIX_TERRAFORM_FMT="true") - COMMAND_TO_RUN+=(--env FIX_TSX="true") - COMMAND_TO_RUN+=(--env FIX_TYPESCRIPT_ES="true") - COMMAND_TO_RUN+=(--env FIX_TYPESCRIPT_PRETTIER="true") - COMMAND_TO_RUN+=(--env FIX_TYPESCRIPT_STANDARD="true") + GIT_REPOSITORY_PATH="$(mktemp -d)" + + initialize_git_repository_and_test_args "${GIT_REPOSITORY_PATH}" "test/data/github-event/github-event-push.json" + + local LINTERS_TEST_CASES_FIX_MODE_DESTINATION_PATH="${GIT_REPOSITORY_PATH}/${LINTERS_TEST_CASE_DIRECTORY}" + mkdir -p "${LINTERS_TEST_CASES_FIX_MODE_DESTINATION_PATH}" + + for LANGUAGE in "${LANGUAGES_WITH_FIX_MODE[@]}"; do + if [[ "${SUPER_LINTER_CONTAINER_IMAGE_TYPE}" == "slim" ]] && + ! IsLanguageInSlimImage "${LANGUAGE}"; then + debug "Skip ${LANGUAGE} because it's not available in the Super-linter ${SUPER_LINTER_CONTAINER_IMAGE_TYPE} image" + continue + fi + local -l LOWERCASE_LANGUAGE="${LANGUAGE}" + cp -rv "${LINTERS_TEST_CASE_DIRECTORY}/${LOWERCASE_LANGUAGE}" "${LINTERS_TEST_CASES_FIX_MODE_DESTINATION_PATH}/" + eval "COMMAND_TO_RUN+=(--env FIX_${LANGUAGE}=\"true\")" + eval "COMMAND_TO_RUN+=(--env VALIDATE_${LANGUAGE}=\"true\")" + done + + # Copy gitignore so we don't commit eventual leftovers from previous runs + cp -v ".gitignore" "${GIT_REPOSITORY_PATH}/" + + # Copy fix mode linter configuration files because default ones are not always + # suitable for fix mode + local FIX_MODE_LINTERS_CONFIG_DIR="${GIT_REPOSITORY_PATH}/.github/linters" + mkdir -p "${FIX_MODE_LINTERS_CONFIG_DIR}" + cp -rv "test/linters-config/fix-mode/." "${FIX_MODE_LINTERS_CONFIG_DIR}/" + cp -rv ".github/linters/tsconfig.json" "${FIX_MODE_LINTERS_CONFIG_DIR}/" + git -C "${GIT_REPOSITORY_PATH}" add . + git -C "${GIT_REPOSITORY_PATH}" commit --no-verify -m "feat: add fix mode test cases" + initialize_github_sha "${GIT_REPOSITORY_PATH}" + + CREATE_LOG_FILE="true" + SAVE_SUPER_LINTER_OUTPUT="true" + VERIFY_FIX_MODE="true" + + # Enable test mode so we run linters and formatters only against their test + # cases + COMMAND_TO_RUN+=(--env FIX_MODE_TEST_CASE_RUN=true) + COMMAND_TO_RUN+=(--env TEST_CASE_RUN=true) + COMMAND_TO_RUN+=(--env ANSIBLE_DIRECTORY="/test/linters/ansible/bad") + configure_typescript_for_test_cases + + # Some linters report a non-zero exit code even if they fix all the issues + EXPECTED_EXIT_CODE=2 } # Run the test setup function @@ -203,28 +221,30 @@ ${TEST_FUNCTION_NAME} CREATE_LOG_FILE="${CREATE_LOG_FILE:-false}" SAVE_SUPER_LINTER_OUTPUT="${SAVE_SUPER_LINTER_OUTPUT:-false}" +SUPER_LINTER_WORKSPACE="${SUPER_LINTER_WORKSPACE:-$(pwd)}" +COMMAND_TO_RUN+=(-v "${SUPER_LINTER_WORKSPACE}":"/tmp/lint") + if [ -n "${SUPER_LINTER_OUTPUT_DIRECTORY_NAME:-}" ]; then COMMAND_TO_RUN+=(-e SUPER_LINTER_OUTPUT_DIRECTORY_NAME="${SUPER_LINTER_OUTPUT_DIRECTORY_NAME}") fi SUPER_LINTER_OUTPUT_DIRECTORY_NAME="${SUPER_LINTER_OUTPUT_DIRECTORY_NAME:-"super-linter-output"}" -SUPER_LINTER_MAIN_OUTPUT_PATH="$(pwd)/${SUPER_LINTER_OUTPUT_DIRECTORY_NAME}" -echo "Super-linter main output path: ${SUPER_LINTER_MAIN_OUTPUT_PATH}" +SUPER_LINTER_MAIN_OUTPUT_PATH="${SUPER_LINTER_WORKSPACE}/${SUPER_LINTER_OUTPUT_DIRECTORY_NAME}" +debug "Super-linter main output path: ${SUPER_LINTER_MAIN_OUTPUT_PATH}" SUPER_LINTER_OUTPUT_PATH="${SUPER_LINTER_MAIN_OUTPUT_PATH}/super-linter" -echo "Super-linter output path: ${SUPER_LINTER_OUTPUT_PATH}" +debug "Super-linter output path: ${SUPER_LINTER_OUTPUT_PATH}" COMMAND_TO_RUN+=(-e CREATE_LOG_FILE="${CREATE_LOG_FILE}") COMMAND_TO_RUN+=(-e LOG_LEVEL="${LOG_LEVEL:-"DEBUG"}") COMMAND_TO_RUN+=(-e RUN_LOCAL="${RUN_LOCAL:-true}") COMMAND_TO_RUN+=(-e SAVE_SUPER_LINTER_OUTPUT="${SAVE_SUPER_LINTER_OUTPUT}") -COMMAND_TO_RUN+=(-v "${SUPER_LINTER_WORKSPACE:-$(pwd)}":"/tmp/lint") -SUPER_LINTER_GITHUB_STEP_SUMMARY_FILE_PATH="$(pwd)/github-step-summary.md" +SUPER_LINTER_GITHUB_STEP_SUMMARY_FILE_PATH="${SUPER_LINTER_WORKSPACE}/github-step-summary.md" # We can't put this inside SUPER_LINTER_MAIN_OUTPUT_PATH because it doesn't exist # before Super-linter creates it, and we want to verify that as well. -echo "SUPER_LINTER_GITHUB_STEP_SUMMARY_FILE_PATH: ${SUPER_LINTER_GITHUB_STEP_SUMMARY_FILE_PATH}" +debug "SUPER_LINTER_GITHUB_STEP_SUMMARY_FILE_PATH: ${SUPER_LINTER_GITHUB_STEP_SUMMARY_FILE_PATH}" if [ -n "${EXPECTED_SUPER_LINTER_SUMMARY_FILE_PATH:-}" ]; then - echo "Expected Super-linter step summary file path: ${EXPECTED_SUPER_LINTER_SUMMARY_FILE_PATH}" + debug "Expected Super-linter step summary file path: ${EXPECTED_SUPER_LINTER_SUMMARY_FILE_PATH}" ENABLE_GITHUB_ACTIONS_STEP_SUMMARY="true" SAVE_SUPER_LINTER_SUMMARY="true" @@ -240,71 +260,105 @@ if [ -n "${SUPER_LINTER_SUMMARY_FILE_NAME:-}" ]; then COMMAND_TO_RUN+=(-e SUPER_LINTER_SUMMARY_FILE_NAME="${SUPER_LINTER_SUMMARY_FILE_NAME}") fi SUPER_LINTER_SUMMARY_FILE_NAME="${SUPER_LINTER_SUMMARY_FILE_NAME:-"super-linter-summary.md"}" -echo "SUPER_LINTER_SUMMARY_FILE_NAME: ${SUPER_LINTER_SUMMARY_FILE_NAME}" +debug "SUPER_LINTER_SUMMARY_FILE_NAME: ${SUPER_LINTER_SUMMARY_FILE_NAME}" SUPER_LINTER_SUMMARY_FILE_PATH="${SUPER_LINTER_MAIN_OUTPUT_PATH}/${SUPER_LINTER_SUMMARY_FILE_NAME}" -echo "Super-linter summary output path: ${SUPER_LINTER_SUMMARY_FILE_PATH}" +debug "Super-linter summary output path: ${SUPER_LINTER_SUMMARY_FILE_PATH}" -LOG_FILE_PATH="$(pwd)/super-linter.log" +LOG_FILE_PATH="${SUPER_LINTER_WORKSPACE}/super-linter.log" COMMAND_TO_RUN+=("${SUPER_LINTER_TEST_CONTAINER_URL}") declare -i EXPECTED_EXIT_CODE EXPECTED_EXIT_CODE=${EXPECTED_EXIT_CODE:-0} -echo "Cleaning eventual leftovers before running tests: ${LEFTOVERS_TO_CLEAN[*]}" +debug "Cleaning eventual leftovers before running tests: ${LEFTOVERS_TO_CLEAN[*]}" LEFTOVERS_TO_CLEAN+=("${LOG_FILE_PATH}") LEFTOVERS_TO_CLEAN+=("${SUPER_LINTER_GITHUB_STEP_SUMMARY_FILE_PATH}") LEFTOVERS_TO_CLEAN+=("${SUPER_LINTER_MAIN_OUTPUT_PATH}") LEFTOVERS_TO_CLEAN+=("${SUPER_LINTER_SUMMARY_FILE_PATH}") +LEFTOVERS_TO_CLEAN+=("${SUPER_LINTER_SUMMARY_FILE_PATH}") +LEFTOVERS_TO_CLEAN+=("${SUPER_LINTER_WORKSPACE}/${LINTERS_TEST_CASE_DIRECTORY}/rust_clippy/bad/target") +LEFTOVERS_TO_CLEAN+=("${SUPER_LINTER_WORKSPACE}/${LINTERS_TEST_CASE_DIRECTORY}/rust_clippy/bad/Cargo.lock") +LEFTOVERS_TO_CLEAN+=("${SUPER_LINTER_WORKSPACE}/${LINTERS_TEST_CASE_DIRECTORY}/rust_clippy/good/target") +LEFTOVERS_TO_CLEAN+=("${SUPER_LINTER_WORKSPACE}/${LINTERS_TEST_CASE_DIRECTORY}/rust_clippy/good/Cargo.lock") +# Delete leftovers in pwd in case the workspace is not pwd +LEFTOVERS_TO_CLEAN+=("$(pwd)/$(basename "${LOG_FILE_PATH}")") +LEFTOVERS_TO_CLEAN+=("$(pwd)/$(basename "${SUPER_LINTER_GITHUB_STEP_SUMMARY_FILE_PATH}")") +LEFTOVERS_TO_CLEAN+=("$(pwd)/$(basename "${SUPER_LINTER_MAIN_OUTPUT_PATH}")") +LEFTOVERS_TO_CLEAN+=("$(pwd)/$(basename "${SUPER_LINTER_SUMMARY_FILE_PATH}")") +LEFTOVERS_TO_CLEAN+=("$(pwd)/${LINTERS_TEST_CASE_DIRECTORY}/rust_clippy/bad/target") +LEFTOVERS_TO_CLEAN+=("$(pwd)/${LINTERS_TEST_CASE_DIRECTORY}/rust_clippy/bad/Cargo.lock") +LEFTOVERS_TO_CLEAN+=("$(pwd)/${LINTERS_TEST_CASE_DIRECTORY}/rust_clippy/good/target") +LEFTOVERS_TO_CLEAN+=("$(pwd)/${LINTERS_TEST_CASE_DIRECTORY}/rust_clippy/good/Cargo.lock") sudo rm -rfv "${LEFTOVERS_TO_CLEAN[@]}" if [[ "${ENABLE_GITHUB_ACTIONS_STEP_SUMMARY}" == "true" ]]; then - echo "Creating GitHub Actions step summary file: ${SUPER_LINTER_GITHUB_STEP_SUMMARY_FILE_PATH}" + debug "Creating GitHub Actions step summary file: ${SUPER_LINTER_GITHUB_STEP_SUMMARY_FILE_PATH}" touch "${SUPER_LINTER_GITHUB_STEP_SUMMARY_FILE_PATH}" fi -if [ ${EXPECTED_EXIT_CODE} -ne 0 ]; then - echo "Disable failures on error because the expected exit code is ${EXPECTED_EXIT_CODE}" - set +o errexit -fi +debug "Command to run: ${COMMAND_TO_RUN[*]}" -echo "Command to run: ${COMMAND_TO_RUN[*]}" +# Disable failures on error so we can continue with tests regardless +# of the Super-linter exit code +set +o errexit "${COMMAND_TO_RUN[@]}" - SUPER_LINTER_EXIT_CODE=$? -# Enable the errexit option in case we disabled it +# Enable the errexit option that we check later set -o errexit -echo "Super-linter exit code: ${SUPER_LINTER_EXIT_CODE}" +debug "Super-linter workspace: ${SUPER_LINTER_WORKSPACE}" +debug "Super-linter exit code: ${SUPER_LINTER_EXIT_CODE}" if [[ "${CREATE_LOG_FILE}" == true ]]; then if [ ! -e "${LOG_FILE_PATH}" ]; then - echo "Log file was requested but it's not available at ${LOG_FILE_PATH}" + debug "Log file was requested but it's not available at ${LOG_FILE_PATH}" exit 1 else sudo chown -R "$(id -u)":"$(id -g)" "${LOG_FILE_PATH}" - echo "Log file contents:" - cat "${LOG_FILE_PATH}" + debug "Log file path: ${LOG_FILE_PATH}" + if [[ "${CI:-}" == "true" ]]; then + debug "Log file contents:" + cat "${LOG_FILE_PATH}" + else + debug "Not in CI environment, skip emitting log file (${LOG_FILE_PATH}) contents" + fi + + if [[ "${SUPER_LINTER_WORKSPACE}" != "$(pwd)" ]]; then + debug "Copying Super-linter log from the workspace (${SUPER_LINTER_WORKSPACE}) to the current working directory for easier inspection" + cp -v "${LOG_FILE_PATH}" "$(pwd)/" + fi fi else - echo "Log file was not requested. CREATE_LOG_FILE: ${CREATE_LOG_FILE}" + debug "Log file was not requested. CREATE_LOG_FILE: ${CREATE_LOG_FILE}" fi if [[ "${SAVE_SUPER_LINTER_OUTPUT}" == true ]]; then if [ ! -d "${SUPER_LINTER_OUTPUT_PATH}" ]; then - echo "Super-linter output was requested but it's not available at ${SUPER_LINTER_OUTPUT_PATH}" + debug "Super-linter output was requested but it's not available at ${SUPER_LINTER_OUTPUT_PATH}" exit 1 else sudo chown -R "$(id -u)":"$(id -g)" "${SUPER_LINTER_OUTPUT_PATH}" - echo "Super-linter output path (${SUPER_LINTER_OUTPUT_PATH}) contents:" - ls -alhR "${SUPER_LINTER_OUTPUT_PATH}" + if [[ "${CI:-}" == "true" ]]; then + debug "Super-linter output path (${SUPER_LINTER_OUTPUT_PATH}) contents:" + ls -alhR "${SUPER_LINTER_OUTPUT_PATH}" + else + debug "Not in CI environment, skip emitting ${SUPER_LINTER_OUTPUT_PATH} contents" + fi + + if [[ "${SUPER_LINTER_WORKSPACE}" != "$(pwd)" ]]; then + debug "Copying Super-linter output from the workspace (${SUPER_LINTER_WORKSPACE}) to the current working directory for easier inspection" + SUPER_LINTER_OUTPUT_PATH_PWD="$(pwd)/super-linter-output/" + mkdir -p "${SUPER_LINTER_OUTPUT_PATH_PWD}" + cp -r "${SUPER_LINTER_OUTPUT_PATH}" "${SUPER_LINTER_OUTPUT_PATH_PWD}" + fi fi else - echo "Super-linter output was not requested. SAVE_SUPER_LINTER_OUTPUT: ${SAVE_SUPER_LINTER_OUTPUT}" + debug "Super-linter output was not requested. SAVE_SUPER_LINTER_OUTPUT: ${SAVE_SUPER_LINTER_OUTPUT}" if [ -e "${SUPER_LINTER_OUTPUT_PATH}" ]; then - echo "Super-linter output was not requested but it's available at ${SUPER_LINTER_OUTPUT_PATH}" + debug "Super-linter output was not requested but it's available at ${SUPER_LINTER_OUTPUT_PATH}" exit 1 fi fi @@ -312,37 +366,96 @@ fi if [ -n "${EXPECTED_SUPER_LINTER_SUMMARY_FILE_PATH:-}" ]; then # Remove eventual HTML comments from the expected file because we use them to disable certain linter rules if ! diff "${SUPER_LINTER_SUMMARY_FILE_PATH}" <(grep -vE '^\s*