mirror of
https://github.com/super-linter/super-linter.git
synced 2024-12-22 04:32:16 -05:00
feat: local fix mode (#5978)
Certain linters and formatters support fixing linting and formatting issues (fix mode). Before this change, Super-linter runs linters and formatters in a mode that doesn't modify the source code in any way (check only mode). With this change, Super-linter supports running linters and formatters in fix mode if explicitly requested by the configuration. If the configuration includes a variable named FIX_<language_name>, Super-linters modifies the command to run the linter or formatter for <language_name> to enable fix mode. The modifications to the linter or formatter command that Super-linter applies depend on what is the default for a particular linter: it either removes or adds options to the command to run the linter or formatter.
This commit is contained in:
parent
633b8af60d
commit
6fdc091361
17 changed files with 786 additions and 70 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -89,7 +89,7 @@ test/reports
|
|||
# Test leftovers
|
||||
.lintr
|
||||
test/linters/rust_clippy/**/Cargo.lock
|
||||
test/linters/rust_clippy/**/target/**
|
||||
test/linters/rust_clippy/**/target
|
||||
|
||||
# Super-linter ouputs
|
||||
super-linter-output/
|
||||
|
|
37
Makefile
37
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 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 ## 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-expect-success ## 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
|
||||
|
@ -231,6 +231,7 @@ test-git-flags: ## Run super-linter with different git-related flags
|
|||
.PHONY: lint-codebase
|
||||
lint-codebase: ## Lint the entire codebase
|
||||
docker run \
|
||||
-e CREATE_LOG_FILE=true \
|
||||
-e RUN_LOCAL=true \
|
||||
-e LOG_LEVEL=DEBUG \
|
||||
-e DEFAULT_BRANCH=main \
|
||||
|
@ -238,11 +239,37 @@ lint-codebase: ## Lint the entire codebase
|
|||
-e FILTER_REGEX_EXCLUDE=".*(/test/linters/|CHANGELOG.md).*" \
|
||||
-e GITLEAKS_CONFIG_FILE=".gitleaks-ignore-tests.toml" \
|
||||
-e RENOVATE_SHAREABLE_CONFIG_PRESET_FILE_NAMES="default.json,hoge.json" \
|
||||
-e SAVE_SUPER_LINTER_OUTPUT=true \
|
||||
-e SAVE_SUPER_LINTER_SUMMARY=true \
|
||||
-e VALIDATE_ALL_CODEBASE=true \
|
||||
-v "$(CURDIR):/tmp/lint" \
|
||||
$(SUPER_LINTER_TEST_CONTAINER_URL)
|
||||
|
||||
# Return an error if there are changes to commit
|
||||
.PHONY: fix-codebase
|
||||
fix-codebase: ## Fix and format the entire codebase
|
||||
docker run \
|
||||
-e CREATE_LOG_FILE=true \
|
||||
-e DEFAULT_BRANCH=main \
|
||||
-e ENABLE_GITHUB_ACTIONS_GROUP_TITLE=true \
|
||||
-e FILTER_REGEX_EXCLUDE=".*(/test/linters/|CHANGELOG.md).*" \
|
||||
-e FIX_ENV=true \
|
||||
-e FIX_JAVASCRIPT_ES=true \
|
||||
-e FIX_JAVASCRIPT_PRETTIER=true \
|
||||
-e FIX_JSON=true \
|
||||
-e FIX_MARKDOWN=true \
|
||||
-e FIX_SHELL_SHFMT=true \
|
||||
-e GITLEAKS_CONFIG_FILE=".gitleaks-ignore-tests.toml" \
|
||||
-e LOG_LEVEL=DEBUG \
|
||||
-e RUN_LOCAL=true \
|
||||
-e SAVE_SUPER_LINTER_OUTPUT=true \
|
||||
-e SAVE_SUPER_LINTER_SUMMARY=true \
|
||||
-e VALIDATE_ALL_CODEBASE=true \
|
||||
-v "$(CURDIR):/tmp/lint" \
|
||||
$(SUPER_LINTER_TEST_CONTAINER_URL) \
|
||||
&& /bin/bash -c "source test/testUtils.sh; if ! CheckUnexpectedGitChanges ${CURDIR}; then exit 1; fi"
|
||||
|
||||
|
||||
# This is a smoke test to check how much time it takes to lint only a small
|
||||
# subset of files, compared to linting the whole codebase.
|
||||
.PHONY: lint-subset-files
|
||||
|
@ -389,6 +416,14 @@ 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
|
||||
$(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
|
||||
|
||||
|
|
74
README.md
74
README.md
|
@ -1,7 +1,7 @@
|
|||
# Super-Linter
|
||||
|
||||
Super-linter is a ready-to-run collection of linters and code analyzers, to
|
||||
help validate your source code.
|
||||
help validate and fix your source code.
|
||||
|
||||
The goal of super-linter is to help you establish best practices and consistent
|
||||
formatting across multiple programming languages, and ensure developers are
|
||||
|
@ -12,6 +12,8 @@ issues that those tools find as console output, and as
|
|||
[GitHub Actions status checks](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/about-status-checks).
|
||||
You can also [run super-linter outside GitHub Actions](#run-super-linter-outside-github-actions).
|
||||
|
||||
Super-linter can also help you [fix linting and formatting issues](#fix-linting-and-formatting-issues).
|
||||
|
||||
Super-linter is licensed under an
|
||||
[MIT License](https://github.com/super-linter/super-linter/blob/main/LICENSE).
|
||||
|
||||
|
@ -183,9 +185,9 @@ Super-Linter provides several variants:
|
|||
- `pwsh` linters
|
||||
- `c#` linters
|
||||
|
||||
## Configure super-linter
|
||||
## Configure Super-linter
|
||||
|
||||
You can configure super-linter using the following environment variables:
|
||||
You can configure Super-linter using the following environment variables:
|
||||
|
||||
| **Environment variable** | **Default Value** | **Description** |
|
||||
|-------------------------------------------------|---------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
|
@ -207,6 +209,41 @@ You can configure super-linter using the following environment variables:
|
|||
| **ENABLE_GITHUB_ACTIONS_STEP_SUMMARY** | `false` if `RUN_LOCAL=true`, `true` otherwise | Flag to enable [GitHub Actions job summary](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary) for the Super-linter action. For more information, see [Summary outputs](#summary-outputs). |
|
||||
| **FILTER_REGEX_EXCLUDE** | not set | Regular expression defining which files will be excluded from linting (ex: `.*src/test.*`). Not setting this variable means to process all files. |
|
||||
| **FILTER_REGEX_INCLUDE** | not set | Regular expression defining which files will be processed by linters (ex: `.*src/.*`). Not setting this variable means to process all files. `FILTER_REGEX_INCLUDE` is evaluated before `FILTER_REGEX_EXCLUDE`. |
|
||||
| **FIX_ANSIBLE** | `false` | Option to enable fix mode for `ANSIBLE`. |
|
||||
| **FIX_CLANG_FORMAT** | `false` | Option to enable fix mode for `CLANG_FORMAT`. |
|
||||
| **FIX_CSHARP** | `false` | Option to enable fix mode for `CSHARP`. |
|
||||
| **FIX_CSS** | `false` | Option to enable fix mode for `CSS`. |
|
||||
| **FIX_ENV** | `false` | Option to enable fix mode for `ENV`. |
|
||||
| **FIX_GO** | `false` | Option to enable fix mode for `GO`. |
|
||||
| **FIX_GO_MODULES** | `false` | Option to enable fix mode for `GO_MODULES`. |
|
||||
| **FIX_GOOGLE_JAVA_FORMAT** | `false` | Option to enable fix mode for `GOOGLE_JAVA_FORMAT`. |
|
||||
| **FIX_GROOVY** | `false` | Option to enable fix mode for `GROOVY`. |
|
||||
| **FIX_JAVASCRIPT_ES** | `false` | Option to enable fix mode for `JAVASCRIPT_ES`. |
|
||||
| **FIX_JAVASCRIPT_PRETTIER** | `false` | Option to enable fix mode for `JAVASCRIPT_PRETTIER`. |
|
||||
| **FIX_JAVASCRIPT_STANDARD** | `false` | Option to enable fix mode for `JAVASCRIPT_STANDARD`. |
|
||||
| **FIX_JSON** | `false` | Option to enable fix mode for `JSON`. |
|
||||
| **FIX_JSONC** | `false` | Option to enable fix mode for `JSONC`. |
|
||||
| **FIX_JSX** | `false` | Option to enable fix mode for `JSX`. |
|
||||
| **FIX_MARKDOWN** | `false` | Option to enable fix mode for `MARKDOWN`. |
|
||||
| **FIX_POWERSHELL** | `false` | Option to enable fix mode for `POWERSHELL`. |
|
||||
| **FIX_PROTOBUF** | `false` | Option to enable fix mode for `PROTOBUF`. |
|
||||
| **FIX_PYTHON_BLACK** | `false` | Option to enable fix mode for `PYTHON_BLACK`. |
|
||||
| **FIX_PYTHON_ISORT** | `false` | Option to enable fix mode for `PYTHON_ISORT`. |
|
||||
| **FIX_PYTHON_RUFF** | `false` | Option to enable fix mode for `PYTHON_RUFF`. |
|
||||
| **FIX_RUBY** | `false` | Option to enable fix mode for `RUBY`. |
|
||||
| **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_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`. |
|
||||
| **FIX_SQLFLUFF** | `false` | Option to enable fix mode for `SQLFLUFF`. |
|
||||
| **FIX_TERRAFORM_FMT** | `false` | Option to enable fix mode for `TERRAFORM_FMT`. |
|
||||
| **FIX_TSX** | `false` | Option to enable fix mode for `TSX`. |
|
||||
| **FIX_TYPESCRIPT_ES** | `false` | Option to enable fix mode for `TYPESCRIPT_ES`. |
|
||||
| **FIX_TYPESCRIPT_PRETTIER** | `false` | Option to enable fix mode for `TYPESCRIPT_PRETTIER`. |
|
||||
| **FIX_TYPESCRIPT_STANDARD** | `false` | Option to enable fix mode for `TYPESCRIPT_STANDARD`. |
|
||||
| **GITHUB_ACTIONS_CONFIG_FILE** | `actionlint.yml` | Filename for [Actionlint configuration](https://github.com/rhysd/actionlint/blob/main/docs/config.md) (ex: `actionlint.yml`) |
|
||||
| **GITHUB_ACTIONS_COMMAND_ARGS** | `null` | Additional arguments passed to `actionlint` command. Useful to [ignore some errors](https://github.com/rhysd/actionlint/blob/main/docs/usage.md#ignore-some-errors) |
|
||||
| **GITHUB_CUSTOM_API_URL** | `https://api.${GITHUB_DOMAIN}` | Specify a custom GitHub API URL in case GitHub Enterprise is used: e.g. `https://github.myenterprise.com/api/v3` |
|
||||
|
@ -351,10 +388,39 @@ The `VALIDATE_[LANGUAGE]` variables work as follows:
|
|||
- If you set any of the `VALIDATE_[LANGUAGE]` variables to `false`, super-linter defaults to leaving any unset variable to true (only exclude those languages).
|
||||
- If you set any of the `VALIDATE_[LANGUAGE]` variables to both `true` and `false`, super-linter fails reporting an error.
|
||||
|
||||
For more information about reusing super-linter configuration across
|
||||
For more information about reusing Super-linter configuration across
|
||||
environments, see
|
||||
[Share Environment variables between environments](docs/run-linter-locally.md#share-environment-variables-between-environments).
|
||||
|
||||
## Fix linting and formatting issues
|
||||
|
||||
All the linters and formatters that Super-linter runs report errors if they
|
||||
detect linting or formatting issues without modifying your source
|
||||
code (_check only mode_). Check only mode is the default for all linters and
|
||||
formatters that Super-linter runs.
|
||||
|
||||
Certain linters and formatters support automatically fixing issues in your code
|
||||
(_fix mode_). You can enable fix mode for a particular linter or formatter by
|
||||
setting the relevant `FIX_<language name>` variable to `true`. To know which
|
||||
linters and formatters support fix mode, refer to the
|
||||
[Configure Super-linter section](#configure-super-linter).
|
||||
|
||||
Setting a `FIX_<language name>` variable to `true` implies setting the
|
||||
corresponding `VALIDATE_<language name>` to `true`. Setting a
|
||||
`FIX_<language name>` variable to `true` and the corresponding
|
||||
`VALIDATE_<language name>` to `false` is a configuration error. Super-linter
|
||||
reports that as a fatal error.
|
||||
|
||||
Super-linter supports the following locations to deliver fixes:
|
||||
|
||||
- In the current Super-linter workspace, so you can process the changes to your
|
||||
files by yourself. For example:
|
||||
|
||||
- If you're running Super-linter in your CI environment, such as GitHub
|
||||
Actions, you can commit and push changes as part of your workflow.
|
||||
- If you're running Super-linter locally, you can commit the changes as you
|
||||
would with any other change in your working directory.
|
||||
|
||||
## Configure linters
|
||||
|
||||
Super-linter provides default configurations for some linters in the [`TEMPLATES/`](TEMPLATES/)
|
||||
|
|
|
@ -8,8 +8,10 @@ new tool, it should include:
|
|||
- Provide test cases:
|
||||
|
||||
1. Create the `test/linters/<LANGUGAGE>` directory.
|
||||
2. Provide at least one test case with a file that is supposed to pass validation: `test/linters/<LANGUAGE>/<name-of-tool>-good`
|
||||
3. Provide at least one test case with a file that is supposed to fail validation: `test/linters/<LANGUAGE>/<name-of-tool>-bad`
|
||||
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/<LANGUAGE>/<name-of-tool>-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/<LANGUAGE>/<name-of-tool>-bad`
|
||||
|
||||
- Update the test suite to check for installed packages, the commands that your new tool needs in the `PATH`, and the expected version command:
|
||||
|
||||
|
@ -89,28 +91,73 @@ new tool, it should include:
|
|||
|
||||
- Update the orchestration scripts to run the new tool:
|
||||
|
||||
- `globals/languages.sh`: add a new item to `LANGUAGES_ARRAY` array. Use the
|
||||
"name" of the language, then a `_`, and finally the name of the linter. Example: `PYTHON_RUFF`
|
||||
- `lib/globals/languages.sh`: add a new item to `LANGUAGES_ARRAY` array. Use the
|
||||
"name" of the language, then a `_`, and finally the name of the linter. Example: `PYTHON_RUFF`.
|
||||
In the context of this document, to avoid repetitions we reference this new
|
||||
item as `<LANGUAGE_NAME>`.
|
||||
|
||||
- Linter configuration:
|
||||
- `globals/linterRules.sh`:
|
||||
- If the new linter accepts a configuration files from the command line, add a new variable
|
||||
with a default filename using the item that you added to the `LANGUAGES_ARRAY` as a prefix,
|
||||
followed by the `CONFIG_FILE` suffix. Example:
|
||||
`PYTHON_RUFF_FILE_NAME="${PYTHON_RUFF_CONFIG_FILE:-.ruff.toml}"`.
|
||||
- If there are arguments that you can only pass using the command line, and you think users
|
||||
might want to customize them, define a new variable using the item that
|
||||
you added to the `LANGUAGES_ARRAY` as a prefix, followed by the
|
||||
`COMMAND_ARGS` suffix. Example:
|
||||
`GITHUB_ACTIONS_COMMAND_ARGS="${GITHUB_ACTIONS_COMMAND_ARGS:-""}"`
|
||||
- Create a new minimal configuration file in the `TEMPLATES` directory with the same name as the
|
||||
default configuration filename. Example: `TEMPLATES/.ruff.toml`.
|
||||
- `lib/linter.sh`
|
||||
- `lib/functions/linterCommands.sh`: define a new array to invoke the new linter.
|
||||
- Provide the logic to populate the list of files or directories to examine: `lib/buildFileList.sh`
|
||||
- If necessary, provide elaborate logic to detect if the tool should examine a file or a directory: `lib/detectFiles.sh`
|
||||
- If the tool needs to take into account special cases:
|
||||
- `lib/globals/linterRules.sh`:
|
||||
- If the new linter accepts a configuration files from the command line,
|
||||
define a new variable:
|
||||
`<LANGUAGE_NAME>_FILE_NAME="${<LANGUAGE_NAME>_CONFIG_FILE:-"default-config-file-name.conf"}"`
|
||||
where `default-config-file-name.conf` is the name of the new,
|
||||
minimal configuration for the linter. Example:
|
||||
`PYTHON_RUFF_FILE_NAME="${PYTHON_RUFF_CONFIG_FILE:-.ruff.toml}"`.
|
||||
- If there are arguments that you can only pass using the command line, and you think users
|
||||
might want to customize them, define a new variable using
|
||||
`<LANGUAGE_NAME>_COMMAND_ARGS` and add it to the command if the
|
||||
configuration provides it. Example:
|
||||
|
||||
- Provide new runtime validation checks in `lib/validation.sh`.
|
||||
- Customize the logic to get the installed version of the tool: `scripts/linterVersions.sh`
|
||||
- Provide custom logic to load configuration files: `lib/linterRules.sh`
|
||||
- Provide custom logic for test cases and to run the tool: `lib/worker.sh`
|
||||
```bash
|
||||
<LANGUAGE_NAME>_COMMAND_ARGS="${<LANGUAGE_NAME>_COMMAND_ARGS:-""}"
|
||||
if [ -n "${<LANGUAGE_NAME>_COMMAND_ARGS:-}" ]; then
|
||||
export <LANGUAGE_NAME>_COMMAND_ARGS
|
||||
LINTER_COMMANDS_ARRAY_<LANGUAGE_NAME>+=("${<LANGUAGE_NAME>_COMMAND_ARGS}")
|
||||
fi
|
||||
```
|
||||
|
||||
- Define the command to invoke the new linter:
|
||||
|
||||
- `lib/functions/linterCommands.sh`: add the command to invoke the linter.
|
||||
Define a new variable: `LINTER_COMMANDS_ARRAY_<LANGUAGE_NAME>`.
|
||||
Example:
|
||||
`LINTER_COMMANDS_ARRAY_GO_MODULES=(golangci-lint run --allow-parallel-runners -c "${GO_LINTER_RULES}")`
|
||||
|
||||
If the linter needs to load a configuration file, add the relevant options
|
||||
and paths to the command you just defined. The path to the configuration
|
||||
file is automatically initialized by Super-linter using in the
|
||||
`<LANGUAGE_NAME>_LINTER_RULES` variable, as in the `GO_LINTER_RULES`
|
||||
example above for the `GO` language.
|
||||
|
||||
- `lib/globals/linterCommandsOptions.sh`: add "check only mode" and "fix
|
||||
linting and formatting issues mode" options if the linter supports it.
|
||||
Super-linter will automatically add them to the command to run the linter.
|
||||
|
||||
- If the linter runs in "fix linting and formatting issues mode" by
|
||||
default, define a new variable with the options to add to the linter
|
||||
command to enable "check only mode":
|
||||
`<LANGUAGE_NAME>_CHECK_ONLY_MODE_OPTIONS=(....)`.
|
||||
Example: `PYTHON_BLACK_CHECK_ONLY_MODE_OPTIONS=(--diff --check)`
|
||||
|
||||
- If the linter runs in "check only mode" by
|
||||
default, define a new variable with the options to add to the linter
|
||||
command to enable "fix linting and formatting issues mode":
|
||||
`<LANGUAGE_NAME>_FIX_MODE_OPTIONS=(...)`.
|
||||
Example: `ANSIBLE_FIX_MODE_OPTIONS=(--fix)`
|
||||
|
||||
- Provide the logic to populate the list of files or directories to examine: `lib/functions/buildFileList.sh`
|
||||
- If necessary, provide elaborate logic to detect if the tool should examine a file or a directory: `lib/functions/detectFiles.sh`
|
||||
- If the tool needs to take into account special cases, reach out to the
|
||||
maintainers by creating a draft pull request and ask relevant questions
|
||||
there. For example, you might need to provide new logic or customize
|
||||
the existing one to:
|
||||
|
||||
- Validate the runtime environment: `lib/functions/validation.sh`.
|
||||
- Get the installed version of the linter: `scripts/linterVersions.sh`
|
||||
- Load configuration files: `lib/functions/linterRules.sh`
|
||||
- Run the linter: `lib/functions/worker.sh`
|
||||
- Compose the linter command: `lib/functions/linterCommands.sh`
|
||||
- Modify the core Super-linter logic: `lib/linter.sh`
|
||||
|
|
|
@ -139,3 +139,12 @@ To get the list of the available `Make` targets, run the following command:
|
|||
```shell
|
||||
make help
|
||||
```
|
||||
|
||||
### Automatically fix formatting and linting issues
|
||||
|
||||
To automatically fix linting and formatting issues when supported, run the
|
||||
following command:
|
||||
|
||||
```shell
|
||||
make fix-codebase
|
||||
```
|
||||
|
|
|
@ -39,17 +39,14 @@ This section helps you upgrade from super-linter `v6.7.0` to `v6.8.0`.
|
|||
|
||||
- If you set `JAVASCRIPT_DEFAULT_STYLE=standard`, set
|
||||
`VALIDATE_JAVASCRIPT_PRETTIER=false`
|
||||
|
||||
- If you set `TYPESCRIPT_DEFAULT_STYLE=standard`, set
|
||||
`VALIDATE_TYPESCRIPT_PRETTIER=false`
|
||||
|
||||
- If you set `JAVASCRIPT_DEFAULT_STYLE=prettier`, set
|
||||
`VALIDATE_JAVASCRIPT_STANDARD=false`
|
||||
|
||||
- If you set `TYPESCRIPT_DEFAULT_STYLE=prettier`, set
|
||||
`VALIDATE_TYPESCRIPT_STANDARD=false`
|
||||
|
||||
Finally, you remove both `JAVASCRIPT_DEFAULT_STYLE` and
|
||||
Finally, remove both `JAVASCRIPT_DEFAULT_STYLE` and
|
||||
`TYPESCRIPT_DEFAULT_STYLE` from your Super-linter configuration.
|
||||
|
||||
## Upgrade from v5 to v6
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# shellcheck disable=SC2034 # Disable ununsed variables warning because we
|
||||
# source this script and use these variables as globals
|
||||
|
||||
# Load linter commands options so we don't need to load it every time we source
|
||||
# source this file
|
||||
# shellcheck source=/dev/null
|
||||
source /action/lib/globals/linterCommandsOptions.sh
|
||||
|
||||
##########################
|
||||
# Define linter commands #
|
||||
##########################
|
||||
|
||||
# If there's no input argument, parallel adds a default {} at the end of the command.
|
||||
# In a few cases, such as ANSIBLE and GO_MODULES,
|
||||
# Consume the input before running the command because we need the input
|
||||
# to set the working directory, but we don't need it appended at the end of the command.
|
||||
# Setting -n 0 would not help in this case, because the input will not be passed
|
||||
# to the --workdir option as well.
|
||||
# shellcheck disable=SC2034 # Variable is referenced in other scripts
|
||||
LINTER_COMMANDS_ARRAY_ANSIBLE=(ansible-lint -c "${ANSIBLE_LINTER_RULES}" "&& echo \"Linted: {}\"")
|
||||
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
|
||||
|
@ -35,12 +36,12 @@ 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 --dry-run)
|
||||
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 whitespace --folder --verify-no-changes --exclude / --include "{/}")
|
||||
LINTER_COMMANDS_ARRAY_CSHARP=(dotnet format whitespace --folder --exclude / --include "{/}")
|
||||
LINTER_COMMANDS_ARRAY_CSS=(stylelint --config "${CSS_LINTER_RULES}")
|
||||
LINTER_COMMANDS_ARRAY_DART=(dart analyze --fatal-infos --fatal-warnings)
|
||||
LINTER_COMMANDS_ARRAY_DOCKERFILE_HADOLINT=(hadolint -c "${DOCKERFILE_HADOLINT_LINTER_RULES}")
|
||||
|
@ -54,16 +55,15 @@ fi
|
|||
LINTER_COMMANDS_ARRAY_GITLEAKS=(gitleaks detect --no-banner --no-git --redact --config "${GITLEAKS_LINTER_RULES}" --verbose --source)
|
||||
LINTER_COMMANDS_ARRAY_GHERKIN=(gherkin-lint -c "${GHERKIN_LINTER_RULES}")
|
||||
LINTER_COMMANDS_ARRAY_GO=(golangci-lint run -c "${GO_LINTER_RULES}" --fast)
|
||||
# Consume the input as we do with ANSIBLE
|
||||
LINTER_COMMANDS_ARRAY_GO_MODULES=(golangci-lint run --allow-parallel-runners -c "${GO_LINTER_RULES}" "&& echo \"Linted: {}\"")
|
||||
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 --dry-run --set-exit-if-changed)
|
||||
LINTER_COMMANDS_ARRAY_GOOGLE_JAVA_FORMAT=(java -jar /usr/bin/google-java-format)
|
||||
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_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)
|
||||
LINTER_COMMANDS_ARRAY_JAVASCRIPT_STANDARD=(standard "${JAVASCRIPT_STANDARD_LINTER_RULES}")
|
||||
LINTER_COMMANDS_ARRAY_JAVASCRIPT_PRETTIER=(prettier --check)
|
||||
LINTER_COMMANDS_ARRAY_JSCPD=(jscpd --config "${JSCPD_LINTER_RULES}")
|
||||
JSCPD_GITIGNORE_OPTION="--gitignore"
|
||||
if [[ "${IGNORE_GITIGNORED_FILES}" == "true" ]]; then
|
||||
|
@ -105,41 +105,105 @@ 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=(pwsh -NoProfile -NoLogo -Command "\"Invoke-ScriptAnalyzer -EnableExit -Settings ${POWERSHELL_LINTER_RULES} -Path '{}'; if (\\\${Error}.Count) { exit 1 }\"")
|
||||
LINTER_COMMANDS_ARRAY_PROTOBUF=(protolint lint --config_path "${PROTOBUF_LINTER_RULES}")
|
||||
LINTER_COMMANDS_ARRAY_PYTHON_BLACK=(black --config "${PYTHON_BLACK_LINTER_RULES}" --diff --check)
|
||||
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 --check --diff --sp "${PYTHON_ISORT_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_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 --check --edition 2015)
|
||||
LINTER_COMMANDS_ARRAY_RUST_2018=(rustfmt --check --edition 2018)
|
||||
LINTER_COMMANDS_ARRAY_RUST_2021=(rustfmt --check --edition 2021)
|
||||
# Consume the input as we do with ANSIBLE
|
||||
LINTER_COMMANDS_ARRAY_RUST_CLIPPY=(cargo-clippy "&& echo \"Linted: {}\"")
|
||||
LINTER_COMMANDS_ARRAY_SCALAFMT=(scalafmt --config "${SCALAFMT_LINTER_RULES}" --test)
|
||||
LINTER_COMMANDS_ARRAY_SHELL_SHFMT=(shfmt -d)
|
||||
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)
|
||||
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}" --check --compact-diff)
|
||||
LINTER_COMMANDS_ARRAY_SNAKEMAKE_SNAKEFMT=(snakefmt --config "${SNAKEMAKE_SNAKEFMT_LINTER_RULES}")
|
||||
LINTER_COMMANDS_ARRAY_STATES=(asl-validator --json-path)
|
||||
LINTER_COMMANDS_ARRAY_SQL=(sql-lint --config "${SQL_LINTER_RULES}")
|
||||
LINTER_COMMANDS_ARRAY_SQLFLUFF=(sqlfluff lint --config "${SQLFLUFF_LINTER_RULES}")
|
||||
LINTER_COMMANDS_ARRAY_SQLFLUFF=(sqlfluff)
|
||||
LINTER_COMMANDS_ARRAY_TEKTON=(tekton-lint)
|
||||
LINTER_COMMANDS_ARRAY_TERRAFORM_FMT=(terraform fmt -check -diff)
|
||||
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)
|
||||
LINTER_COMMANDS_ARRAY_TYPESCRIPT_STANDARD=(ts-standard --parser @typescript-eslint/parser --plugin @typescript-eslint/eslint-plugin --project "${TYPESCRIPT_STANDARD_TSCONFIG_FILE}")
|
||||
LINTER_COMMANDS_ARRAY_TYPESCRIPT_PRETTIER=(prettier --check)
|
||||
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
|
||||
|
||||
function 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."
|
||||
|
||||
if [[ -v "${FIX_MODE_VARIABLE_NAME}" ]]; then
|
||||
debug "${FIX_MODE_VARIABLE_NAME} is set. Check if we need to add check only mode options or fix mode options or commands."
|
||||
|
||||
local FIX_MODE_OPTIONS_REF_VARIABLE_NAME="${LANGUAGE}_FIX_MODE_OPTIONS"
|
||||
local -n FIX_MODE_OPTIONS_REF="${FIX_MODE_OPTIONS_REF_VARIABLE_NAME}"
|
||||
|
||||
local OPTIONS_VARIABLE_NAME="${LANGUAGE}"
|
||||
|
||||
local -n FIX_MODE_REF="${FIX_MODE_VARIABLE_NAME}"
|
||||
if [[ "${FIX_MODE_REF}" == "true" ]]; then
|
||||
debug "Fix mode for ${LANGUAGE} is enabled. Check if ${LANGUAGE} needs options to enable fix mode."
|
||||
OPTIONS_VARIABLE_NAME="${OPTIONS_VARIABLE_NAME}_FIX_MODE_OPTIONS"
|
||||
else
|
||||
debug "Fix mode for ${LANGUAGE} is not enabled. Check if ${LANGUAGE} needs options to enable check mode."
|
||||
OPTIONS_VARIABLE_NAME="${OPTIONS_VARIABLE_NAME}_CHECK_ONLY_MODE_OPTIONS"
|
||||
fi
|
||||
|
||||
local -a OPTIONS_TO_ADD_ARRAY
|
||||
OPTIONS_TO_ADD_ARRAY=()
|
||||
if [[ -v "${OPTIONS_VARIABLE_NAME}" ]]; then
|
||||
local -n MODE_OPTIONS="${OPTIONS_VARIABLE_NAME}"
|
||||
debug "${!MODE_OPTIONS} is defined. Contents: ${MODE_OPTIONS[*]}"
|
||||
OPTIONS_TO_ADD_ARRAY=("${MODE_OPTIONS[@]}")
|
||||
unset -n MODE_OPTIONS
|
||||
else
|
||||
debug "There are no options or commands for check only mode or fix mode to add at the end of the command for ${LANGUAGE}"
|
||||
fi
|
||||
|
||||
local -n LINTER_COMMAND_ARRAY="LINTER_COMMANDS_ARRAY_${LANGUAGE}"
|
||||
debug "Load command for ${LANGUAGE}: ${!LINTER_COMMAND_ARRAY}. Contents: ${LINTER_COMMAND_ARRAY[*]}"
|
||||
if [[ "${#OPTIONS_TO_ADD_ARRAY[@]}" -gt 0 ]]; then
|
||||
debug "There are ${#OPTIONS_TO_ADD_ARRAY[@]} options to add at the end of the command for ${LANGUAGE}: ${OPTIONS_TO_ADD_ARRAY[*]}"
|
||||
LINTER_COMMAND_ARRAY=("${LINTER_COMMAND_ARRAY[@]}" "${OPTIONS_TO_ADD_ARRAY[@]}")
|
||||
debug "Add options at the end of the command for ${LANGUAGE}. Result: ${LINTER_COMMAND_ARRAY[*]}"
|
||||
else
|
||||
debug "${LANGUAGE} doesn't need any further options or commands for fix mode or check mode."
|
||||
fi
|
||||
|
||||
debug "Completed the initialization of linter command for ${LANGUAGE}. Result: ${LINTER_COMMAND_ARRAY[*]}"
|
||||
|
||||
unset -n LINTER_COMMAND_ARRAY
|
||||
unset -n FIX_MODE_REF
|
||||
unset -n FIX_MODE_OPTIONS_REF
|
||||
else
|
||||
debug "${FIX_MODE_VARIABLE_NAME} is not set. Don't add check only mode options or fix mode options or commands for ${LANGUAGE}."
|
||||
fi
|
||||
}
|
||||
|
||||
function InitInputConsumeCommands() {
|
||||
LINTER_COMMANDS_ARRAY_ANSIBLE+=("${INPUT_CONSUME_COMMAND[@]}")
|
||||
LINTER_COMMANDS_ARRAY_GO_MODULES+=("${INPUT_CONSUME_COMMAND[@]}")
|
||||
LINTER_COMMANDS_ARRAY_RUST_CLIPPY+=("${INPUT_CONSUME_COMMAND[@]}")
|
||||
}
|
||||
|
||||
function InitPowerShellCommand() {
|
||||
debug "PowerShell command before initialization: ${LINTER_COMMANDS_ARRAY_POWERSHELL[*]}"
|
||||
LINTER_COMMANDS_ARRAY_POWERSHELL=(pwsh -NoProfile -NoLogo -Command "\"${LINTER_COMMANDS_ARRAY_POWERSHELL[*]}; if (\\\${Error}.Count) { exit 1 }\"")
|
||||
debug "PowerShell command after initialization: ${LINTER_COMMANDS_ARRAY_POWERSHELL[*]}"
|
||||
}
|
||||
|
|
|
@ -140,6 +140,51 @@ function ValidateValidationVariables() {
|
|||
done
|
||||
}
|
||||
|
||||
function ValidateCheckModeAndFixModeVariables() {
|
||||
for LANGUAGE in "${LANGUAGE_ARRAY[@]}"; do
|
||||
local FIX_MODE_OPTIONS_VARIABLE_NAME="${LANGUAGE}_FIX_MODE_OPTIONS"
|
||||
local CHECK_ONLY_MODE_OPTIONS_VARIABLE_NAME="${LANGUAGE}_CHECK_ONLY_MODE_OPTIONS"
|
||||
local FIX_MODE_VARIABLE_NAME="FIX_${LANGUAGE}"
|
||||
debug "Check if ${LANGUAGE} supports fix mode by checking if ${FIX_MODE_OPTIONS_VARIABLE_NAME}, ${CHECK_ONLY_MODE_OPTIONS_VARIABLE_NAME}, or both variables are set."
|
||||
if [[ -v "${FIX_MODE_OPTIONS_VARIABLE_NAME}" ]] ||
|
||||
[[ -v "${CHECK_ONLY_MODE_OPTIONS_VARIABLE_NAME}" ]]; then
|
||||
debug "Assuming that ${LANGUAGE} supports fix mode because ${FIX_MODE_OPTIONS_VARIABLE_NAME}, ${CHECK_ONLY_MODE_OPTIONS_VARIABLE_NAME}, or both variables are set."
|
||||
|
||||
local -n FIX_MODE_REF="${FIX_MODE_VARIABLE_NAME}"
|
||||
if [[ -n "${FIX_MODE_REF:-}" ]]; then
|
||||
debug "The configuration provided a value for ${FIX_MODE_VARIABLE_NAME}: ${FIX_MODE_REF}"
|
||||
else
|
||||
FIX_MODE_REF="false"
|
||||
debug "The configuration didn't provide a value for ${FIX_MODE_VARIABLE_NAME} for ${LANGUAGE}. Setting it to: ${FIX_MODE_REF}"
|
||||
fi
|
||||
|
||||
# TODO: After refactoring ValidateBooleanVariable to return an error instead
|
||||
# of exiting the whole program, add a test case for when ValidateBooleanVariable fails
|
||||
ValidateBooleanVariable "${!FIX_MODE_REF}" "${FIX_MODE_REF}"
|
||||
|
||||
local -n VALIDATE_MODE_REF="VALIDATE_${LANGUAGE}"
|
||||
|
||||
if [[ "${FIX_MODE_REF}" == "true" ]] && [[ "${VALIDATE_MODE_REF}" == "false" ]]; then
|
||||
error "Cannot set ${!FIX_MODE_REF} to ${FIX_MODE_REF} when ${!VALIDATE_MODE_REF} is ${VALIDATE_MODE_REF}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
export FIX_MODE_REF
|
||||
else
|
||||
debug "Assuming that ${LANGUAGE} doesn't support fix mode because it doesn't have ${FIX_MODE_OPTIONS_VARIABLE_NAME}, nor ${CHECK_ONLY_MODE_OPTIONS_VARIABLE_NAME} variables defined."
|
||||
if [[ -v "${FIX_MODE_VARIABLE_NAME}" ]]; then
|
||||
error "The configuration provided a value for ${FIX_MODE_VARIABLE_NAME} but it's not supported for ${LANGUAGE}"
|
||||
return 1
|
||||
else
|
||||
debug "The configuration didn't provide a value for ${FIX_MODE_VARIABLE_NAME} for ${LANGUAGE}"
|
||||
fi
|
||||
fi
|
||||
|
||||
unset -n FIX_MODE_REF
|
||||
unset -n VALIDATE_MODE_REF
|
||||
done
|
||||
}
|
||||
|
||||
function CheckIfGitBranchExists() {
|
||||
local BRANCH_NAME="${1}"
|
||||
debug "Check if the ${BRANCH_NAME} branch exists in ${GITHUB_WORKSPACE}"
|
||||
|
|
|
@ -142,6 +142,16 @@ function LintCodebase() {
|
|||
|
||||
# shellcheck source=/dev/null
|
||||
source /action/lib/functions/linterCommands.sh
|
||||
# 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}"
|
||||
fi
|
||||
InitInputConsumeCommands
|
||||
|
||||
if [[ "${FILE_TYPE}" == "POWERSHELL" ]]; then
|
||||
debug "Language: ${FILE_TYPE}. Initialize PowerShell command"
|
||||
InitPowerShellCommand
|
||||
fi
|
||||
|
||||
local -n LINTER_COMMAND_ARRAY
|
||||
LINTER_COMMAND_ARRAY="LINTER_COMMANDS_ARRAY_${FILE_TYPE}"
|
||||
|
|
75
lib/globals/linterCommandsOptions.sh
Executable file
75
lib/globals/linterCommandsOptions.sh
Executable file
|
@ -0,0 +1,75 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# shellcheck disable=SC2034 # Disable ununsed variables warning because we
|
||||
# source this script and use these variables as globals
|
||||
|
||||
# "check only" mode options for linters that that we reuse across several languages
|
||||
PRETTIER_CHECK_ONLY_MODE_OPTIONS=(--check)
|
||||
RUSTFMT_CHECK_ONLY_MODE_OPTIONS=(--check)
|
||||
|
||||
# Define configuration options to enable "check only" mode.
|
||||
# Some linters and formatters only support a "check only" mode so there's no
|
||||
# need to define a "check only" mode option for those.
|
||||
CLANG_FORMAT_CHECK_ONLY_MODE_OPTIONS=(--dry-run)
|
||||
CSHARP_CHECK_ONLY_MODE_OPTIONS=(--verify-no-changes)
|
||||
GOOGLE_JAVA_FORMAT_CHECK_ONLY_MODE_OPTIONS=(--dry-run --set-exit-if-changed)
|
||||
JAVASCRIPT_PRETTIER_CHECK_ONLY_MODE_OPTIONS=("${PRETTIER_CHECK_ONLY_MODE_OPTIONS[@]}")
|
||||
PYTHON_BLACK_CHECK_ONLY_MODE_OPTIONS=(--diff --check)
|
||||
PYTHON_ISORT_CHECK_ONLY_MODE_OPTIONS=(--diff --check)
|
||||
RUST_2015_CHECK_ONLY_MODE_OPTIONS=("${RUSTFMT_CHECK_ONLY_MODE_OPTIONS[@]}")
|
||||
RUST_2018_CHECK_ONLY_MODE_OPTIONS=("${RUSTFMT_CHECK_ONLY_MODE_OPTIONS[@]}")
|
||||
RUST_2021_CHECK_ONLY_MODE_OPTIONS=("${RUSTFMT_CHECK_ONLY_MODE_OPTIONS[@]}")
|
||||
SCALAFMT_CHECK_ONLY_MODE_OPTIONS=(--test)
|
||||
SHELL_SHFMT_CHECK_ONLY_MODE_OPTIONS=(--diff)
|
||||
SNAKEMAKE_SNAKEFMT_CHECK_ONLY_MODE_OPTIONS=(--check --compact-diff)
|
||||
SQLFLUFF_CHECK_ONLY_MODE_OPTIONS=(lint)
|
||||
TERRAFORM_FMT_CHECK_ONLY_MODE_OPTIONS=(-check -diff)
|
||||
TYPESCRIPT_PRETTIER_CHECK_ONLY_MODE_OPTIONS=("${PRETTIER_CHECK_ONLY_MODE_OPTIONS[@]}")
|
||||
|
||||
# Fix mode options for linters that that we reuse across several languages
|
||||
ESLINT_FIX_MODE_OPTIONS=(--fix)
|
||||
GOLANGCI_LINT_FIX_MODE_OPTIONS=(--fix)
|
||||
PRETTIER_FIX_MODE_OPTIONS=(--write)
|
||||
STANDARD_FIX_MODE_OPTIONS=(--fix)
|
||||
|
||||
# Define configuration options to enable "fix mode".
|
||||
# Not all linters and formatters support this.
|
||||
ANSIBLE_FIX_MODE_OPTIONS=(--fix)
|
||||
CSS_FIX_MODE_OPTIONS=(--fix)
|
||||
ENV_FIX_MODE_OPTIONS=(fix)
|
||||
GO_FIX_MODE_OPTIONS=("${GOLANGCI_LINT_FIX_MODE_OPTIONS[@]}")
|
||||
GO_MODULES_FIX_MODE_OPTIONS=("${GOLANGCI_LINT_FIX_MODE_OPTIONS[@]}")
|
||||
GROOVY_FIX_MODE_OPTIONS=(--fix)
|
||||
JAVASCRIPT_ES_FIX_MODE_OPTIONS=("${ESLINT_FIX_MODE_OPTIONS[@]}")
|
||||
JAVASCRIPT_PRETTIER_FIX_MODE_OPTIONS=("${PRETTIER_FIX_MODE_OPTIONS[@]}")
|
||||
JAVASCRIPT_STANDARD_FIX_MODE_OPTIONS=("${STANDARD_FIX_MODE_OPTIONS[@]}")
|
||||
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)
|
||||
POWERSHELL_FIX_MODE_OPTIONS=(-Fix)
|
||||
PROTOBUF_FIX_MODE_OPTIONS=(-fix)
|
||||
PYTHON_RUFF_FIX_MODE_OPTIONS=(--fix)
|
||||
RUBY_FIX_MODE_OPTIONS=(--autocorrect)
|
||||
RUST_CLIPPY_FIX_MODE_OPTIONS=(--fix)
|
||||
SHELL_SHFMT_FIX_MODE_OPTIONS=(--write)
|
||||
SQLFLUFF_FIX_MODE_OPTIONS=(fix)
|
||||
TSX_FIX_MODE_OPTIONS=("${ESLINT_FIX_MODE_OPTIONS[@]}")
|
||||
TYPESCRIPT_ES_FIX_MODE_OPTIONS=("${ESLINT_FIX_MODE_OPTIONS[@]}")
|
||||
TYPESCRIPT_PRETTIER_FIX_MODE_OPTIONS=("${PRETTIER_FIX_MODE_OPTIONS[@]}")
|
||||
TYPESCRIPT_STANDARD_FIX_MODE_OPTIONS=("${STANDARD_FIX_MODE_OPTIONS[@]}")
|
||||
|
||||
# sqlfluff is a special case because it needs a different subcommand and
|
||||
# subcommand options
|
||||
SQLFLUFF_SHARED_SUBCOMMAND_OPTIONS=(--config "${SQLFLUFF_LINTER_RULES}")
|
||||
SQLFLUFF_CHECK_ONLY_MODE_OPTIONS+=("${SQLFLUFF_SHARED_SUBCOMMAND_OPTIONS[@]}")
|
||||
SQLFLUFF_FIX_MODE_OPTIONS+=("${SQLFLUFF_SHARED_SUBCOMMAND_OPTIONS[@]}")
|
||||
|
||||
# If there's no input argument, GNU Parallel adds a default {} at the end of the
|
||||
# command it runs. In a few cases, such as ANSIBLE, GO_MODULES, and RUST_CLIPPY,
|
||||
# consume the {} element by artifically adding it to the command to run because
|
||||
# we need the input to set the working directory, but we don't need it appended
|
||||
# at the end of the command.
|
||||
# Setting the -n 0 GNU Parallel would not help in this case, because the input
|
||||
# will not be passed to the --workdir option as well.
|
||||
INPUT_CONSUME_COMMAND=("&& echo \"Linted: {}\"")
|
|
@ -788,6 +788,18 @@ done
|
|||
# Load rules for special cases
|
||||
GetStandardRules "javascript"
|
||||
|
||||
#############################################################################
|
||||
# Validate the environment that depends on linter rules variables being set #
|
||||
#############################################################################
|
||||
|
||||
# We need the variables defined in linterCommandsOptions to initialize FIX_....
|
||||
# variables.
|
||||
# shellcheck source=/dev/null
|
||||
source /action/lib/globals/linterCommandsOptions.sh
|
||||
if ! ValidateCheckModeAndFixModeVariables; then
|
||||
fatal "Error while validating the configuration fix mode for linters that support that"
|
||||
fi
|
||||
|
||||
#################################
|
||||
# Check for SSL cert and update #
|
||||
#################################
|
||||
|
|
|
@ -475,6 +475,7 @@ control "super-linter-validate-files" do
|
|||
"/action/lib/functions/validation.sh",
|
||||
"/action/lib/functions/worker.sh",
|
||||
"/action/lib/globals/languages.sh",
|
||||
"/action/lib/globals/linterCommandsOptions.sh",
|
||||
"/action/lib/globals/linterRules.sh",
|
||||
"/action/lib/.automation/actionlint.yml",
|
||||
"/action/lib/.automation/.ansible-lint.yml",
|
||||
|
|
|
@ -4,6 +4,9 @@ set -o errexit
|
|||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
source "test/testUtils.sh"
|
||||
|
||||
# Default log level
|
||||
# shellcheck disable=SC2034
|
||||
LOG_LEVEL="DEBUG"
|
||||
|
@ -39,6 +42,11 @@ for LANGUAGE in "${LANGUAGE_ARRAY_FOR_LINTER_RULES[@]}"; do
|
|||
done
|
||||
ValidateValidationVariables
|
||||
|
||||
# Now we can load linter command options because they have
|
||||
# dependencies on linter rules
|
||||
# shellcheck source=/dev/null
|
||||
source /action/lib/globals/linterCommandsOptions.sh
|
||||
|
||||
# The slim image might not have this variable defined
|
||||
if [[ ! -v ARM_TTK_PSD1 ]]; then
|
||||
ARM_TTK_PSD1="/usr/lib/microsoft/arm-ttk/arm-ttk.psd1"
|
||||
|
@ -51,6 +59,13 @@ fi
|
|||
# shellcheck source=/dev/null
|
||||
source "lib/functions/linterCommands.sh"
|
||||
|
||||
# Initialize the variables we're going to use to verify tests before running tests
|
||||
# because some tests modify LINTER_COMMANDS_xxx variables
|
||||
BASE_LINTER_COMMANDS_ARRAY_ANSIBLE=("${LINTER_COMMANDS_ARRAY_ANSIBLE[@]}")
|
||||
BASE_LINTER_COMMANDS_ARRAY_GO_MODULES=("${LINTER_COMMANDS_ARRAY_GO_MODULES[@]}")
|
||||
BASE_LINTER_COMMANDS_ARRAY_JSCPD=("${LINTER_COMMANDS_ARRAY_JSCPD[@]}")
|
||||
BASE_LINTER_COMMANDS_ARRAY_RUST_CLIPPY=("${LINTER_COMMANDS_ARRAY_RUST_CLIPPY[@]}")
|
||||
|
||||
function LinterCommandPresenceTest() {
|
||||
local FUNCTION_NAME
|
||||
FUNCTION_NAME="${FUNCNAME[0]}"
|
||||
|
@ -83,10 +98,10 @@ function IgnoreGitIgnoredFilesJscpdCommandTest() {
|
|||
# shellcheck source=/dev/null
|
||||
source "lib/functions/linterCommands.sh"
|
||||
|
||||
EXPECTED_COMMAND=("${LINTER_COMMANDS_ARRAY_JSCPD[@]}" "${JSCPD_GITIGNORE_OPTION}")
|
||||
EXPECTED_COMMAND=("${BASE_LINTER_COMMANDS_ARRAY_JSCPD[@]}" "${JSCPD_GITIGNORE_OPTION}")
|
||||
|
||||
if [[ "${LINTER_COMMANDS_ARRAY_JSCPD[*]}" == "${EXPECTED_COMMAND[*]}" ]]; then
|
||||
debug "Command (${LINTER_COMMANDS_ARRAY_JSCPD[*]}) matches with the expected one (${EXPECTED_COMMAND[*]})"
|
||||
if ! AssertArraysElementsContentMatch "LINTER_COMMANDS_ARRAY_JSCPD" "EXPECTED_COMMAND"; then
|
||||
fatal "${FUNCTION_NAME} test failed"
|
||||
fi
|
||||
|
||||
notice "${FUNCTION_NAME} PASS"
|
||||
|
@ -97,19 +112,138 @@ function JscpdCommandTest() {
|
|||
FUNCTION_NAME="${FUNCNAME[0]}"
|
||||
info "${FUNCTION_NAME} start"
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
IGNORE_GITIGNORED_FILES="false"
|
||||
|
||||
# Source the file again so it accounts for modifications
|
||||
# shellcheck source=/dev/null
|
||||
source "lib/functions/linterCommands.sh"
|
||||
|
||||
EXPECTED_COMMAND=(jscpd --config "${JSCPD_LINTER_RULES}")
|
||||
# shellcheck disable=SC2034
|
||||
EXPECTED_COMMAND=("${BASE_LINTER_COMMANDS_ARRAY_JSCPD[@]}")
|
||||
|
||||
if [[ "${LINTER_COMMANDS_ARRAY_JSCPD[*]}" == "${EXPECTED_COMMAND[*]}" ]]; then
|
||||
debug "Command (${LINTER_COMMANDS_ARRAY_JSCPD[*]}) matches with the expected one (${EXPECTED_COMMAND[*]})"
|
||||
if ! AssertArraysElementsContentMatch "LINTER_COMMANDS_ARRAY_JSCPD" "EXPECTED_COMMAND"; then
|
||||
fatal "${FUNCTION_NAME} test failed"
|
||||
fi
|
||||
|
||||
notice "${FUNCTION_NAME} PASS"
|
||||
}
|
||||
|
||||
function InitInputConsumeCommandsTest() {
|
||||
local FUNCTION_NAME
|
||||
FUNCTION_NAME="${FUNCNAME[0]}"
|
||||
info "${FUNCTION_NAME} start"
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
EXPECTED_LINTER_COMMANDS_ARRAY_ANSIBLE=("${BASE_LINTER_COMMANDS_ARRAY_ANSIBLE[@]}" "${INPUT_CONSUME_COMMAND[@]}")
|
||||
# shellcheck disable=SC2034
|
||||
EXPECTED_LINTER_COMMANDS_ARRAY_GO_MODULES=("${BASE_LINTER_COMMANDS_ARRAY_GO_MODULES[@]}" "${INPUT_CONSUME_COMMAND[@]}")
|
||||
# shellcheck disable=SC2034
|
||||
EXPECTED_LINTER_COMMANDS_ARRAY_RUST_CLIPPY=("${BASE_LINTER_COMMANDS_ARRAY_RUST_CLIPPY[@]}" "${INPUT_CONSUME_COMMAND[@]}")
|
||||
|
||||
if ! InitInputConsumeCommands; then
|
||||
fatal "Error while initializing GNU parallel input consume commands"
|
||||
fi
|
||||
|
||||
if ! AssertArraysElementsContentMatch "LINTER_COMMANDS_ARRAY_ANSIBLE" "EXPECTED_LINTER_COMMANDS_ARRAY_ANSIBLE"; then
|
||||
fatal "${FUNCTION_NAME} test failed"
|
||||
fi
|
||||
|
||||
if ! AssertArraysElementsContentMatch "LINTER_COMMANDS_ARRAY_GO_MODULES" "EXPECTED_LINTER_COMMANDS_ARRAY_GO_MODULES"; then
|
||||
fatal "${FUNCTION_NAME} test failed"
|
||||
fi
|
||||
|
||||
if ! AssertArraysElementsContentMatch "LINTER_COMMANDS_ARRAY_RUST_CLIPPY" "EXPECTED_LINTER_COMMANDS_ARRAY_RUST_CLIPPY"; then
|
||||
fatal "${FUNCTION_NAME} test failed"
|
||||
fi
|
||||
|
||||
notice "${FUNCTION_NAME} PASS"
|
||||
}
|
||||
|
||||
function InitFixModeOptionsAndCommandsTest() {
|
||||
local FUNCTION_NAME
|
||||
FUNCTION_NAME="${FUNCNAME[0]}"
|
||||
info "${FUNCTION_NAME} start"
|
||||
|
||||
LANGUAGE_ARRAY=("A" "B" "C")
|
||||
|
||||
# Test a command that has only fix mode options to add
|
||||
# shellcheck disable=SC2034
|
||||
A_FIX_MODE_OPTIONS=(--fixA)
|
||||
|
||||
# Test a command that has only check only mode options to add
|
||||
# shellcheck disable=SC2034
|
||||
B_CHECK_ONLY_MODE_TEST=(--checkB)
|
||||
|
||||
# Test a command that has both fix mode and check only mode options to add
|
||||
# shellcheck disable=SC2034
|
||||
C_CHECK_ONLY_MODE_TEST=(--checkC)
|
||||
# shellcheck disable=SC2034
|
||||
C_FIX_MODE_OPTIONS=(--fixC)
|
||||
|
||||
for LANGUAGE in "${LANGUAGE_ARRAY[@]}"; do
|
||||
local -n FIX_LANGUAGE_VARIABLE_NAME="FIX_${LANGUAGE}"
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
FIX_LANGUAGE_VARIABLE_NAME="true"
|
||||
|
||||
local -n LINTER_COMMANDS_ARRAY="LINTER_COMMANDS_ARRAY_${LANGUAGE}"
|
||||
# shellcheck disable=SC2034
|
||||
LINTER_COMMANDS_ARRAY=("LINTER_COMMANDS_ARRAY_FOR_LINTER_${LANGUAGE}_FIX_MODE_TEST")
|
||||
EXPECTED_LINTER_COMMANDS_ARRAY_FIX_MODE=("${LINTER_COMMANDS_ARRAY[@]}")
|
||||
local FIX_MODE_OPTIONS_VARIABLE_NAME="${LANGUAGE}_FIX_MODE_OPTIONS"
|
||||
if [[ -v "${FIX_MODE_OPTIONS_VARIABLE_NAME}" ]]; then
|
||||
local -n FIX_MODE_OPTIONS="${FIX_MODE_OPTIONS_VARIABLE_NAME}"
|
||||
# shellcheck disable=SC2034
|
||||
EXPECTED_LINTER_COMMANDS_ARRAY_FIX_MODE+=("${FIX_MODE_OPTIONS[@]}")
|
||||
unset -n FIX_MODE_OPTIONS
|
||||
fi
|
||||
if ! InitFixModeOptionsAndCommands "${LANGUAGE}"; then
|
||||
fatal "InitFixModeOptionsAndCommands for ${LANGUAGE} should have passed validation"
|
||||
fi
|
||||
if ! AssertArraysElementsContentMatch "LINTER_COMMANDS_ARRAY" "EXPECTED_LINTER_COMMANDS_ARRAY_FIX_MODE"; then
|
||||
fatal "${FUNCTION_NAME} ${!FIX_LANGUAGE_VARIABLE_NAME}: ${FIX_LANGUAGE_VARIABLE_NAME} test failed"
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
FIX_LANGUAGE_VARIABLE_NAME="false"
|
||||
LINTER_COMMANDS_ARRAY=("LINTER_COMMANDS_ARRAY_FOR_LINTER_${LANGUAGE}_CHECK_ONLY_MODE_TEST")
|
||||
# shellcheck disable=SC2034
|
||||
EXPECTED_LINTER_COMMANDS_ARRAY_CHECK_ONLY_MODE=("${LINTER_COMMANDS_ARRAY[@]}")
|
||||
local CHECK_ONLY_MODE_OPTIONS_VARIABLE_NAME="${LANGUAGE}_CHECK_ONLY_MODE_OPTIONS"
|
||||
if [[ -v "${CHECK_ONLY_MODE_OPTIONS_VARIABLE_NAME}" ]]; then
|
||||
local -n CHECK_ONLY_MODE_OPTIONS="${CHECK_ONLY_MODE_OPTIONS_VARIABLE_NAME}"
|
||||
# shellcheck disable=SC2034
|
||||
EXPECTED_LINTER_COMMANDS_ARRAY_CHECK_ONLY_MODE+=("${CHECK_ONLY_MODE_OPTIONS[@]}")
|
||||
unset -n CHECK_ONLY_MODE_OPTIONS
|
||||
fi
|
||||
if ! InitFixModeOptionsAndCommands "${LANGUAGE}"; then
|
||||
fatal "InitFixModeOptionsAndCommands for ${LANGUAGE} should have passed validation"
|
||||
fi
|
||||
if ! AssertArraysElementsContentMatch "LINTER_COMMANDS_ARRAY" "EXPECTED_LINTER_COMMANDS_ARRAY_CHECK_ONLY_MODE"; then
|
||||
fatal "${FUNCTION_NAME} ${!FIX_LANGUAGE_VARIABLE_NAME}: ${FIX_LANGUAGE_VARIABLE_NAME} test failed"
|
||||
fi
|
||||
|
||||
unset -n FIX_LANGUAGE_VARIABLE_NAME
|
||||
unset -n LINTER_COMMANDS_ARRAY
|
||||
done
|
||||
|
||||
notice "${FUNCTION_NAME} PASS"
|
||||
}
|
||||
|
||||
function InitPowerShellCommandTest() {
|
||||
# shellcheck disable=SC2034
|
||||
EXPECTED_LINTER_COMMANDS_ARRAY_POWERSHELL=(pwsh -NoProfile -NoLogo -Command "\"${LINTER_COMMANDS_ARRAY_POWERSHELL[*]}; if (\\\${Error}.Count) { exit 1 }\"")
|
||||
InitPowerShellCommand
|
||||
|
||||
if ! AssertArraysElementsContentMatch "LINTER_COMMANDS_ARRAY_POWERSHELL" "EXPECTED_LINTER_COMMANDS_ARRAY_POWERSHELL"; then
|
||||
fatal "${FUNCTION_NAME} test failed"
|
||||
fi
|
||||
}
|
||||
|
||||
LinterCommandPresenceTest
|
||||
IgnoreGitIgnoredFilesJscpdCommandTest
|
||||
JscpdCommandTest
|
||||
InitInputConsumeCommandsTest
|
||||
InitFixModeOptionsAndCommandsTest
|
||||
InitPowerShellCommandTest
|
||||
|
|
|
@ -363,7 +363,7 @@ function ValidationVariablesExportTest() {
|
|||
for LANGUAGE in "${LANGUAGE_ARRAY[@]}"; do
|
||||
local -n VALIDATE_LANGUAGE
|
||||
VALIDATE_LANGUAGE="VALIDATE_${LANGUAGE}"
|
||||
debug "VALIDATE_LANGUAGE (${LANGUAGE}) variable attributes: ${VALIDATE_LANGUAGE@a}"
|
||||
debug "VALIDATE_LANGUAGE (Language: ${LANGUAGE}) variable attributes: ${VALIDATE_LANGUAGE@a}"
|
||||
if [[ "${VALIDATE_LANGUAGE@a}" == *x* ]]; then
|
||||
info "VALIDATE_LANGUAGE for ${LANGUAGE} is exported as expected"
|
||||
else
|
||||
|
@ -375,6 +375,130 @@ function ValidationVariablesExportTest() {
|
|||
notice "${FUNCTION_NAME} PASS"
|
||||
}
|
||||
|
||||
function ValidateCheckModeAndFixModeVariablesTest() {
|
||||
local FUNCTION_NAME
|
||||
FUNCTION_NAME="${FUNCNAME[0]}"
|
||||
info "${FUNCTION_NAME} start"
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
LANGUAGE_ARRAY=('A' 'B' 'C' 'D')
|
||||
# shellcheck disable=SC2034
|
||||
A_FIX_MODE_OPTIONS=(--fixA)
|
||||
# shellcheck disable=SC2034
|
||||
A_CHECK_ONLY_MODE_OPTIONS=(--checkA)
|
||||
# shellcheck disable=SC2034
|
||||
B_FIX_MODE_OPTIONS=(--fixB)
|
||||
# shellcheck disable=SC2034
|
||||
C_CHECK_ONLY_MODE_OPTIONS=(--checkC)
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
VALIDATE_A="true"
|
||||
# shellcheck disable=SC2034
|
||||
VALIDATE_B="true"
|
||||
# shellcheck disable=SC2034
|
||||
VALIDATE_C="true"
|
||||
# shellcheck disable=SC2034
|
||||
FIX_B="true"
|
||||
|
||||
if ! ValidateCheckModeAndFixModeVariables; then
|
||||
fatal "Error while validating fix mode variables"
|
||||
fi
|
||||
|
||||
if [[ -v FIX_A ]]; then
|
||||
debug "FIX_A variable is defined as expected"
|
||||
else
|
||||
fatal "FIX_A variable should have been defined"
|
||||
fi
|
||||
|
||||
EXPECTED_FIX_A="false"
|
||||
if [[ "${FIX_A}" == "${EXPECTED_FIX_A}" ]]; then
|
||||
debug "FIX_A variable has the expected value: ${FIX_A}"
|
||||
else
|
||||
fatal "FIX_A (${FIX_A}) doesn't match with the expected value: ${EXPECTED_FIX_A}"
|
||||
fi
|
||||
|
||||
if [[ -v FIX_C ]]; then
|
||||
debug "FIX_C variable is defined as expected"
|
||||
else
|
||||
fatal "FIX_C variable should have been defined"
|
||||
fi
|
||||
|
||||
EXPECTED_FIX_C="false"
|
||||
if [[ "${FIX_C}" == "${EXPECTED_FIX_C}" ]]; then
|
||||
debug "FIX_C variable has the expected value: ${FIX_C}"
|
||||
else
|
||||
fatal "FIX_C (${FIX_C}) doesn't match with the expected value: ${EXPECTED_FIX_C}"
|
||||
fi
|
||||
|
||||
# No need to check if FIX_B is defined because we defined it earlier in this test function
|
||||
|
||||
if [[ ! -v FIX_D ]]; then
|
||||
debug "FIX_D is not defined as expected"
|
||||
else
|
||||
fatal "FIX_D variable should have not been defined"
|
||||
fi
|
||||
|
||||
debug "FIX_A variable attributes: ${FIX_A@a}"
|
||||
if [[ "${FIX_A@a}" == *x* ]]; then
|
||||
debug "FIX_A is exported as expected"
|
||||
else
|
||||
fatal "FIX_A should have been exported"
|
||||
fi
|
||||
|
||||
debug "FIX_B variable attributes: ${FIX_B@a}"
|
||||
if [[ "${FIX_B@a}" == *x* ]]; then
|
||||
debug "FIX_B is exported as expected"
|
||||
else
|
||||
fatal "FIX_B should have been exported"
|
||||
fi
|
||||
|
||||
debug "FIX_C variable attributes: ${FIX_C@a}"
|
||||
if [[ "${FIX_C@a}" == *x* ]]; then
|
||||
debug "FIX_C is exported as expected"
|
||||
else
|
||||
fatal "FIX_C should have been exported"
|
||||
fi
|
||||
|
||||
unset FIX_A
|
||||
unset FIX_B
|
||||
unset FIX_C
|
||||
unset FIX_D
|
||||
unset VALIDATE_A
|
||||
unset VALIDATE_B
|
||||
unset VALIDATE_C
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
LANGUAGE_ARRAY=('E')
|
||||
# shellcheck disable=SC2034
|
||||
E_FIX_MODE_OPTIONS=(--fixA)
|
||||
FIX_E="true"
|
||||
VALIDATE_E="false"
|
||||
|
||||
if ValidateCheckModeAndFixModeVariables; then
|
||||
fatal "FIX_E (${FIX_E}) and VALIDATE_E (${VALIDATE_E}) should have failed validation"
|
||||
else
|
||||
debug "FIX_E (${FIX_E}) and VALIDATE_E (${VALIDATE_E}) failed validation as expected"
|
||||
fi
|
||||
|
||||
unset FIX_E
|
||||
unset VALIDATE_E
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
LANGUAGE_ARRAY=('F')
|
||||
FIX_F="true"
|
||||
|
||||
if ValidateCheckModeAndFixModeVariables; then
|
||||
fatal "FIX_F (${FIX_F}) should have failed validation when it doesn't support fix mode or check only mode"
|
||||
else
|
||||
debug "FIX_F (${FIX_F}) failed validation as expected when it doesn't support fix mode or check only mode"
|
||||
fi
|
||||
|
||||
unset FIX_F
|
||||
unset VALIDATE_F
|
||||
|
||||
notice "${FUNCTION_NAME} PASS"
|
||||
}
|
||||
|
||||
IsUnsignedIntegerSuccessTest
|
||||
IsUnsignedIntegerFailureTest
|
||||
ValidateDeprecatedVariablesTest
|
||||
|
@ -384,3 +508,4 @@ ValidateFindModeTest
|
|||
ValidateAnsibleDirectoryTest
|
||||
ValidateValidationVariablesTest
|
||||
ValidationVariablesExportTest
|
||||
ValidateCheckModeAndFixModeVariablesTest
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
// file name for tests.
|
||||
// groovylint-disable-next-line ClassNameSameAsFilename
|
||||
class Example {
|
||||
|
||||
static void main(String[] args) {
|
||||
File file = new File("E:/Example.txt")
|
||||
File file = new File('E:/Example.txt')
|
||||
println "The file ${file.absolutePath} has ${file.length()} bytes"
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,9 @@ set -o errexit
|
|||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
source "test/testUtils.sh"
|
||||
|
||||
SUPER_LINTER_TEST_CONTAINER_URL="${1}"
|
||||
TEST_FUNCTION_NAME="${2}"
|
||||
SUPER_LINTER_CONTAINER_IMAGE_TYPE="${3}"
|
||||
|
@ -151,6 +154,48 @@ run_test_case_custom_summary() {
|
|||
SUPER_LINTER_SUMMARY_FILE_NAME="custom-github-step-summary.md"
|
||||
}
|
||||
|
||||
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")
|
||||
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")
|
||||
}
|
||||
|
||||
# Run the test setup function
|
||||
${TEST_FUNCTION_NAME}
|
||||
|
||||
|
@ -316,3 +361,8 @@ for item in "${TEMP_ITEMS_TO_CLEAN[@]}"; do
|
|||
echo "${item} does not exist as expected"
|
||||
fi
|
||||
done
|
||||
|
||||
if ! CheckUnexpectedGitChanges "$(pwd)"; then
|
||||
echo "There are unexpected modifications to the working directory after running tests."
|
||||
exit 1
|
||||
fi
|
||||
|
|
44
test/testUtils.sh
Executable file
44
test/testUtils.sh
Executable file
|
@ -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"
|
||||
|
||||
function AssertArraysElementsContentMatch() {
|
||||
local ARRAY_1_VARIABLE_NAME="${1}"
|
||||
local ARRAY_2_VARIABLE_NAME="${2}"
|
||||
local -n ARRAY_1="${ARRAY_1_VARIABLE_NAME}"
|
||||
local -n ARRAY_2="${ARRAY_2_VARIABLE_NAME}"
|
||||
if [[ "${ARRAY_1[*]}" == "${ARRAY_2[*]}" ]]; then
|
||||
debug "${ARRAY_1_VARIABLE_NAME} (${ARRAY_1[*]}) matches the expected value: ${ARRAY_2[*]}"
|
||||
RETURN_CODE=0
|
||||
else
|
||||
error "${ARRAY_1_VARIABLE_NAME} (${ARRAY_1[*]}) doesn't match the expected value: ${ARRAY_2[*]}"
|
||||
RETURN_CODE=1
|
||||
fi
|
||||
unset -n ARRAY_1
|
||||
unset -n ARRAY_2
|
||||
return ${RETURN_CODE}
|
||||
}
|
||||
|
||||
function CheckUnexpectedGitChanges() {
|
||||
local GIT_REPOSITORY_PATH="${1}"
|
||||
# Check if there are unexpected changes in the working directory:
|
||||
# - Unstaged changes
|
||||
# - Changes that are staged but not committed
|
||||
# - Untracked files and directories
|
||||
if ! git -C "${GIT_REPOSITORY_PATH}" diff --exit-code --quiet ||
|
||||
! git -C "${GIT_REPOSITORY_PATH}" diff --cached --exit-code --quiet ||
|
||||
! git -C "${GIT_REPOSITORY_PATH}" ls-files --others --exclude-standard --directory; then
|
||||
echo "There are unexpected changes in the working directory of the ${GIT_REPOSITORY_PATH} Git repository."
|
||||
git -C "${GIT_REPOSITORY_PATH}" status
|
||||
return 1
|
||||
fi
|
||||
}
|
Loading…
Reference in a new issue