2023-12-12 02:41:41 -05:00
|
|
|
# How to add support for a new tool to super-linter
|
|
|
|
|
2024-09-13 08:37:48 -04:00
|
|
|
If you want to propose a _Pull Request_ to add **new** language support or a new
|
|
|
|
tool, do the following.
|
2023-12-12 02:41:41 -05:00
|
|
|
|
2024-09-13 08:37:48 -04:00
|
|
|
## Update documentation
|
2023-12-12 02:41:41 -05:00
|
|
|
|
2024-09-13 08:37:48 -04:00
|
|
|
- `README.md`
|
2023-12-12 02:41:41 -05:00
|
|
|
|
2024-09-13 08:37:48 -04:00
|
|
|
## Provide test cases
|
2023-12-12 02:41:41 -05:00
|
|
|
|
2024-09-13 08:37:48 -04:00
|
|
|
1. Create the `test/linters/<LANGUAGE_NAME>` 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/<LANGUAGE_NAME>/<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>/<name-of-tool>-bad`. If the tool 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. Update expected summary reports: `test/data/super-linter-summary`.
|
2024-12-20 14:13:16 -05:00
|
|
|
5. If the tool supports check-only mode or fix mode, add the `<LANGUAGE>` to the
|
|
|
|
`LANGUAGES_WITH_FIX_MODE` array in `test/testUtils.sh`
|
2024-09-13 08:37:48 -04:00
|
|
|
|
|
|
|
## Update the test suite
|
|
|
|
|
|
|
|
Update the test suite to check for installed packages, the commands that your
|
|
|
|
new tool needs in the `PATH`, and the expected version command:
|
|
|
|
|
|
|
|
- `test/inspec/super-linter/controls/super_linter.rb`
|
|
|
|
|
|
|
|
## Install the tool
|
2023-12-12 02:41:41 -05:00
|
|
|
|
|
|
|
- Install the tool by pointing to specific package or container image versions:
|
|
|
|
|
2024-10-10 08:24:13 -04:00
|
|
|
- If there are PyPi packages:
|
|
|
|
|
|
|
|
1. Create a text file named `dependencies/python/<name-of-tool>.txt` and
|
|
|
|
list the packages there.
|
|
|
|
1. Add the new virtual environment `bin` directory to the `PATH` in the
|
|
|
|
Super-linter `Dockerfile`, in the `Configure Environment` section.
|
|
|
|
Example:
|
|
|
|
|
|
|
|
```dockerfile
|
|
|
|
ENV PATH="${PATH}:/venvs/<name-of-tool>/bin"
|
|
|
|
```
|
|
|
|
|
2024-10-10 14:40:17 -04:00
|
|
|
1. Add the new dependencies to the `pip` group in the DependaBot
|
|
|
|
configuration file (`.github/dependabot.yaml`).
|
|
|
|
|
2024-09-13 08:37:48 -04:00
|
|
|
- If there are npm packages, update `dependencies/package.json` and
|
|
|
|
`dependencies/package-lock.json`. by adding the new packages.
|
|
|
|
- If there are Ruby Gems, update `dependencies/Gemfile` and
|
|
|
|
`dependencies/Gemfile.lock`
|
2023-12-12 02:41:41 -05:00
|
|
|
- If there are Maven or Java packages:
|
|
|
|
|
|
|
|
1. Create a directory named `dependencies/<name-of-tool>`.
|
2024-09-13 08:37:48 -04:00
|
|
|
2. Create a `dependencies/<name-of-tool>/build.gradle` file with the
|
|
|
|
following contents:
|
2023-12-12 02:41:41 -05:00
|
|
|
|
2024-08-15 04:21:26 -04:00
|
|
|
```gradle
|
|
|
|
repositories {
|
|
|
|
mavenLocal()
|
|
|
|
mavenCentral()
|
|
|
|
}
|
2023-12-12 02:41:41 -05:00
|
|
|
|
2024-08-15 04:21:26 -04:00
|
|
|
// Hold this dependency here so we can get automated updates using DependaBot
|
|
|
|
dependencies {
|
|
|
|
implementation 'your:dependency-here:version'
|
|
|
|
}
|
2023-12-12 02:41:41 -05:00
|
|
|
|
2024-08-15 04:21:26 -04:00
|
|
|
group 'com.github.super-linter'
|
|
|
|
version '1.0.0-SNAPSHOT'
|
|
|
|
```
|
2023-12-12 02:41:41 -05:00
|
|
|
|
2024-09-13 08:37:48 -04:00
|
|
|
3. Update the `dependencies` section in
|
|
|
|
`dependencies/<name-of-tool>/build.gradle` to install your dependencies.
|
2024-10-10 14:40:17 -04:00
|
|
|
|
2023-12-12 02:41:41 -05:00
|
|
|
4. Add the following content to the `Dockerfile`:
|
|
|
|
|
2024-08-15 04:21:26 -04:00
|
|
|
```dockerfile
|
|
|
|
COPY scripts/install-<name-of-tool>.sh /
|
|
|
|
RUN --mount=type=secret,id=GITHUB_TOKEN /<name-of-tool>.sh && rm -rf /<name-of-tool>.sh
|
|
|
|
```
|
2023-12-12 02:41:41 -05:00
|
|
|
|
2024-09-13 08:37:48 -04:00
|
|
|
5. Create `scripts/install-<name-of-tool>.sh`, and implement the logic to
|
|
|
|
install your tool. You get the version of a dependency from
|
|
|
|
`build.gradle`. Example:
|
2023-12-12 02:41:41 -05:00
|
|
|
|
2024-08-15 04:21:26 -04:00
|
|
|
```sh
|
2024-09-27 03:59:31 -04:00
|
|
|
GOOGLE_JAVA_FORMAT_VERSION="$(
|
|
|
|
set -euo pipefail
|
|
|
|
awk -F "[:']" '/google-java-format/ {print $4}' "google-java-format/build.gradle"
|
|
|
|
)"
|
2024-08-15 04:21:26 -04:00
|
|
|
```
|
2023-12-12 02:41:41 -05:00
|
|
|
|
2024-10-10 14:40:17 -04:00
|
|
|
6. Add the new tool dependencies to the DependaBot configuration in the
|
|
|
|
`directories` list and in the `java-gradle` group of the `gradle` package
|
|
|
|
ecosystem.
|
2023-12-12 02:41:41 -05:00
|
|
|
|
|
|
|
- If there is a container (Docker) image:
|
|
|
|
|
|
|
|
1. Add a new build stage to get the image:
|
|
|
|
|
2024-08-15 04:21:26 -04:00
|
|
|
```dockerfile
|
|
|
|
FROM your/image:version as <name-of-tool>
|
|
|
|
```
|
2023-12-12 02:41:41 -05:00
|
|
|
|
2024-09-13 08:37:48 -04:00
|
|
|
1. Copy the necessary binaries and libraries to the relevant locations.
|
|
|
|
Example:
|
2023-12-12 02:41:41 -05:00
|
|
|
|
2024-08-15 04:21:26 -04:00
|
|
|
```sh
|
|
|
|
COPY --from=<name-of-tool> /usr/local/bin/<name-of-command> /usr/bin/
|
|
|
|
```
|
2023-12-12 02:41:41 -05:00
|
|
|
|
2024-10-10 14:40:17 -04:00
|
|
|
1. Add the new dependency to the `docker` group in the DependaBot
|
|
|
|
configuration file.
|
|
|
|
|
2024-09-13 08:37:48 -04:00
|
|
|
## Run the new tool
|
2023-12-12 02:41:41 -05:00
|
|
|
|
|
|
|
- Update the orchestration scripts to run the new tool:
|
|
|
|
|
2024-09-13 08:37:48 -04:00
|
|
|
- `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 tool. To
|
|
|
|
allow for future additions, use a language name and a tool name for the new
|
|
|
|
item. Example: `PYTHON_RUFF`. In the context of this document, to avoid
|
|
|
|
repetitions we reference this new item as `<LANGUAGE_NAME>`.
|
|
|
|
|
|
|
|
- Define the command to invoke the new tool:
|
|
|
|
|
|
|
|
- `lib/functions/linterCommands.sh`: add the command to invoke the tool.
|
|
|
|
Define a new variable: `LINTER_COMMANDS_ARRAY_<LANGUAGE_NAME>`. Example:
|
|
|
|
`LINTER_COMMANDS_ARRAY_GO_MODULES=(golangci-lint run --allow-parallel-runners)`
|
|
|
|
|
|
|
|
- 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
|
2024-08-07 09:36:16 -04:00
|
|
|
configuration provides it. Example:
|
|
|
|
|
2024-08-15 04:21:26 -04:00
|
|
|
```bash
|
|
|
|
<LANGUAGE_NAME>_COMMAND_ARGS="${<LANGUAGE_NAME>_COMMAND_ARGS:-""}"
|
|
|
|
if [ -n "${<LANGUAGE_NAME>_COMMAND_ARGS:-}" ]; then
|
|
|
|
export <LANGUAGE_NAME>_COMMAND_ARGS
|
2024-09-13 08:37:48 -04:00
|
|
|
AddOptionsToCommand "LINTER_COMMANDS_ARRAY_<LANGUAGE_NAME>" "${<LANGUAGE_NAME>_COMMAND_ARGS}"
|
2024-08-15 04:21:26 -04:00
|
|
|
fi
|
|
|
|
```
|
2024-08-07 09:36:16 -04:00
|
|
|
|
2024-09-13 08:37:48 -04:00
|
|
|
- `lib/globals/linterCommandsOptions.sh`: add "check only mode" and "fix
|
|
|
|
linting and formatting issues mode" options if the tool supports it.
|
|
|
|
Super-linter will automatically add them to the command to run the tool.
|
|
|
|
|
|
|
|
- If the tool runs in "fix linting and formatting issues mode" by default,
|
|
|
|
define a new variable with the options to add to the tool command to
|
|
|
|
enable "check only mode":
|
|
|
|
`<LANGUAGE_NAME>_CHECK_ONLY_MODE_OPTIONS=(....)`. Example:
|
|
|
|
`PYTHON_BLACK_CHECK_ONLY_MODE_OPTIONS=(--diff --check)`
|
|
|
|
|
|
|
|
- If the tool runs in "check only mode" by default, define a new variable
|
|
|
|
with the options to add to the tool command to enable "fix linting and
|
|
|
|
formatting issues mode": `<LANGUAGE_NAME>_FIX_MODE_OPTIONS=(...)`.
|
|
|
|
Example: `ANSIBLE_FIX_MODE_OPTIONS=(--fix)`
|
2024-08-07 09:36:16 -04:00
|
|
|
|
2024-09-13 08:37:48 -04:00
|
|
|
- If the tool needs option for both the "check only mode" and the fix
|
|
|
|
mode, define both variables as described in the previous points.
|
2024-08-07 09:36:16 -04:00
|
|
|
|
2024-09-13 08:37:48 -04:00
|
|
|
## Configure the new tool
|
2024-08-07 09:36:16 -04:00
|
|
|
|
2024-09-13 08:37:48 -04:00
|
|
|
If the new tool doesn't support a configuration file search mechanism, update
|
|
|
|
the command to run the new tool to set the path to the configuration file:
|
|
|
|
|
|
|
|
1. Define a new variable in `lib/globals/linterRules.sh`:
|
|
|
|
`<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 configuration
|
|
|
|
file for the new tool. Use one of the default recommended configurationfile
|
|
|
|
names for the new tool. Example:
|
|
|
|
`PYTHON_RUFF_FILE_NAME="${PYTHON_RUFF_CONFIG_FILE:-.ruff.toml}"`.
|
|
|
|
Super-linter automatically initializes the path to the configuration file in
|
|
|
|
the `<LANGUAGE_NAME>_LINTER_RULES` variable using the
|
|
|
|
`<LANGUAGE_NAME>_FILE_NAME`. Example: `PYTHON_RUFF_LINTER_RULES`
|
|
|
|
|
|
|
|
1. Create a new minimal configuration file in the `TEMPLATES` directory.
|
|
|
|
Example: `TEMPLATES/default-config-file-name.conf`.
|
|
|
|
|
|
|
|
1. Update `lib/functions/linterCommands.sh` to set the path to the configuration
|
|
|
|
file path. Example: `htmlhint --config "${HTML_LINTER_RULES}"`
|
|
|
|
|
|
|
|
### Configure the new tool for the Super-linter repository
|
|
|
|
|
|
|
|
If the default configuration of the new tool is unsuitable for the Super-linter
|
|
|
|
repository, create a new configuration file for the new tool using the default
|
|
|
|
filename:
|
|
|
|
|
|
|
|
- If the new tool supports a configuration file search mechanism, create the
|
|
|
|
configuration file in a location where the new tool will find it.
|
|
|
|
|
|
|
|
- If the new tool doesn't support a configuration file search mechanism and you
|
|
|
|
updated the new tool command to set the configuration file path, create the
|
|
|
|
configuration file in the `.github/linters` directory using its default
|
|
|
|
filename.
|
|
|
|
|
|
|
|
## Populate the file list
|
|
|
|
|
|
|
|
Provide the logic to populate the list of files or directories to examine:
|
|
|
|
`lib/functions/buildFileList.sh`
|
|
|
|
|
|
|
|
## Get the tool version
|
|
|
|
|
|
|
|
Provide the logic to populate the versions file: `scripts/linterVersions.sh`
|
|
|
|
|
|
|
|
## Detection logic
|
|
|
|
|
|
|
|
If necessary, provide elaborate logic to detect if the tool should examine a
|
|
|
|
file or a directory: `lib/functions/detectFiles.sh`
|
|
|
|
|
|
|
|
## Special cases
|
|
|
|
|
|
|
|
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:
|
2024-08-07 09:36:16 -04:00
|
|
|
|
2024-09-13 08:37:48 -04:00
|
|
|
- Validate the runtime environment: `lib/functions/validation.sh`.
|
|
|
|
- Get the installed version of the tool: `scripts/linterVersions.sh`
|
|
|
|
- Load configuration files: `lib/functions/linterRules.sh`
|
|
|
|
- Run the tool: `lib/functions/worker.sh`
|
|
|
|
- Compose the tool command: `lib/functions/linterCommands.sh`
|
|
|
|
- Modify the core Super-linter logic: `lib/linter.sh`
|