Skip to content

Commit

Permalink
feat(variables): resolve variables in template context
Browse files Browse the repository at this point in the history
  • Loading branch information
qvalentin committed Jun 30, 2024
1 parent 4ea126f commit bd51a17
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 12 deletions.
6 changes: 3 additions & 3 deletions internal/handler/hover_main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,16 @@ func TestHoverMain(t *testing.T) {
Line: 74,
Character: 50,
},
expected: "$root.Values.deployments",
expected: "### ../../testdata/example/values.yaml\nfirst:\n some: value\nsecond:\n some: value\n\n\n",
expectedError: nil,
},
{
desc: "Test hover on template context with variables in range loop",
position: lsp.Position{
Line: 80,
Character: 35,
Character: 31,
},
expected: "$config.hpa.minReplicas",
expected: "### ../../testdata/example/values.yaml\nvalue\n\n",
expectedError: nil,
},
{
Expand Down
7 changes: 7 additions & 0 deletions internal/lsp/symbol_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ func (t TemplateContext) PrependContext(context string) TemplateContext {
return append(TemplateContext{ensureNoLeadingDot(context)}, t...)
}

func NewTemplateContext(string string) TemplateContext {
if string == "." {
return TemplateContext{}
}
return strings.Split(string, ".")
}

func ensureNoLeadingDot(context string) string {
if context[0] == '.' && len(context) > 1 {
return context[1:]
Expand Down
8 changes: 7 additions & 1 deletion internal/lsp/symbol_table_template_context_variables.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,13 @@ func (s *SymbolTable) ResolveVariablesInTemplateContext(templateContext Template

for _, definition := range variableDefinitions {
if util.RangeContainsRange(definition.Scope, pointRange) {
return s.ResolveVariablesInTemplateContext(templateContext.Tail().PrependContext(definition.Value), pointRange)

prefix := NewTemplateContext(definition.Value)
if definition.VariableType == VariableTypeRangeValue && len(prefix) > 0 {
prefix[len(prefix)-1] = prefix[len(prefix)-1] + "[]"
}

return s.ResolveVariablesInTemplateContext(append(prefix, templateContext.Tail()...), pointRange)
}
}
return templateContext, fmt.Errorf("variable %s not found", variableName)
Expand Down
37 changes: 30 additions & 7 deletions internal/lsp/symbol_table_template_context_variables_test.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,42 @@
package lsp

import (
"strings"
"testing"

sitter "github.com/smacker/go-tree-sitter"
"github.com/stretchr/testify/assert"
)

func TestResolveVariablesInTemplateContext(t *testing.T) {
template := "{{ $values := .Values }} {{ $values.test }} "
ast := ParseAst(nil, template)
symbolTable := NewSymbolTable(ast, []byte(template))
result, err := symbolTable.ResolveVariablesInTemplateContext(
TemplateContext{"$values", "test"}, sitter.Range{StartByte: 22, EndByte: 23})
tests := []struct {
template string
templateCtx TemplateContext
expectedCtx TemplateContext
expectedErr error
}{
{"{{ $values := .Values }} {{ $values.te^st }}", TemplateContext{"$values", "test"}, TemplateContext{"", "Values", "test"}, nil},
{"{{- range $type, $config := .Values.deployments }} {{ $config.te^st }}", TemplateContext{"$config", "test"}, TemplateContext{"", "Values", "deployments[]", "test"}, nil},
{" {{ $values := .Values }} {{- range $type, $config := $values.deployments }} {{ $config.te^st }}", TemplateContext{"$config", "test"}, TemplateContext{"", "Values", "deployments[]", "test"}, nil},
}

assert.NoError(t, err)
assert.Equal(t, TemplateContext{"Values", "test"}, result)
for _, tt := range tests {
t.Run(tt.template, func(t *testing.T) {
col := strings.Index(tt.template, "^")
buf := strings.Replace(tt.template, "^", "", 1)
ast := ParseAst(nil, tt.template)
symbolTable := NewSymbolTable(ast, []byte(buf))

result, err := symbolTable.ResolveVariablesInTemplateContext(
tt.templateCtx, sitter.Range{StartByte: uint32(col), EndByte: uint32(col + 1)})

if tt.expectedErr != nil {
assert.Error(t, err)
assert.Equal(t, tt.expectedErr, err)
} else {
assert.NoError(t, err)
assert.Equal(t, tt.expectedCtx, result)
}
})
}
}
2 changes: 1 addition & 1 deletion testdata/example/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ spec:
metadata:
name: my-app-{{ $type }}
spec:
replicas: {{ $config.hpa.minReplicas }}
replicas: {{ $config.some }}
test: {{ $.Values.ingress.hosts }}
---
{{- end }}
Expand Down

0 comments on commit bd51a17

Please sign in to comment.