oxsecurity / megalinter

🦙 MegaLinter analyzes 50 languages, 22 formats, 21 tooling formats, excessive copy-pastes, spelling mistakes and security issues in your repository sources with a GitHub Action, other CI tools or locally.
https://megalinter.io
GNU Affero General Public License v3.0
1.88k stars 224 forks source link

Overriding `ENABLE_LINTERS` on command line seems not accepted #3507

Closed llaville closed 4 months ago

llaville commented 4 months ago

Describe the bug MegaLinter PHP flavor Docker image does not accept to filter linters by ENABLE_LINTERS environment variable.

To Reproduce Steps to reproduce the behavior:

  1. Invoke command sudo rm -rf megalinter-reports/ && time docker run --rm -v /var/run/docker.sock:/var/run/docker.sock:rw -v $(pwd):/tmp/lint:rw -e ENABLE_LINTERS=PHP_PHPSTAN -e LOG_LEVEL=debug oxsecurity/megalinter-php:v7
  2. Verify on megalinter-reports/megalinter.log that only PHPSTAN linter is enabled
  3. All PHP linters are ran

Expected behavior As explained by the official documentation : https://megalinter.io/latest/config-activation/

If ENABLE_LINTERS is set, only listed linters will be processed

Screenshots linters

----------------------------------------------------------------------------------------------------
 - Image Creation Date: 2024-04-23T20:13:29Z
 - Image Revision: 03986e6993ccf699a22451118520680b438e7d2a
 - Image Version: v7.11.1
----------------------------------------------------------------------------------------------------
The MegaLinter documentation can be found at:
 - https://megalinter.io/7.11.1
----------------------------------------------------------------------------------------------------
MegaLinter initialization
MegaLinter will analyze workspace [/tmp/lint]
BUILD_DATE=2024-04-23T20:13:29Z
BUILD_REVISION=03986e6993ccf699a22451118520680b438e7d2a
BUILD_VERSION=v7.11.1
CONFIG_REPORTER=False
CONFIG_SOURCE=TEMPORARY VAL THAT SHOULD NOT REMAIN
CONSOLE_REPORTER=True
DISABLE_LINTERS=['JSON_JSONLINT', 'JSON_V8R', 'MARKDOWN_MARKDOWN_LINK_CHECK', 'MARKDOWN_MARKDOWN_TABLE_FORMATTER', 'PHP_BUILTIN', 'YAML_V8R']
DOCKERFILE_HADOLINT_CONFIG_FILE=.hadolint.yml
EDITORCONFIG_EDITORCONFIG_CHECKER_CLI_LINT_MODE=project
ENABLE=['ACTION', 'BASH', 'CREDENTIALS', 'DOCKERFILE', 'EDITORCONFIG', 'JSON', 'MARKDOWN', 'PHP', 'YAML']
ENABLE_LINTERS=PHP_PHPSTAN
EXCLUDED_DIRECTORIES=['.git', '.changes']
GOPATH=/go
GOROOT=/usr/lib/go
GPG_KEY=7169605F62C751356D054A26A821E680E5FA6305
HOME=/root
HOSTNAME=ce532bb932e8
IGNORE_GITIGNORED_FILES=True
JAVA_HOME=/usr/lib/jvm/java-17-openjdk
JSON_PRETTIER_FILTER_REGEX_EXCLUDE=(composer.json)
LANG=C.UTF-8
LOG_LEVEL=debug
MARKDOWN_MARKDOWNLINT_CONFIG_FILE=.markdown-lint.json
MEGALINTER_FLAVOR=php
NODE_ENV=production
NODE_OPTIONS=--max-old-space-size=8192
NODE_PATH=/node-deps/node_modules
PATH=/usr/lib/jvm/java-17-openjdk/bin:/node-deps/node_modules/.bin:/root/.cargo/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/go/bin:/go/bin:/venvs/ansible-lint/bin:/venvs/djlint/bin:/venvs/checkov/bin:/venvs/semgrep/bin:/venvs/snakemake/bin:/venvs/snakefmt/bin:/venvs/proselint/bin:/venvs/sqlfluff/bin:/venvs/yamllint/bin
PHP_PHPCS_ARGUMENTS=-n
PHP_PHPCS_CONFIG_FILE=.phpcs.xml.dist
PHP_PHPLINT_ARGUMENTS=--no-cache
PHP_PHPLINT_CLI_LINT_MODE=project
PHP_PHPSTAN_CLI_LINT_MODE=project
PRINT_ALL_FILES=False
PRINT_ALPACA=False
PWD=/
PYTHONPATH=:/
PYTHON_GET_PIP_SHA256=dfe9fd5c28dc98b5ac17979a953ea550cec37ae1b47a5116007395bfacff2ab9
PYTHON_GET_PIP_URL=https://github.com/pypa/get-pip/raw/dbf0c85f76fb6e1ab42aa672ffca6f0a675d9ee4/public/get-pip.py
PYTHON_PIP_VERSION=24.0
PYTHON_VERSION=3.12.3
SARIF_REPORTER=False
SARIF_REPORTER_LINTERS=['PHP_PHPSTAN']
SHLVL=1
SHOW_ELAPSED_TIME=True
UPDATED_SOURCES_REPORTER=False
YAML_PRETTIER_FILTER_REGEX_EXCLUDE=(\.github|mkdocs\.yml|\.mega-linter\.yml|\.changie\.yaml)
YAML_YAMLLINT_FILTER_REGEX_EXCLUDE=(\.github|mkdocs\.yml)
_=/usr/local/bin/python
cli=True
request_id=e0ccb798-020f-11ef-b1a8-0242ac120002
----------------------------------------------------------------------------------------------------

Additional context

My local MegaLinter config file contains at least

ENABLE:
    - ACTION
    - BASH
    - CREDENTIALS
    - DOCKERFILE
    - EDITORCONFIG
    - JSON
    - MARKDOWN
    - PHP
    - YAML
DISABLE_LINTERS:
    - JSON_JSONLINT
    - JSON_V8R
    - MARKDOWN_MARKDOWN_LINK_CHECK
    - MARKDOWN_MARKDOWN_TABLE_FORMATTER
    - PHP_BUILTIN
    #- PHP_PSALM
    - YAML_V8R
nvuillam commented 4 months ago

I think ENABLE of .mega-linter.yml + ENABLE_LINTERS from env var provides the result you observe.

Can you try with -e ENABLE=PHP -e ENABLE_LINTERS=PHP_PHPSTAN ?

I think it should work for your use case :)

nvuillam commented 4 months ago

Note: if you really want PHP_PHPSTAN only, you can also use this standalone image -> https://hub.docker.com/r/oxsecurity/megalinter-only-php_phpstan/tags

llaville commented 4 months ago

I think ENABLE of .mega-linter.yml + ENABLE_LINTERS from env var provides the result you observe.

Can you try with -e ENABLE=PHP -e ENABLE_LINTERS=PHP_PHPSTAN ?

I think it should work for your use case :)

This one won't work. I've already tried. Only PHP linters are used but it display four available.

llaville commented 4 months ago

Note: if you really want PHP_PHPSTAN only, you can also use this standalone image -> https://hub.docker.com/r/oxsecurity/megalinter-only-php_phpstan/tags

I'll check this one tomorrow. But I'm surprised that it won't work. I remember to this feature in previous versions 6 or 5 and it run fine. But I don't know which specific version. I suspect a minor regression.

nvuillam commented 4 months ago

I agree with you, if it doesn't work, it must be a regression, you should be able to select the linters you want to run ! In my memory, there was a priority on ENABLE over DISABLE variables

Let's investigate

llaville commented 4 months ago

Note: if you really want PHP_PHPSTAN only, you can also use this standalone image -> https://hub.docker.com/r/oxsecurity/megalinter-only-php_phpstan/tags

FYI: I've just tested this docker image, and of course it run as expected. Results by image

only-php-phpstan

Compare vs invocation of oxsecurity/megalinter-php:v7 (v7.11.1) with -e ENABLE=PHP -e ENABLE_LINTERS=PHP_PHPSTAN arguments that print

enable_linters_php

llaville commented 4 months ago

I agree with you, if it doesn't work, it must be a regression, you should be able to select the linters you want to run ! In my memory, there was a priority on ENABLE over DISABLE variables

Let's investigate

I think I've found origin. I'll investigate more ... and will keep you aware soon

llaville commented 4 months ago

@nvuillam Good news, my tests are finished.

With predefined settings into a .mega-linter.yml config file

ENABLE:
    - ACTION
    - BASH
    - CREDENTIALS
    - DOCKERFILE
    - EDITORCONFIG
    - JSON
    - MARKDOWN
    - PHP
    - YAML
DISABLE_LINTERS:
    - JSON_JSONLINT
    - JSON_V8R
    - MARKDOWN_MARKDOWN_LINK_CHECK
    - MARKDOWN_MARKDOWN_TABLE_FORMATTER
    - PHP_BUILTIN
    - PHP_PSALM
    - YAML_V8R

or NOT, test results are the same. ENABLE_LINTERS has now a higher privilege vs other activation/deactivation rules.

If ENABLE_LINTERS is set, only listed linters will be processed

With a single linter : -e ENABLE_LINTERS=PHP_PHPSTAN

+----SUMMARY-+---------+---------+-------+-------+--------+--------------+
| Descriptor | Linter  | Mode    | Files | Fixed | Errors | Elapsed time |
+------------+---------+---------+-------+-------+--------+--------------+
| ❌ PHP     | phpstan | project |   n/a |       |      9 |        4.41s |
+------------+---------+---------+-------+-------+--------+--------------+

With multiple linters : -e ENABLE_LINTERS=PHP_PSALM,PHP_PHPLINT

+----SUMMARY-+---------+---------------+-------+-------+--------+--------------+
| Descriptor | Linter  | Mode          | Files | Fixed | Errors | Elapsed time |
+------------+---------+---------------+-------+-------+--------+--------------+
| ✅ PHP     | phplint | project       |   n/a |       |      0 |        0.16s |
| ❌ PHP     | psalm   | list_of_files |    45 |       |     41 |        4.05s |
+------------+---------+---------------+-------+-------+--------+--------------+

NB: even if PSALM was disabled by megalinter config file

llaville commented 4 months ago

Commit df9f6fe5357ee73a1f9c41370551ff4e98b380a9 solved this issue !

llaville commented 4 months ago

Need to fix again / thanks to test automation to highlight the problem

Suprised that following tests PASSED

But not :

llaville commented 4 months ago

Ok this time, I think I've found the right fix to solve this issue and avoid regressions. I'll continue this afternoon, by pushing commit and wait the MegaLinter automation verdict, because I've no more free time now.

nvuillam commented 4 months ago

thanks :)

llaville commented 4 months ago

@nvuillam You'll laugh ! Either I didn't understood the rules of activation/deactivation features, or it works as expected ;-)

I'll try to explain :

As I have a .mega-linter.yml config file with existing activation rules definition, I though it won't work

ENABLE:
    - ACTION
    - BASH
    - CREDENTIALS
    - DOCKERFILE
    - EDITORCONFIG
    - JSON
    - MARKDOWN
    - PHP
    - YAML
DISABLE_LINTERS:
    - JSON_JSONLINT
    - JSON_V8R
    - MARKDOWN_MARKDOWN_LINK_CHECK
    - MARKDOWN_MARKDOWN_TABLE_FORMATTER
    - PHP_BUILTIN
    - PHP_PSALM
    - YAML_V8R

But as official doc said :

MegaLinter have all linters enabled by default, but allows to enable only some, or disable only some

  • If ENABLE isn't set, all descriptors are activated by default. If set, all linters of listed descriptors will be activated by default
  • If ENABLE_LINTERS is set, only listed linters will be processed
  • If DISABLE is set, the linters in the listed descriptors will be skipped
  • If DISABLE_LINTERS is set, the listed linters will be skipped

Configuration file contents and env variable given on command line are combined to produces final results ! This is here, the combined values that make me wrong on analysis.

So when I invoke MegaLinter with following argument -e ENABLE_LINTERS=PHP_PHPLINT I though that only PHPLINT will produce results, but it was without other defined on config file.

When I remove activation/deactivation rules on config file, I got only the PHPLint results (as wanted).

So I consider this is not an issue : Can you confirm ?

BTW, on searching origin of issue I've added some extra debugging line that add on debug level such kind of output

[Activation] + PHP_PHPCS (PHP) was activated by ENABLE strategies
[Activation] + PHP_PHPSTAN (PHP) was activated by ENABLE strategies
[Activation] - PHP_PSALM (PHP) was not activated by DISABLE_LINTERS strategies
[Activation] + PHP_PHPLINT (PHP) was activated by ENABLE_LINTERS strategies

Do you want it in core of MegaLinter ?

On PHP flavor with all linters, I got something like

[Activation] - ACTION_ACTIONLINT (ACTION) was not activated by default strategies
[Activation] - ANSIBLE_ANSIBLE_LINT (ANSIBLE) was not activated by default strategies
[Activation] - API_SPECTRAL (API) was not activated by default strategies
[Activation] - ARM_ARM_TTK (ARM) was not activated by default strategies
[Activation] - BASH_EXEC (BASH) was not activated by default strategies
[Activation] - BASH_SHELLCHECK (BASH) was not activated by default strategies
[Activation] - BASH_SHFMT (BASH) was not activated by default strategies
[Activation] - BICEP_BICEP_LINTER (BICEP) was not activated by default strategies
[Activation] - C_CPPLINT (C) was not activated by default strategies
[Activation] - C_CLANG_FORMAT (C) was not activated by default strategies
[Activation] - CLOJURE_CLJ_KONDO (CLOJURE) was not activated by default strategies
[Activation] - CLOJURE_CLJSTYLE (CLOJURE) was not activated by default strategies
[Activation] - CLOUDFORMATION_CFN_LINT (CLOUDFORMATION) was not activated by default strategies
[Activation] - COFFEE_COFFEELINT (COFFEE) was not activated by default strategies
[Activation] - COPYPASTE_JSCPD (COPYPASTE) was not activated by default strategies
[Activation] - CPP_CPPLINT (CPP) was not activated by default strategies
[Activation] - CPP_CLANG_FORMAT (CPP) was not activated by default strategies
[Activation] - CSHARP_DOTNET_FORMAT (CSHARP) was not activated by default strategies
[Activation] - CSHARP_CSHARPIER (CSHARP) was not activated by default strategies
[Activation] - CSHARP_ROSLYNATOR (CSHARP) was not activated by default strategies
[Activation] - CSS_STYLELINT (CSS) was not activated by default strategies
[Activation] - CSS_SCSS_LINT (CSS) was not activated by default strategies
[Activation] - DART_DARTANALYZER (DART) was not activated by default strategies
[Activation] - DOCKERFILE_HADOLINT (DOCKERFILE) was not activated by default strategies
[Activation] - EDITORCONFIG_EDITORCONFIG_CHECKER (EDITORCONFIG) was not activated by default strategies
[Activation] - ENV_DOTENV_LINTER (ENV) was not activated by default strategies
[Activation] - GHERKIN_GHERKIN_LINT (GHERKIN) was not activated by default strategies
[Activation] - GO_GOLANGCI_LINT (GO) was not activated by default strategies
[Activation] - GO_REVIVE (GO) was not activated by default strategies
[Activation] - GRAPHQL_GRAPHQL_SCHEMA_LINTER (GRAPHQL) was not activated by default strategies
[Activation] - GROOVY_NPM_GROOVY_LINT (GROOVY) was not activated by default strategies
[Activation] - HTML_DJLINT (HTML) was not activated by default strategies
[Activation] - HTML_HTMLHINT (HTML) was not activated by default strategies
[Activation] - JAVA_CHECKSTYLE (JAVA) was not activated by default strategies
[Activation] - JAVA_PMD (JAVA) was not activated by default strategies
[Activation] - JAVASCRIPT_ES (JAVASCRIPT) was not activated by default strategies
[Activation] - JAVASCRIPT_STANDARD (JAVASCRIPT) was not activated by default strategies
[Activation] - JAVASCRIPT_PRETTIER (JAVASCRIPT) was not activated by default strategies
[Activation] + JSON_JSONLINT (JSON) was activated by ENABLE_LINTERS strategies
[Activation] - JSON_ESLINT_PLUGIN_JSONC (JSON) was not activated by default strategies
[Activation] - JSON_V8R (JSON) was not activated by default strategies
[Activation] - JSON_PRETTIER (JSON) was not activated by default strategies
[Activation] - JSON_NPM_PACKAGE_JSON_LINT (JSON) was not activated by default strategies
[Activation] - JSX_ESLINT (JSX) was not activated by default strategies
[Activation] - KOTLIN_KTLINT (KOTLIN) was not activated by default strategies
[Activation] - KOTLIN_DETEKT (KOTLIN) was not activated by default strategies
[Activation] - KUBERNETES_KUBECONFORM (KUBERNETES) was not activated by default strategies
[Activation] - KUBERNETES_HELM (KUBERNETES) was not activated by default strategies
[Activation] - KUBERNETES_KUBESCAPE (KUBERNETES) was not activated by default strategies
[Activation] - LATEX_CHKTEX (LATEX) was not activated by default strategies
[Activation] - LUA_LUACHECK (LUA) was not activated by default strategies
[Activation] - MAKEFILE_CHECKMAKE (MAKEFILE) was not activated by default strategies
[Activation] - MARKDOWN_MARKDOWNLINT (MARKDOWN) was not activated by default strategies
[Activation] - MARKDOWN_REMARK_LINT (MARKDOWN) was not activated by default strategies
[Activation] - MARKDOWN_MARKDOWN_LINK_CHECK (MARKDOWN) was not activated by default strategies
[Activation] - MARKDOWN_MARKDOWN_TABLE_FORMATTER (MARKDOWN) was not activated by default strategies
[Activation] - OPENAPI_SPECTRAL (OPENAPI) was not activated by default strategies
[Activation] - PERL_PERLCRITIC (PERL) was not activated by default strategies
[Activation] - PHP_PHPCS (PHP) was not activated by default strategies
[Activation] - PHP_PHPSTAN (PHP) was not activated by default strategies
[Activation] - PHP_PSALM (PHP) was not activated by default strategies
[Activation] + PHP_PHPLINT (PHP) was activated by ENABLE_LINTERS strategies
[Activation] - POWERSHELL_POWERSHELL (POWERSHELL) was not activated by default strategies
[Activation] - POWERSHELL_POWERSHELL_FORMATTER (POWERSHELL) was not activated by default strategies
[Activation] - PROTOBUF_PROTOLINT (PROTOBUF) was not activated by default strategies
[Activation] - PUPPET_PUPPET_LINT (PUPPET) was not activated by default strategies
[Activation] - PYTHON_PYLINT (PYTHON) was not activated by default strategies
[Activation] - PYTHON_BLACK (PYTHON) was not activated by default strategies
[Activation] - PYTHON_FLAKE8 (PYTHON) was not activated by default strategies
[Activation] - PYTHON_ISORT (PYTHON) was not activated by default strategies
[Activation] - PYTHON_BANDIT (PYTHON) was not activated by default strategies
[Activation] - PYTHON_MYPY (PYTHON) was not activated by default strategies
[Activation] - PYTHON_PYRIGHT (PYTHON) was not activated by default strategies
[Activation] - PYTHON_RUFF (PYTHON) was not activated by default strategies
[Activation] - R_LINTR (R) was not activated by default strategies
[Activation] - RAKU_RAKU (RAKU) was not activated by default strategies
[Activation] - REPOSITORY_CHECKOV (REPOSITORY) was not activated by default strategies
[Activation] - REPOSITORY_DEVSKIM (REPOSITORY) was not activated by default strategies
[Activation] - REPOSITORY_DUSTILOCK (REPOSITORY) was not activated by default strategies
[Activation] - REPOSITORY_GIT_DIFF (REPOSITORY) was not activated by default strategies
[Activation] - REPOSITORY_GITLEAKS (REPOSITORY) was not activated by default strategies
[Activation] - REPOSITORY_GRYPE (REPOSITORY) was not activated by default strategies
[Activation] - REPOSITORY_KICS (REPOSITORY) was not activated by default strategies
[Activation] - REPOSITORY_SECRETLINT (REPOSITORY) was not activated by default strategies
[Activation] - REPOSITORY_SEMGREP (REPOSITORY) was not activated by default strategies
[Activation] - REPOSITORY_SYFT (REPOSITORY) was not activated by default strategies
[Activation] - REPOSITORY_TRIVY (REPOSITORY) was not activated by default strategies
[Activation] - REPOSITORY_TRIVY_SBOM (REPOSITORY) was not activated by default strategies
[Activation] - REPOSITORY_TRUFFLEHOG (REPOSITORY) was not activated by default strategies
[Activation] - RST_RST_LINT (RST) was not activated by default strategies
[Activation] - RST_RSTCHECK (RST) was not activated by default strategies
[Activation] - RST_RSTFMT (RST) was not activated by default strategies
[Activation] - RUBY_RUBOCOP (RUBY) was not activated by default strategies
[Activation] - RUST_CLIPPY (RUST) was not activated by default strategies
[Activation] - SALESFORCE_SFDX_SCANNER_APEX (SALESFORCE) was not activated by default strategies
[Activation] - SALESFORCE_SFDX_SCANNER_AURA (SALESFORCE) was not activated by default strategies
[Activation] - SALESFORCE_SFDX_SCANNER_LWC (SALESFORCE) was not activated by default strategies
[Activation] - SALESFORCE_LIGHTNING_FLOW_SCANNER (SALESFORCE) was not activated by default strategies
[Activation] - SCALA_SCALAFIX (SCALA) was not activated by default strategies
[Activation] - SNAKEMAKE_LINT (SNAKEMAKE) was not activated by default strategies
[Activation] - SNAKEMAKE_SNAKEFMT (SNAKEMAKE) was not activated by default strategies
[Activation] - SPELL_CSPELL (SPELL) was not activated by default strategies
[Activation] - SPELL_PROSELINT (SPELL) was not activated by default strategies
[Activation] - SPELL_VALE (SPELL) was not activated by default strategies
[Activation] - SPELL_LYCHEE (SPELL) was not activated by default strategies
[Activation] - SQL_SQL_LINT (SQL) was not activated by default strategies
[Activation] - SQL_SQLFLUFF (SQL) was not activated by default strategies
[Activation] - SQL_TSQLLINT (SQL) was not activated by default strategies
[Activation] - SWIFT_SWIFTLINT (SWIFT) was not activated by default strategies
[Activation] - TEKTON_TEKTON_LINT (TEKTON) was not activated by default strategies
[Activation] - TERRAFORM_TFLINT (TERRAFORM) was not activated by default strategies
[Activation] - TERRAFORM_TERRASCAN (TERRAFORM) was not activated by default strategies
[Activation] - TERRAFORM_TERRAGRUNT (TERRAFORM) was not activated by default strategies
[Activation] - TERRAFORM_TERRAFORM_FMT (TERRAFORM) was not activated by default strategies
[Activation] - TSX_ESLINT (TSX) was not activated by default strategies
[Activation] - TYPESCRIPT_ES (TYPESCRIPT) was not activated by default strategies
[Activation] - TYPESCRIPT_STANDARD (TYPESCRIPT) was not activated by default strategies
[Activation] - TYPESCRIPT_PRETTIER (TYPESCRIPT) was not activated by default strategies
[Activation] - VBDOTNET_DOTNET_FORMAT (VBDOTNET) was not activated by default strategies
[Activation] - XML_XMLLINT (XML) was not activated by default strategies
[Activation] - YAML_PRETTIER (YAML) was not activated by default strategies
[Activation] - YAML_YAMLLINT (YAML) was not activated by default strategies
[Activation] - YAML_V8R (YAML) was not activated by default strategies
llaville commented 4 months ago

new commit e3d20fd79ac8aab46e6c8065d30c3a29f5515cf8 related to these previous extra Activation logs

nvuillam commented 4 months ago

It's indeed how it is supposed to work :) But what changed with latest version compared to your config that used to work before ?

llaville commented 4 months ago

I don't remember. I used this linter filtering very few. So it was long time ago I did it !