Skip to content

Commit 8bb4485

Browse files
author
Venkata Subramani Renduchintala
committed
feat(sre): add Go and Terraform language support with CI validation
- gopls: enable autostart with staticcheck, unusedparams, gofumpt - nvim-dap-go: delve integration with debug-test keymaps (<leader>dt/dT) - terraformls: already autostart; add terraform-ls + tflint to Mason - Treesitter: add go, terraform, hcl parsers to ensure_installed - Mason: add gopls, terraform-ls, tflint, delve (all CI-guarded) - CI: TSUpdateSync step + headless treesitter parser validation - test/fixtures: hello.go and main.tf for parser smoke tests
1 parent 7813c35 commit 8bb4485

9 files changed

Lines changed: 171 additions & 2 deletions

File tree

.github/workflows/validate.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,25 @@ jobs:
7171
nvim-config:ci \
7272
nvim --headless -c "qall"
7373
timeout-minutes: 2
74+
75+
- name: Install treesitter parsers (Go, Terraform, HCL)
76+
run: |
77+
docker run --rm \
78+
-e CI=true \
79+
-v "${{ github.workspace }}:/home/dev/.config/nvim:ro" \
80+
-v "$HOME/.local/share/nvim-ci:/home/dev/.local/share/nvim" \
81+
nvim-config:ci \
82+
nvim --headless -c "TSUpdateSync" -c "qall"
83+
timeout-minutes: 10
84+
85+
- name: Test Go and Terraform treesitter parsers
86+
run: |
87+
docker run --rm \
88+
-e CI=true \
89+
-v "${{ github.workspace }}:/home/dev/.config/nvim:ro" \
90+
-v "$HOME/.local/share/nvim-ci:/home/dev/.local/share/nvim" \
91+
nvim-config:ci \
92+
nvim --headless \
93+
-c "luafile /home/dev/.config/nvim/test/validate_treesitter.lua" \
94+
-c "qall"
95+
timeout-minutes: 2

lua/lsp/configs/go.lua

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
return {
2+
"leoluz/nvim-dap-go",
3+
ft = "go",
4+
dependencies = {
5+
"mfussenegger/nvim-dap",
6+
},
7+
config = function()
8+
require("dap-go").setup({
9+
dap_configurations = {
10+
{
11+
type = "go",
12+
name = "Attach remote",
13+
mode = "remote",
14+
request = "attach",
15+
},
16+
},
17+
delve = {
18+
path = "dlv",
19+
initialize_timeout_sec = 20,
20+
port = "${port}",
21+
args = {},
22+
build_flags = "",
23+
detached = vim.fn.has("win32") == 0,
24+
},
25+
})
26+
27+
local wk = require("which-key")
28+
wk.add({
29+
{ "<leader>dt", "<cmd>lua require('dap-go').debug_test()<cr>", desc = "[GO] Debug test under cursor" },
30+
{ "<leader>dT", "<cmd>lua require('dap-go').debug_last_test()<cr>", desc = "[GO] Debug last test" },
31+
})
32+
end,
33+
}

lua/lsp/init.lua

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,18 @@ if lspconfig then
140140

141141
-- Go Language Server
142142
lspconfig("gopls", {
143-
autostart = false,
143+
autostart = true,
144144
capabilities = capabilities,
145+
settings = {
146+
gopls = {
147+
analyses = {
148+
unusedparams = true,
149+
shadow = true,
150+
},
151+
staticcheck = true,
152+
gofumpt = true,
153+
},
154+
},
145155
})
146156

147157
-- Gradle Language Server

lua/plugins/configs/mason.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ return {
2020
automatic_enable = false,
2121
-- skip heavy binary downloads in CI; lazy.nvim plugin code is still validated
2222
ensure_installed = vim.env.CI and {} or {
23+
"gopls",
24+
"terraform-ls",
2325
"ansiblels",
2426
"awk_ls",
2527
"bashls",
@@ -56,6 +58,7 @@ return {
5658
automatic_installation = not vim.env.CI,
5759
quiet_mode = false,
5860
ensure_installed = vim.env.CI and {} or {
61+
"tflint",
5962
"actionlint",
6063
"ansible-lint",
6164
"api-linter",
@@ -93,6 +96,7 @@ return {
9396
config = function()
9497
require("mason-nvim-dap").setup({
9598
ensure_installed = vim.env.CI and {} or {
99+
"delve",
96100
"codelldb",
97101
"javatest",
98102
"javadbg",

lua/plugins/configs/treesitter.lua

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,11 @@ return {
3636
"javascript",
3737
"typescript",
3838
"vue",
39-
"toml"
39+
"toml",
40+
-- SRE
41+
"go",
42+
"terraform",
43+
"hcl",
4044
},
4145
refactor = {
4246
highlight_definitions = {

lua/plugins/init.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ local plugins = {
8686
require("plugins.configs.mason"),
8787
"neovim/nvim-lspconfig",
8888
require("lsp.configs.dap"),
89+
require("lsp.configs.go"),
8990
require("lsp.configs.java"),
9091
require("lsp.configs.rust"),
9192
require("lsp.configs.python"),

test/fixtures/hello.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"os"
6+
)
7+
8+
func greet(name string) string {
9+
return fmt.Sprintf("Hello, %s!", name)
10+
}
11+
12+
func main() {
13+
name := os.Getenv("USER")
14+
if name == "" {
15+
name = "SRE"
16+
}
17+
fmt.Println(greet(name))
18+
}

test/fixtures/main.tf

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
terraform {
2+
required_version = ">= 1.0"
3+
4+
required_providers {
5+
local = {
6+
source = "hashicorp/local"
7+
version = "~> 2.0"
8+
}
9+
}
10+
}
11+
12+
variable "environment" {
13+
description = "Deployment environment"
14+
type = string
15+
default = "dev"
16+
}
17+
18+
locals {
19+
greeting = "Hello from environment: ${var.environment}"
20+
}
21+
22+
resource "local_file" "hello" {
23+
content = local.greeting
24+
filename = "${path.module}/hello.txt"
25+
}
26+
27+
output "message" {
28+
value = local.greeting
29+
}

test/validate_treesitter.lua

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
-- Headless treesitter validation script.
2+
-- Exit code 1 on any failure so CI catches it.
3+
local errors = {}
4+
5+
local function test_parser(lang, filepath)
6+
local lines = vim.fn.readfile(filepath)
7+
if #lines == 0 then
8+
table.insert(errors, string.format('[%s] fixture not found or empty: %s', lang, filepath))
9+
return
10+
end
11+
12+
local buf = vim.api.nvim_create_buf(false, true)
13+
vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
14+
15+
local ok, result = pcall(vim.treesitter.get_parser, buf, lang)
16+
if not ok then
17+
table.insert(errors, string.format('[%s] parser load failed: %s', lang, tostring(result)))
18+
vim.api.nvim_buf_delete(buf, { force = true })
19+
return
20+
end
21+
22+
local ok2, trees = pcall(function() return result:parse() end)
23+
if not ok2 then
24+
table.insert(errors, string.format('[%s] parse failed: %s', lang, tostring(trees)))
25+
vim.api.nvim_buf_delete(buf, { force = true })
26+
return
27+
end
28+
29+
if not trees or #trees == 0 then
30+
table.insert(errors, string.format('[%s] no parse trees returned', lang))
31+
vim.api.nvim_buf_delete(buf, { force = true })
32+
return
33+
end
34+
35+
vim.api.nvim_buf_delete(buf, { force = true })
36+
print(string.format('OK [%s]: treesitter parser works', lang))
37+
end
38+
39+
local cfg = '/home/dev/.config/nvim'
40+
test_parser('go', cfg .. '/test/fixtures/hello.go')
41+
test_parser('terraform', cfg .. '/test/fixtures/main.tf')
42+
43+
if #errors > 0 then
44+
for _, err in ipairs(errors) do
45+
io.stderr:write('FAIL ' .. err .. '\n')
46+
end
47+
vim.cmd('cquit 1')
48+
end

0 commit comments

Comments
 (0)