简介
MegaLinter 是一个多语言、多工具的集成代码检查工具,它能够通过一个统一的工作流来运行多个静态代码分析工具,从而提供全面的代码质量检查。
官网:https://megalinter.io/latest/
MegaLinter 的特点:
多语言支持:MegaLinter 支持多种编程语言,包括常见的如 C、C++、Java、Python、JavaScript 等,以及一些不太常见的语言。这使得它成为跨多个项目和团队的理想选择。
多工具集成:MegaLinter 集成了许多常用的静态代码分析工具,如 ESLint、Pylint、RuboCop、Checkstyle 等。通过 MegaLinter,我们可以在一个工作流中同时运行这些工具,减少配置和管理的复杂性。
全面的代码检查:MegaLinter 运行各种工具,并对代码库进行全面的代码质量检查。它可以检查代码规范、潜在的错误、安全漏洞、代码复杂度等等,帮助我们发现和解决潜在的问题。
体验
编写两个 js 文件
demo.js
cosole.log("nihao");
demo-2.js
console.log('nihao')
目录结构如下:
D:/apps-data/docker/megalinter/lint/
|- demo.js
|_ demo-2.js
启动镜像,开始检测
docker run --rm -v D:/apps-data/docker/megalinter/run/docker.sock:/var/run/docker.sock:rw -v D:/apps-data/docker/megalinter/lint:/tmp/lint:rw oxsecurity/megalinter:v7
其中 -v D:/apps-data/docker/megalinter/lint:/tmp/lint
将D:/apps-data/docker/megalinter/lint
下存储的待测文件转储进 /tmp/lint
megalinter 将扫面 /tmp/lint
中的文件,并自动识别其语言,然后进行静态检查。
日志如下:
Skipped setting git safe.directory DEFAULT_WORKSPACE: ...
Setting git safe.directory default: /github/workspace ...
Setting git safe.directory to /tmp/lint ...
[MegaLinter init] ONE-SHOT RUN
[config] Environment variables only (no config file found in /tmp/lint)
.:oool' ,looo;
.xNXNXl .dXNNXo.
lXXXX0c. 'oKXXN0;
.oKNXNX0kxdddddddoc,. .;lodddddddxk0XXXX0c
.:kKXXXXXXXXXXXXNXX0dllx0XXXXXXXXXXXXXXXKd,
.,cdkOOOOOOOO0KXXXXXXXXXXK0OOOOOOOkxo:'
'ckKXNNNXkc'
':::::;. .c0XX0l. .;::::;.
'xXXXXXx' :kx: ;OXXXXKd.
.dKNNXXO; .. :0XXXXKl.
.lKXXXX0: .lKXXXX0:
:0XXXXKl. .dXXXXXk,
;kXXXXKd:cxXXXXXx'
'xXNXXXXXXXXXKo.
.oKXXXXNXXX0l.
.lKNNXNNXO:
,looool'
==========================================================
============= MegaLinter, by OX.security =============
========= https://ox.security?ref=megalinter ===========
==========================================================
----------------------------------------------------------------------------------------------------
------------------------------------ MegaLinter, by OX Security ------------------------------------
----------------------------------------------------------------------------------------------------
- Image Creation Date: 2024-02-11T21:47:21Z
- Image Revision: 190cd0dad6dc52b2de5b810e3b290c3d6bdcc0f2
- Image Version: v7.9.0
----------------------------------------------------------------------------------------------------
The MegaLinter documentation can be found at:
- https://megalinter.io/7.9.0
----------------------------------------------------------------------------------------------------
MegaLinter initialization
MegaLinter will analyze workspace [/tmp/lint]
[Activation] ACTION_ACTIONLINT has been set inactive, as subdirectory has not been found: .github/workflows (set value "any" to always activate)
[Activation] ANSIBLE_ANSIBLE_LINT has been set inactive, as subdirectory has not been found: ansible (set value "any" to always activate)
[Activation] EDITORCONFIG_EDITORCONFIG_CHECKER has been set inactive, as none of these files has been found: ['.editorconfig']
[Activation] JAVASCRIPT_ES has been set inactive, as none of these files has been found: ['.eslintrc.json', '.eslintrc.yml', '.eslintrc.yaml', '.eslintrc.js', '.eslintrc.cjs', 'package.json:eslintConfig']
[Activation] JSON_NPM_PACKAGE_JSON_LINT has been set inactive, as none of these files has been found: ['package.json']
[Activation] JSX_ESLINT has been set inactive, as none of these files has been found: ['.eslintrc.json', '.eslintrc.yml', '.eslintrc.yaml', '.eslintrc.js', '.eslintrc.cjs', 'package.json:eslintConfig']
[Activation] KUBERNETES_KUBECONFORM has been set inactive, as subdirectory has not been found: kubernetes (set value "any" to always activate)
[Activation] KUBERNETES_HELM has been set inactive, as none of these files has been found: ['Chart.yml', 'Chart.yaml']
[Activation] KUBERNETES_KUBESCAPE has been set inactive, as none of these files has been found: ['Chart.yml', 'Chart.yaml']
[SemgrepLinter] Deactivated because no ruleset has been defined
[Activation] SALESFORCE_SFDX_SCANNER_APEX has been set inactive, as subdirectory has not been found: force-app (set value "any" to always activate)
[Activation] SALESFORCE_SFDX_SCANNER_AURA has been set inactive, as subdirectory has not been found: force-app (set value "any" to always activate)
[Activation] SALESFORCE_SFDX_SCANNER_LWC has been set inactive, as subdirectory has not been found: force-app (set value "any" to always activate)
[Activation] SALESFORCE_LIGHTNING_FLOW_SCANNER has been set inactive, as subdirectory has not been found: force-app (set value "any" to always activate)
[Activation] SPELL_PROSELINT has been set inactive, as none of these files has been found: ['.proselintrc', 'proselint/config.json']
[Activation] SPELL_VALE has been set inactive, as none of these files has been found: ['.vale.ini']
[Activation] SQL_SQLFLUFF has been set inactive, as none of these files has been found: ['.sqlfluff']
[Activation] SWIFT_SWIFTLINT has been set inactive, as none of these files has been found: ['.swiftlint.yml']
[Activation] TSX_ESLINT has been set inactive, as none of these files has been found: ['.eslintrc.json', '.eslintrc.yml', '.eslintrc.yaml', '.eslintrc.js', '.eslintrc.cjs', 'package.json:eslintConfig']
[Activation] TYPESCRIPT_ES has been set inactive, as none of these files has been found: ['.eslintrc.json', '.eslintrc.yml', '.eslintrc.yaml', '.eslintrc.js', '.eslintrc.cjs', 'package.json:eslintConfig']
CLOJURE_CLJSTYLE has been temporary disabled in MegaLinter, please use a previous MegaLinter version or wait for the next one !
MARKDOWN_REMARK_LINT has been temporary disabled in MegaLinter, please use a previous MegaLinter version or wait for the next one !
Skipped linters: ACTION_ACTIONLINT, ANSIBLE_ANSIBLE_LINT, CLOJURE_CLJSTYLE, EDITORCONFIG_EDITORCONFIG_CHECKER, JAVASCRIPT_ES, JAVASCRIPT_PRETTIER, JSON_NPM_PACKAGE_JSON_LINT, JSX_ESLINT, KUBERNETES_HELM, KUBERNETES_KUBECONFORM, KUBERNETES_KUBESCAPE, MARKDOWN_REMARK_LINT, REPOSITORY_SEMGREP, SALESFORCE_LIGHTNING_FLOW_SCANNER, SALESFORCE_SFDX_SCANNER_APEX, SALESFORCE_SFDX_SCANNER_AURA, SALESFORCE_SFDX_SCANNER_LWC, SPELL_PROSELINT, SPELL_VALE, SQL_SQLFLUFF, SWIFT_SWIFTLINT, TSX_ESLINT, TYPESCRIPT_ES, TYPESCRIPT_PRETTIER
To receive reports as email, please set variable EMAIL_REPORTER_EMAIL
MegaLinter now collects the files to analyse
Listing all files in directory [/tmp/lint], then filter with:
- File extensions: , .R, .RMD, .Rmd, .bash, .bicep, .c, .c++, .cc, .cdxml, .clj, .cljc, .cljs, .coffee, .cpp, .cs, .csproj, .css, .cu, .cuh, .cxx, .dart, .dash, .edn, .env, .feature, .go, .gradle, .graphql, .groovy, .gvy, .h, .h++, .hcl, .hh, .hpp, .htm, .html, .hxx, .java, .js, .json, .json5, .jsonc, .ksh, .kt, .kts, .lua, .markdown, .md, .mdx, .nf, .p6, .php, .pl, .pl6, .pm, .pm6, .pp, .proto, .ps1, .ps1xml, .psd1, .psm1, .psrc, .pssc, .py, .r, .raku, .rakumod, .rakutest, .rb, .rs, .rst, .saas, .scala, .scss, .sh, .smk, .sql, .t, .tex, .tf, .ts, .txt, .vb, .xml, .yaml, .yml
- File names (regex): Containerfile, Dockerfile, Jenkinsfile, Makefile, Snakefile
Unable to list git ignored files (/tmp/lint)
Kept [2] files on [2] found files
+----MATCHING LINTERS-----+----------+----------------+------------+
| Descriptor | Linter | Criteria | Matching files | Format/Fix |
+------------+------------+----------+----------------+------------+
| COPYPASTE | jscpd | | project | no |
| JAVASCRIPT | standard | .js | 2 | no |
| REPOSITORY | checkov | | project | no |
| REPOSITORY | devskim | | project | no |
| REPOSITORY | dustilock | | project | no |
| REPOSITORY | git_diff | | project | no |
| REPOSITORY | gitleaks | | project | no |
| REPOSITORY | grype | | project | no |
| REPOSITORY | kics | | project | no |
| REPOSITORY | secretlint | | project | no |
| REPOSITORY | syft | | project | no |
| REPOSITORY | trivy | | project | no |
| REPOSITORY | trivy-sbom | | project | no |
| REPOSITORY | trufflehog | | project | no |
| SPELL | cspell | | 2 | no |
+------------+------------+----------+----------------+------------+
Processing linters on [8] parallel cores…
✅ Linted [REPOSITORY] files with [secretlint] successfully - (1.43s)
- Using [secretlint v8.1.1] https://megalinter.io/7.9.0/descriptors/repository_secretlint
- MegaLinter key: [REPOSITORY_SECRETLINT]
- Rules config: [.secretlintrc.json]
- Ignore file: [.secretlintignore]
✅ Linted [COPYPASTE] files with [jscpd] successfully - (1.65s)
- Using [jscpd v3.5.10] https://megalinter.io/7.9.0/descriptors/copypaste_jscpd
- MegaLinter key: [COPYPASTE_JSCPD]
- Rules config: [.jscpd.json]
✅ Linted [REPOSITORY] files with [devskim] successfully - (3.55s)
- Using [devskim v1.0.28] https://megalinter.io/7.9.0/descriptors/repository_devskim
- MegaLinter key: [REPOSITORY_DEVSKIM]
- Rules config: [.devskim.json]
❌ Linted [SPELL] files with [cspell]: Found 3 error(s) - (3.96s)
- Using [cspell v8.3.2] https://megalinter.io/7.9.0/descriptors/spell_cspell
- MegaLinter key: [SPELL_CSPELL]
- Rules config: identified by [cspell]
- Number of files analyzed: [3]
--Error detail:
1/3 ./45e552d0-e85d-4f19-82ac-9d0aa19d3b67-megalinter_file_names_cspell.txt 777.88ms
2/3 ./demo-2.js 338.66ms X
./demo-2.js:1:14 - Unknown word (nihao) -- console.log('nihao');
Suggestions: [chiao, nina, nipa, nita, niza]
3/3 ./demo.js 125.36ms X
./demo.js:1:1 - Unknown word (cosole) -- cosole.log("nihao");
Suggestions: [console, Console, cole, cool, cose]
./demo.js:1:13 - Unknown word (nihao) -- cosole.log("nihao");
Suggestions: [chiao, nina, nipa, nita, niza]
CSpell: Files checked: 3, Issues found: 3 in 2 files
✅ Linted [REPOSITORY] files with [dustilock] successfully - (0.09s)
- Using [dustilock v1.2.0] https://megalinter.io/7.9.0/descriptors/repository_dustilock
- MegaLinter key: [REPOSITORY_DUSTILOCK]
- Rules config: identified by [dustilock]
✅ Linted [REPOSITORY] files with [gitleaks] successfully - (0.16s)
- Using [gitleaks v8.18.2] https://megalinter.io/7.9.0/descriptors/repository_gitleaks
- MegaLinter key: [REPOSITORY_GITLEAKS]
- Rules config: [.gitleaks.toml]
❌ Linted [JAVASCRIPT] files with [standard]: Found 1 error(s) - (2.48s)
- Using [standard v17.1.0] https://megalinter.io/7.9.0/descriptors/javascript_standard
- MegaLinter key: [JAVASCRIPT_STANDARD]
- Rules config: identified by [standard]
- Number of files analyzed: [2]
--Error detail:
standard: Use JavaScript Standard Style (https://standardjs.com)
standard: Run `standard --fix` to automatically fix some problems.
/tmp/lint/demo-2.js:1:21: Extra semicolon. (semi)
/tmp/lint/demo.js:1:1: 'cosole' is not defined. (no-undef)
/tmp/lint/demo.js:1:12: Strings must use singlequote. (quotes)
/tmp/lint/demo.js:1:20: Extra semicolon. (semi)
/tmp/lint/demo.js:1:21: Newline required at end of file but not found. (eol-last)
❌ Linted [REPOSITORY] files with [git_diff]: Found 1 error(s) - (0.01s)
- Using [git_diff v2.43.0] https://megalinter.io/7.9.0/descriptors/repository_git_diff
- MegaLinter key: [REPOSITORY_GIT_DIFF]
- Rules config: identified by [git_diff]
--Error detail:
warning: Not a git repository. Use --no-index to compare two paths outside a working tree
usage: git diff --no-index [<options>] <path> <path>
Diff output format options
-p, --patch generate patch
-s, --no-patch suppress diff output
-u generate patch
-U, --unified[=<n>] generate diffs with <n> lines context
-W, --[no-]function-context
generate diffs with <n> lines context
--raw generate the diff in raw format
--patch-with-raw synonym for '-p --raw'
--patch-with-stat synonym for '-p --stat'
--numstat machine friendly --stat
--shortstat output only the last line of --stat
-X, --dirstat[=<param1,param2>...]
output the distribution of relative amount of changes for each sub-directory
--cumulative synonym for --dirstat=cumulative
--dirstat-by-file[=<param1,param2>...]
synonym for --dirstat=files,param1,param2...
--check warn if changes introduce conflict markers or whitespace errors
--summary condensed summary such as creations, renames and mode changes
--name-only show only names of changed files
--name-status show only names and status of changed files
--stat[=<width>[,<name-width>[,<count>]]]
generate diffstat
--stat-width <width> generate diffstat with a given width
--stat-name-width <width>
generate diffstat with a given name width
--stat-graph-width <width>
generate diffstat with a given graph width
--stat-count <count> generate diffstat with limited lines
--[no-]compact-summary
generate compact summary in diffstat
--binary output a binary diff that can be applied
--[no-]full-index show full pre- and post-image object names on the "index" lines
--[no-]color[=<when>] show colored diff
--ws-error-highlight <kind>
highlight whitespace errors in the 'context', 'old' or 'new' lines in the diff
-z do not munge pathnames and use NULs as output field terminators in --raw or --numstat
--[no-]abbrev[=<n>] use <n> digits to display object names
--src-prefix <prefix> show the given source prefix instead of "a/"
--dst-prefix <prefix> show the given destination prefix instead of "b/"
--line-prefix <prefix>
prepend an additional prefix to every line of output
--no-prefix do not show any source or destination prefix
--default-prefix use default prefixes a/ and b/
--inter-hunk-context <n>
show context between diff hunks up to the specified number of lines
--output-indicator-new <char>
specify the character to indicate a new line instead of '+'
--output-indicator-old <char>
specify the character to indicate an old line instead of '-'
--output-indicator-context <char>
specify the character to indicate a context instead of ' '
Diff rename options
-B, --break-rewrites[=<n>[/<m>]]
break complete rewrite changes into pairs of delete and create
-M, --find-renames[=<n>]
detect renames
-D, --irreversible-delete
omit the preimage for deletes
-C, --find-copies[=<n>]
detect copies
--[no-]find-copies-harder
use unmodified files as source to find copies
--no-renames disable rename detection
--[no-]rename-empty use empty blobs as rename source
--[no-]follow continue listing the history of a file beyond renames
-l <n> prevent rename/copy detection if the number of rename/copy targets exceeds given limit
Diff algorithm options
--minimal produce the smallest possible diff
-w, --ignore-all-space
ignore whitespace when comparing lines
-b, --ignore-space-change
ignore changes in amount of whitespace
--ignore-space-at-eol ignore changes in whitespace at EOL
--ignore-cr-at-eol ignore carrier-return at the end of line
--ignore-blank-lines ignore changes whose lines are all blank
-I, --[no-]ignore-matching-lines <regex>
ignore changes whose all lines match <regex>
--[no-]indent-heuristic
heuristic to shift diff hunk boundaries for easy reading
--patience generate diff using the "patience diff" algorithm
--histogram generate diff using the "histogram diff" algorithm
--diff-algorithm <algorithm>
choose a diff algorithm
--anchored <text> generate diff using the "anchored diff" algorithm
--word-diff[=<mode>] show word diff, using <mode> to delimit changed words
--word-diff-regex <regex>
use <regex> to decide what a word is
--color-words[=<regex>]
equivalent to --word-diff=color --word-diff-regex=<regex>
--[no-]color-moved[=<mode>]
moved lines of code are colored differently
--[no-]color-moved-ws <mode>
how white spaces are ignored in --color-moved
Other diff options
--[no-]relative[=<prefix>]
when run from subdir, exclude changes outside and show relative paths
-a, --[no-]text treat all files as text
-R swap two inputs, reverse the diff
--[no-]exit-code exit with 1 if there were differences, 0 otherwise
--[no-]quiet disable all output of the program
--[no-]ext-diff allow an external diff helper to be executed
--[no-]textconv run external text conversion filters when comparing binary files
--ignore-submodules[=<when>]
ignore changes to submodules in the diff generation
--submodule[=<format>]
specify how differences in submodules are shown
--ita-invisible-in-index
hide 'git add -N' entries from the index
--ita-visible-in-index
treat 'git add -N' entries as real in the index
-S <string> look for differences that change the number of occurrences of the specified string
-G <regex> look for differences that change the number of occurrences of the specified regex
--pickaxe-all show all changes in the changeset with -S or -G
--pickaxe-regex treat <string> in -S as extended POSIX regular expression
-O <file> control the order in which files appear in the output
--rotate-to <path> show the change in the specified path first
--skip-to <path> skip the output to the specified path
--find-object <object-id>
look for differences that change the number of occurrences of the specified object
--diff-filter [(A|C|D|M|R|T|U|X|B)...[*]]
select files by diff type
--output <file> output to a specific file
✅ Linted [REPOSITORY] files with [kics] successfully - (7.56s)
- Using [kics v1.7.12] https://megalinter.io/7.9.0/descriptors/repository_kics
- MegaLinter key: [REPOSITORY_KICS]
- Rules config: identified by [kics]
✅ Linted [REPOSITORY] files with [syft] successfully - (5.95s)
- Using [syft v0.104.0] https://megalinter.io/7.9.0/descriptors/repository_syft
- MegaLinter key: [REPOSITORY_SYFT]
- Rules config: identified by [syft]
✅ Linted [REPOSITORY] files with [trufflehog] successfully - (16.64s)
- Using [trufflehog v3.67.5] https://megalinter.io/7.9.0/descriptors/repository_trufflehog
- MegaLinter key: [REPOSITORY_TRUFFLEHOG]
- Rules config: identified by [trufflehog]
✅ Linted [REPOSITORY] files with [checkov] successfully - (27.79s)
- Using [checkov v3.2.20] https://megalinter.io/7.9.0/descriptors/repository_checkov
- MegaLinter key: [REPOSITORY_CHECKOV]
- Rules config: [.checkov.yml]
其中下表中信息,表明探测到了两个javascript文件
+----MATCHING LINTERS-----+----------+----------------+------------+
| Descriptor | Linter | Criteria | Matching files | Format/Fix |
+------------+------------+----------+----------------+------------+
| COPYPASTE | jscpd | | project | no |
| JAVASCRIPT | standard | .js | 2 | no |
| REPOSITORY | checkov | | project | no |
| REPOSITORY | devskim | | project | no |
| REPOSITORY | dustilock | | project | no |
| REPOSITORY | git_diff | | project | no |
| REPOSITORY | gitleaks | | project | no |
| REPOSITORY | grype | | project | no |
| REPOSITORY | kics | | project | no |
| REPOSITORY | secretlint | | project | no |
| REPOSITORY | syft | | project | no |
| REPOSITORY | trivy | | project | no |
| REPOSITORY | trivy-sbom | | project | no |
| REPOSITORY | trufflehog | | project | no |
| SPELL | cspell | | 2 | no |
+------------+------------+----------+----------------+------------+
运行结束后,容器会自动删除
检测报告生成在 D:\apps-data\docker\megalinter\lint\megalinter-reports
目录
其中 linters_logs
有详细报告,如下:
以上 ERROR-JAVASCRIPT_STANDARD.log
是 js
检测结果输出,如下
总结
- Megalinter 的 Docker 镜像包很大(9G多),下载比较慢 。
- Megalinter 的结果生成在文件中,并不能拿来直接使用。