From fd2d0741106180682a93beceeaabecdb365b82b6 Mon Sep 17 00:00:00 2001 From: Fredrik Averpil Date: Mon, 23 Sep 2024 20:15:55 +0200 Subject: [PATCH] feat: add api-linter https://github.com/googleapis/api-linter --- lua/lint/linters/api-linter.lua | 79 +++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 lua/lint/linters/api-linter.lua diff --git a/lua/lint/linters/api-linter.lua b/lua/lint/linters/api-linter.lua new file mode 100644 index 00000000..9c635c87 --- /dev/null +++ b/lua/lint/linters/api-linter.lua @@ -0,0 +1,79 @@ +local function find_file(filenames) + local found = vim.fs.find(function(name, path) + return vim.tbl_contains(filenames, name) + end, { + limit = 1, + type = "file", + path = ".", + }) + return found[1] +end + +local descriptor_filepath = os.tmpname() +local cleanup_descriptor = function() + os.remove(descriptor_filepath) +end + +--- Function to set the `--descriptor-set-in` argument. +--- This requires the buf CLI, which will first build the descriptor file. +local function descriptor_set_in() + if vim.fn.executable("buf") == 0 then + error("buf CLI not found") + end + + local buffer_parent_dir = vim.fn.expand("%:p:h") + local buf_filenames = { "buf.yaml", "buf.yml" } + local buf_config_filepath = find_file(buf_filenames, buffer_parent_dir) + if buf_config_filepath == nil then + error("Buf config file not found") + end + local buf_config_folderpath = vim.fn.fnamemodify(buf_config_filepath, ":h") + local buf_cmd = { "buf", "build", "-o", descriptor_filepath } + local buf_cmd_opts = { cwd = buf_config_folderpath } + local obj = vim.system(buf_cmd, buf_cmd_opts):wait() + if obj.code ~= 0 then + error("Command failed: " .. vim.inspect(buf_cmd) .. "\n" .. obj.stderr) + end + local descriptor_arg = "--descriptor-set-in=" .. descriptor_filepath + return descriptor_arg +end + +return { + cmd = "api-linter", + stdin = false, + append_fname = true, + args = { + "--output-format=json", + "--disable-rule=core::0191", + descriptor_set_in, + }, + stream = "stdout", + ignore_exitcode = true, + env = nil, + parser = function(output) + if output == "" then + return {} + end + local json_output = vim.json.decode(output) + local diagnostics = {} + if json_output == nil then + return diagnostics + end + for _, item in ipairs(json_output) do + for _, problem in ipairs(item.problems) do + table.insert(diagnostics, { + message = problem.message, + file = item.file, + code = problem.rule_id .. " " .. problem.rule_doc_uri, + severity = vim.diagnostic.severity.WARN, + lnum = problem.location.start_position.line_number - 1, + col = problem.location.start_position.column_number - 1, + end_lnum = problem.location.end_position.line_number - 1, + end_col = problem.location.end_position.column_number - 1, + }) + end + end + cleanup_descriptor() + return diagnostics + end, +}