Skip to content

Commit

Permalink
Merge branch 'master' into feat/gitlint
Browse files Browse the repository at this point in the history
  • Loading branch information
pbnj authored Oct 14, 2023
2 parents 664f353 + 6d596b8 commit 2b6dacf
Show file tree
Hide file tree
Showing 6 changed files with 226 additions and 36 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ Other dedicated linters that are built-in are:
| [vulture][vulture] | `vulture` |
| [yamllint][yamllint] | `yamllint` |
| [tfsec][tfsec] | `tfsec` |
| [trivy][trivy] | `trivy` |

## Custom Linters

Expand Down Expand Up @@ -389,6 +390,7 @@ busted tests/
[buf_lint]: https://github.com/bufbuild/buf
[erb-lint]: https://github.com/shopify/erb-lint
[tfsec]: https://github.com/aquasecurity/tfsec
[trivy]: https://github.com/aquasecurity/trivy
[djlint]: https://djlint.com/
[buildifier]: https://github.com/bazelbuild/buildtools/tree/master/buildifier
[solhint]: https://protofire.github.io/solhint/
Expand Down
34 changes: 27 additions & 7 deletions lua/lint/linters/eslint.lua
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
local pattern = [[%s*(%d+):(%d+)%s+(%w+)%s+(.+%S)%s+(%S+)]]
local groups = { 'lnum', 'col', 'severity', 'message', 'code' }
local severity_map = {
['error'] = vim.diagnostic.severity.ERROR,
['warn'] = vim.diagnostic.severity.WARN,
['warning'] = vim.diagnostic.severity.WARN,
local severities = {
nil,
vim.diagnostic.severity.ERROR,
vim.diagnostic.severity.WARN,
}

return require('lint.util').inject_cmd_exe({
Expand All @@ -16,12 +14,34 @@ return require('lint.util').inject_cmd_exe({
return 'eslint'
end,
args = {
'--format',
'json',
'--stdin',
'--stdin-filename',
function() return vim.api.nvim_buf_get_name(0) end,
},
stdin = true,
stream = 'stdout',
ignore_exitcode = true,
parser = require('lint.parser').from_pattern(pattern, groups, severity_map, { ['source'] = 'eslint' }),
parser = function(output)
local success, decodedData = pcall(vim.json.decode, output)
local diagnostics = {}

if success and decodedData ~= nil then
for _, diagnostic in ipairs(decodedData.messages or {}) do
table.insert(diagnostics, {
source = "eslint",
lnum = diagnostic.line - 1,
col = diagnostic.column - 1,
end_lnum = diagnostic.endLine - 1,
end_col = diagnostic.endColumn - 1,
severity = severities[diagnostic.severity],
message = diagnostic.message,
code = diagnostic.ruleId
})
end
end

return diagnostics
end
})
34 changes: 27 additions & 7 deletions lua/lint/linters/eslint_d.lua
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
local pattern = [[%s*(%d+):(%d+)%s+(%w+)%s+(.+%S)%s+(%S+)]]
local groups = { 'lnum', 'col', 'severity', 'message', 'code' }
local severity_map = {
['error'] = vim.diagnostic.severity.ERROR,
['warn'] = vim.diagnostic.severity.WARN,
['warning'] = vim.diagnostic.severity.WARN,
local severities = {
nil,
vim.diagnostic.severity.ERROR,
vim.diagnostic.severity.WARN,
}

return require('lint.util').inject_cmd_exe({
Expand All @@ -16,12 +14,34 @@ return require('lint.util').inject_cmd_exe({
return 'eslint_d'
end,
args = {
'--format',
'json',
'--stdin',
'--stdin-filename',
function() return vim.api.nvim_buf_get_name(0) end,
},
stdin = true,
stream = 'stdout',
ignore_exitcode = true,
parser = require('lint.parser').from_pattern(pattern, groups, severity_map, { ['source'] = 'eslint_d' }),
parser = function(output)
local success, decodedData = pcall(vim.json.decode, output)
local diagnostics = {}

if success and decodedData ~= nil then
for _, diagnostic in ipairs(decodedData.messages or {}) do
table.insert(diagnostics, {
source = "eslint_d",
lnum = diagnostic.line - 1,
col = diagnostic.column - 1,
end_lnum = diagnostic.endLine - 1,
end_col = diagnostic.endColumn - 1,
severity = severities[diagnostic.severity],
message = diagnostic.message,
code = diagnostic.ruleId
})
end
end

return diagnostics
end
})
40 changes: 40 additions & 0 deletions lua/lint/linters/trivy.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
local severity_map = {
["LOW"] = vim.diagnostic.severity.INFO,
["MEDIUM"] = vim.diagnostic.severity.WARN,
["HIGH"] = vim.diagnostic.severity.ERROR,
}

return {
cmd = "trivy",
stdin = false,
append_fname = true,
args = { "--scanners", "config", "--format", "json", "fs" },
stream = "stdout",
ignore_exitcode = false,
parser = function(output, bufnr)
local diagnostics = {}
local ok, decoded = pcall(vim.json.decode, output)
if not ok then
return diagnostics
end
local fpath = vim.fn.fnamemodify(vim.api.nvim_buf_get_name(bufnr), ":t")
for _, result in ipairs(decoded and decoded.Results or {}) do
if result.Target == fpath then
for _, misconfig in ipairs(result.Misconfigurations) do
local err = {
source = "trivy",
message = string.format("%s %s", misconfig.Title, misconfig.Description),
col = misconfig.CauseMetadata.StartLine,
end_col = misconfig.CauseMetadata.EndLine,
lnum = misconfig.CauseMetadata.StartLine - 1,
end_lnum = misconfig.CauseMetadata.EndLine - 1,
code = misconfig.ID,
severity = severity_map[misconfig.Severity],
}
table.insert(diagnostics, err)
end
end
end
return diagnostics
end,
}
51 changes: 29 additions & 22 deletions tests/eslint_d_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,48 +7,55 @@ describe("linter.eslint_d", function()

it("can parse output", function()
local parser = require("lint.linters.eslint_d").parser
local result = parser(
[[
/directory/file.js
1:10 error 'testFunc' is defined but never used no-unused-vars
4:16 error This branch can never execute. Its condition is a duplicate or covered by previous conditions in the if-else-if chain no-dupe-else-if

✖ 2 problems (2 errors, 0 warnings)
]],
vim.api.nvim_get_current_buf()
)
local result = parser([[
{
"messages": [
{
"column": 10,
"endColumn": 18,
"endLine": 1,
"line": 1,
"message": "'testFunc' is defined but never used",
"ruleId": "no-unused-vars",
"severity": 2
},
{
"column": 16,
"endColumn": 22,
"endLine": 4,
"line": 4,
"message": "This branch can never execute. Its condition is a duplicate or covered by previous conditions in the if-else-if chain",
"ruleId": "no-dupe-else-if",
"severity": 2
}
]
}]])

assert.are.same(2, #result)

local expected_1 = {
code = "no-unused-vars",
col = 9,
end_col = 9,
end_col = 17,
end_lnum = 0,
lnum = 0,
message = "'testFunc' is defined but never used",
severity = 1,
source = "eslint_d",
user_data = {
lsp = {
code = "no-unused-vars",
},
},
}
assert.are.same(expected_1, result[1])

local expected_2 = {
code = "no-dupe-else-if",
col = 15,
end_col = 15,
end_col = 21,
end_lnum = 3,
lnum = 3,
message = "This branch can never execute. Its condition is a duplicate or covered by previous conditions in the if-else-if chain",
message =
"This branch can never execute. Its condition is a duplicate or covered by previous conditions in the if-else-if chain",
severity = 1,
source = "eslint_d",
user_data = {
lsp = {
code = "no-dupe-else-if",
},
},
}
assert.are.same(expected_2, result[2])
end)
Expand Down
101 changes: 101 additions & 0 deletions tests/trivy_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
describe("linter.trivy", function()
it("Parses output sample", function()
local parser = require("lint.linters.trivy").parser
local bufnr = vim.uri_to_bufnr("file:///main.tf")
local output = [[
{
"SchemaVersion": 2,
"ArtifactName": "main.tf",
"ArtifactType": "filesystem",
"Metadata": {
"ImageConfig": {
"architecture": "",
"created": "0001-01-01T00:00:00Z",
"os": "",
"rootfs": {
"type": "",
"diff_ids": null
},
"config": {}
}
},
"Results": [
{
"Target": ".",
"Class": "config",
"Type": "terraform",
"MisconfSummary": {
"Successes": 1,
"Failures": 0,
"Exceptions": 0
}
},
{
"Target": "main.tf",
"Class": "config",
"Type": "terraform",
"MisconfSummary": {
"Successes": 0,
"Failures": 1,
"Exceptions": 0
},
"Misconfigurations": [
{
"Type": "Terraform Security Check",
"ID": "AVD-AWS-0065",
"AVDID": "AVD-AWS-0065",
"Title": "A KMS key is not configured to auto-rotate.",
"Description": "You should configure your KMS keys to auto rotate to maintain security and defend against compromise.",
"Message": "Key does not have rotation enabled.",
"Query": "data..",
"Resolution": "Configure KMS key to auto rotate",
"Severity": "MEDIUM",
"PrimaryURL": "https://avd.aquasec.com/misconfig/avd-aws-0065",
"References": [
"https://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html",
"https://avd.aquasec.com/misconfig/avd-aws-0065"
],
"Status": "FAIL",
"Layer": {},
"CauseMetadata": {
"Resource": "aws_kms_key.foo",
"Provider": "AWS",
"Service": "kms",
"StartLine": 15,
"EndLine": 15,
"Code": {
"Lines": [
{
"Number": 15,
"Content": "resource \"aws_kms_key\" \"foo\" {}",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"FirstCause": true,
"LastCause": true
}
]
}
}
}
]
}
]
}
]]
local result = parser(output, bufnr)
local expected = {
{
source = "trivy",
message = "A KMS key is not configured to auto-rotate. You should configure your KMS keys to auto rotate to maintain security and defend against compromise.",
lnum = 14,
end_lnum = 14,
col = 15,
end_col = 15,
severity = vim.diagnostic.severity.WARN,
code = "AVD-AWS-0065",
},
}
assert.are.same(expected, result)
end)
end)

0 comments on commit 2b6dacf

Please sign in to comment.