Skip to content

Commit

Permalink
feat(diagnostics): add regal linter
Browse files Browse the repository at this point in the history
Signed-off-by: Ievgenii Shepeliuk <eshepelyuk@gmail.com>
  • Loading branch information
eshepelyuk committed Nov 17, 2023
1 parent 78cac91 commit 562fcf2
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 21 deletions.
23 changes: 23 additions & 0 deletions doc/tags
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
null-ls-alternatives null-ls.txt /*null-ls-alternatives*
null-ls-community null-ls.txt /*null-ls-community*
null-ls-contributing null-ls.txt /*null-ls-contributing*
null-ls-documentation null-ls.txt /*null-ls-documentation*
null-ls-does-it-work-with-(other-plugin)? null-ls.txt /*null-ls-does-it-work-with-(other-plugin)?*
null-ls-examples null-ls.txt /*null-ls-examples*
null-ls-faq null-ls.txt /*null-ls-faq*
null-ls-features null-ls.txt /*null-ls-features*
null-ls-how-do-i-format-files-on-save? null-ls.txt /*null-ls-how-do-i-format-files-on-save?*
null-ls-how-do-i-format-files? null-ls.txt /*null-ls-how-do-i-format-files?*
null-ls-how-does-it-work? null-ls.txt /*null-ls-how-does-it-work?*
null-ls-migration null-ls.txt /*null-ls-migration*
null-ls-motivation null-ls.txt /*null-ls-motivation*
null-ls-none-ls.nvim null-ls.txt /*null-ls-none-ls.nvim*
null-ls-null-ls.nvim null-ls.txt /*null-ls-null-ls.nvim*
null-ls-parsing-buffer-content null-ls.txt /*null-ls-parsing-buffer-content*
null-ls-parsing-cli-program-output null-ls.txt /*null-ls-parsing-cli-program-output*
null-ls-setup null-ls.txt /*null-ls-setup*
null-ls-status null-ls.txt /*null-ls-status*
null-ls-table-of-contents null-ls.txt /*null-ls-table-of-contents*
null-ls-tests null-ls.txt /*null-ls-tests*
null-ls-will-it-affect-my-performance? null-ls.txt /*null-ls-will-it-affect-my-performance?*
null-ls.txt null-ls.txt /*null-ls.txt*
54 changes: 54 additions & 0 deletions lua/null-ls/builtins/diagnostics/regal.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
local h = require("null-ls.helpers")
local methods = require("null-ls.methods")
local log = require("null-ls.logger")

local handle_regal_output = function(params)
local diags = {}
if params.output.violations ~= nil then
for _, d in ipairs(params.output.violations) do
if d.location ~= nil then
table.insert(diags, {
row = d.location.row,
col = d.location.col,
source = "regal",
message = d.description,
severity = vim.diagnostic.severity.ERROR,
filename = d.location.file,
code = d.title,
})
end
end
elseif params.err ~= nil then
log:error(params.output)
end

return diags
end

return h.make_builtin({
name = "regal",
meta = {
url = "https://docs.styra.com/regal",
description = "Regal is a linter for Rego, with the goal of making your Rego magnificent!.",
},
method = methods.internal.DIAGNOSTICS_ON_SAVE,
filetypes = { "rego" },
generator_opts = {
command = "regal",
args = {
"lint",
"-f",
"json",
"$ROOT",
},
format = "json_raw",
check_exit_code = function(code)
return code <= 1
end,
to_stdin = false,
from_stderr = true,
multiple_files = true,
on_output = handle_regal_output,
},
factory = h.generator_factory,
})
107 changes: 86 additions & 21 deletions test/spec/builtins/diagnostics_spec.lua
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
local mock = require("luassert.mock")
local stub = require("luassert.stub")
local spy = require("luassert.spy")

local diagnostics = require("null-ls.builtins").diagnostics
mock(require("null-ls.logger"), true)

stub(vim, "notify")

describe("diagnostics", function()
describe("spectral", function()
Expand Down Expand Up @@ -1390,19 +1390,20 @@ describe("diagnostics", function()

it("should create a diagnostic with error severity", function()
local output = vim.json.decode([[
{
"errors": [
{
"message": "var tenant_id is unsafe",
"code": "rego_unsafe_var_error",
"location": {
"file": "src/geo.rego",
"row": 49,
"col": 3
{
"errors": [
{
"message": "var tenant_id is unsafe",
"code": "rego_unsafe_var_error",
"location": {
"file": "src/geo.rego",
"row": 49,
"col": 3
}
}
}
]
} ]])
]
}
]])
local diagnostic = parser({ output = output })
assert.same({
{
Expand All @@ -1419,18 +1420,82 @@ describe("diagnostics", function()

it("should not create a diagnostic without location", function()
local output = vim.json.decode([[
{
"errors": [
{
"errors": [
{
"message": "var tenant_id is unsafe",
"code": "rego_unsafe_var_error"
}
]
}
]])
local diagnostic = parser({ output = output })
assert.same({}, diagnostic)
end)

end)

describe("regal", function()
local linter = diagnostics.regal
local parser = linter._opts.on_output

it("should create a diagnostic with error severity", function()
local output = vim.json.decode([[
{
"violations": [
{
"title": "prefer-snake-case",
"description": "Prefer snake_case for names",
"category": "style",
"level": "error",
"location": {
"col": 9,
"row": 3,
"file": "test.rego",
"text": "default allowRbac := true"
}
}
]
}
]])
local diagnostic = parser({ output = output })
assert.same({
{
"message": "var tenant_id is unsafe",
"code": "rego_unsafe_var_error"
}
]
} ]])
row = 3,
col = 9,
severity = 1,
message = "Prefer snake_case for names",
filename = "test.rego",
source = "regal",
code = "prefer-snake-case",
},
}, diagnostic)
end)

it("should not create a diagnostic without location", function()
local output = vim.json.decode([[
{
"violations": [
{
"title": "prefer-snake-case",
"description": "Prefer snake_case for names",
"category": "style",
"level": "error"
}
]
}
]])
local diagnostic = parser({ output = output })
assert.same({}, diagnostic)
end)

it("should log error for non-json output", function()
local diagnostic = parser({ output = "non-json-output", err = "json error" })
assert.same({}, diagnostic)
assert.stub(vim.notify).was_called_with("[null-ls] non-json-output", vim.log.levels.ERROR, { title = "null-ls" })
end)
end)

describe("glslc", function()
local linter = diagnostics.glslc
local parser = linter._opts.on_output
Expand Down

0 comments on commit 562fcf2

Please sign in to comment.