Skip to content

Commit

Permalink
feat(workspaces): finish multi chart support
Browse files Browse the repository at this point in the history
  • Loading branch information
qvalentin committed Jan 14, 2024
1 parent 2029128 commit 9d1fcae
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 43 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/bin
/dist
__debug_bin*
.vscode
.coverage
3 changes: 3 additions & 0 deletions internal/charts/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package charts
import (
"path/filepath"

"github.com/mrjosh/helm-ls/internal/util"
"github.com/mrjosh/helm-ls/pkg/chart"
"github.com/mrjosh/helm-ls/pkg/chartutil"
"go.lsp.dev/uri"
Expand All @@ -12,6 +13,7 @@ import (
type ChartMetadata struct {
YamlNode yaml.Node
Metadata chart.Metadata
URI uri.URI
}

func NewChartMetadata(rootURI uri.URI) *ChartMetadata {
Expand All @@ -24,6 +26,7 @@ func NewChartMetadata(rootURI uri.URI) *ChartMetadata {
return &ChartMetadata{
Metadata: loadChartMetadata(filePath),
YamlNode: chartNode,
URI: uri.New(util.FileURIScheme + filePath),
}
}

Expand Down
10 changes: 9 additions & 1 deletion internal/handler/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,17 @@ func completionAstParsing(doc *lsplocal.Document, position lsp.Position) (string
}

func (h *langHandler) getValuesCompletions(chart *charts.Chart, splittedVar []string) (result []lsp.CompletionItem) {
m := make(map[string]lsp.CompletionItem)
for _, valuesFile := range chart.ValuesFiles.AllValuesFiles() {
result = append(result, h.getValue(valuesFile.Values, splittedVar)...)
for _, item := range h.getValue(valuesFile.Values, splittedVar) {
m[item.InsertText] = item
}
}

for _, item := range m {
result = append(result, item)
}

return result
}

Expand Down
36 changes: 31 additions & 5 deletions internal/handler/completion_values_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ func TestEmptyValues(t *testing.T) {
linterName: "helm-lint",
connPool: nil,
documents: nil,
values: make(map[string]interface{}),
}

var result = handler.getValue(make(map[string]interface{}), []string{"global"})
Expand All @@ -35,7 +34,6 @@ func TestValues(t *testing.T) {
linterName: "helm-lint",
connPool: nil,
documents: nil,
values: make(map[string]interface{}),
}
var nested = map[string]interface{}{"nested": "value"}
var values = map[string]interface{}{"global": nested}
Expand Down Expand Up @@ -63,7 +61,6 @@ func TestWrongValues(t *testing.T) {
linterName: "helm-lint",
connPool: nil,
documents: nil,
values: make(map[string]interface{}),
}
var nested = map[string]interface{}{"nested": 1}
var values = map[string]interface{}{"global": nested}
Expand Down Expand Up @@ -107,12 +104,12 @@ func TestCompletionAstParsing(t *testing.T) {
}

}

func TestGetValuesCompletions(t *testing.T) {
handler := &langHandler{
linterName: "helm-lint",
connPool: nil,
documents: nil,
values: make(map[string]interface{}),
}
var nested = map[string]interface{}{"nested": "value"}
var valuesMain = map[string]interface{}{"global": nested}
Expand All @@ -136,9 +133,38 @@ func TestGetValuesCompletions(t *testing.T) {
}

result := handler.getValuesCompletions(chart, []string{"g"})

assert.Equal(t, 2, len(result))

result = handler.getValuesCompletions(chart, []string{"something", "different"})
assert.Empty(t, result)
}

func TestGetValuesCompletionsContainsNoDupliactes(t *testing.T) {
handler := &langHandler{
linterName: "helm-lint",
connPool: nil,
documents: nil,
}
var nested = map[string]interface{}{"nested": "value"}
var valuesMain = map[string]interface{}{"global": nested}
var valuesAdditional = map[string]interface{}{"global": nested}
chart := &charts.Chart{
ValuesFiles: &charts.ValuesFiles{
MainValuesFile: &charts.ValuesFile{
Values: valuesMain,
ValueNode: yaml.Node{},
URI: "",
},
AdditionalValuesFiles: []*charts.ValuesFile{
{
Values: valuesAdditional,
URI: "",
},
},
},
RootURI: "",
}

result := handler.getValuesCompletions(chart, []string{"g"})
assert.Equal(t, 1, len(result))
}
4 changes: 2 additions & 2 deletions internal/handler/definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func (h *langHandler) getDefinitionForFixedIdentifier(chart *charts.Chart, node

case "Chart":
return []lsp.Location{
{URI: h.projectFiles.GetChartFileURI()}},
{URI: chart.ChartMetadata.URI}},
nil
}

Expand All @@ -116,7 +116,7 @@ func (h *langHandler) getDefinitionForValue(chart *charts.Chart, node *sitter.No
return h.getValueDefinition(chart, yamlPath.GetTail()), nil
}
if yamlPath.IsChartPath() {
definitionFileURI = h.projectFiles.GetChartFileURI()
definitionFileURI = chart.ChartMetadata.URI
position, err := h.getChartDefinition(&chart.ChartMetadata.YamlNode, yamlPath.GetTail())
if err == nil {
positions = append(positions, position)
Expand Down
10 changes: 0 additions & 10 deletions internal/handler/definition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,6 @@ func genericDefinitionTest(t *testing.T, position lsp.Position, expectedLocation
linterName: "helm-lint",
connPool: nil,
documents: nil,
values: make(map[string]interface{}),
projectFiles: ProjectFiles{
ValuesFile: "/values.yaml",
ChartFile: "",
},
}

parser := sitter.NewParser()
Expand Down Expand Up @@ -189,11 +184,6 @@ func genericDefinitionTestMultipleValuesFiles(t *testing.T, position lsp.Positio
linterName: "helm-lint",
connPool: nil,
documents: nil,
values: make(map[string]interface{}),
projectFiles: ProjectFiles{
ValuesFile: "/values.yaml",
ChartFile: "",
},
}

parser := sitter.NewParser()
Expand Down
10 changes: 4 additions & 6 deletions internal/handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/mrjosh/helm-ls/internal/charts"
lsplocal "github.com/mrjosh/helm-ls/internal/lsp"
"github.com/mrjosh/helm-ls/internal/util"
"github.com/mrjosh/helm-ls/pkg/chartutil"
"go.lsp.dev/jsonrpc2"
lsp "go.lsp.dev/protocol"

Expand All @@ -24,8 +23,6 @@ type langHandler struct {
linterName string
documents *lsplocal.DocumentStore
chartStore *charts.ChartStore
projectFiles ProjectFiles
values chartutil.Values
yamllsConnector *yamlls.Connector
helmlsConfig util.HelmlsConfiguration
}
Expand All @@ -36,8 +33,6 @@ func NewHandler(connPool jsonrpc2.Conn) jsonrpc2.Handler {
handler := &langHandler{
linterName: "helm-lint",
connPool: connPool,
projectFiles: ProjectFiles{},
values: make(map[string]interface{}),
documents: documents,
helmlsConfig: util.DefaultConfig,
yamllsConnector: &yamlls.Connector{},
Expand Down Expand Up @@ -99,7 +94,10 @@ func (h *langHandler) handleTextDocumentDidOpen(ctx context.Context, reply jsonr

h.yamllsConnector.DocumentDidOpen(doc.Ast, params)

_, _ = h.chartStore.GetChartForDoc(doc.URI)
_, err = h.chartStore.GetChartForDoc(doc.URI)
if err != nil {
logger.Error("Error getting chart info for file", doc.URI, err)
}

doc, ok := h.documents.Get(params.TextDocument.URI)
if !ok {
Expand Down
26 changes: 22 additions & 4 deletions internal/handler/hover.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"path/filepath"
"reflect"
"sort"
"strings"

"github.com/mrjosh/helm-ls/internal/charts"
Expand Down Expand Up @@ -156,9 +157,9 @@ func (h *langHandler) getValueHover(chart *charts.Chart, splittedVar []string) (
var (
valuesFiles = chart.ResolveValueFiles(splittedVar, h.chartStore)
selector = strings.Join(splittedVar, ".")
results = map[uri.URI]string{}
)

results := map[uri.URI]string{}
for _, valuesFiles := range valuesFiles {
for _, valuesFile := range valuesFiles.AllValuesFiles() {
result, err := getTableOrValueForSelector(valuesFile.Values, selector)
Expand All @@ -168,8 +169,24 @@ func (h *langHandler) getValueHover(chart *charts.Chart, splittedVar []string) (
}
}

for uri, value := range results {
result += fmt.Sprintf("# %s\n%s\n\n", filepath.Base(uri.Filename()), value)
keys := make([]string, 0, len(results))
for u := range results {
keys = append(keys, string(u))
}

sort.Sort(sort.Reverse(sort.StringSlice(keys)))

for _, key := range keys {
uriKey := uri.New(key)
value := results[uriKey]
if value == "" {
value = "\"\""
}
filepath, err := filepath.Rel(h.chartStore.RootURI.Filename(), uriKey.Filename())
if err != nil {
filepath = uriKey.Filename()
}
result += fmt.Sprintf("### %s\n%s\n\n", filepath, value)
}
return result, nil
}
Expand All @@ -178,10 +195,11 @@ func getTableOrValueForSelector(values chartutil.Values, selector string) (strin
if len(selector) > 0 {
var localValues, err = values.Table(selector)
if err != nil {
logger.Debug("values.PathValue(tableName)", err)
logger.Debug("values.PathValue(tableName) because of error", err)
var value, err = values.PathValue(selector)
return fmt.Sprint(value), err
}
logger.Debug("converting to YAML", localValues)
return localValues.YAML()
}
return values.YAML()
Expand Down
82 changes: 76 additions & 6 deletions internal/handler/hover_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import (

"github.com/mrjosh/helm-ls/internal/charts"
"github.com/stretchr/testify/assert"
"go.lsp.dev/uri"
)

func Test_langHandler_getValueHover(t *testing.T) {
type args struct {
chart *charts.Chart
parentChart *charts.Chart
splittedVar []string
}
tests := []struct {
Expand All @@ -32,7 +34,7 @@ func Test_langHandler_getValueHover(t *testing.T) {
},
splittedVar: []string{"key"},
},
want: `# values.yaml
want: `### values.yaml
value
`,
Expand All @@ -44,24 +46,92 @@ value
chart: &charts.Chart{
ValuesFiles: &charts.ValuesFiles{
MainValuesFile: &charts.ValuesFile{Values: map[string]interface{}{"key": "value"}, URI: "file://tmp/values.yaml"},
AdditionalValuesFiles: []*charts.ValuesFile{{Values: map[string]interface{}{"key": "other"}, URI: "file://tmp/values.other.yaml"}},
AdditionalValuesFiles: []*charts.ValuesFile{{Values: map[string]interface{}{"key": ""}, URI: "file://tmp/values.other.yaml"}},
},
},
splittedVar: []string{"key"},
},
want: `# values.yaml
want: `### values.yaml
value
# values.other.yaml
other
### values.other.yaml
""
`,
wantErr: false,
},
{
name: "yaml result",
args: args{
chart: &charts.Chart{
ValuesFiles: &charts.ValuesFiles{
MainValuesFile: &charts.ValuesFile{Values: map[string]interface{}{"key": map[string]interface{}{"nested": "value"}}, URI: "file://tmp/values.yaml"},
},
},
splittedVar: []string{"key"},
},
want: `### values.yaml
nested: value
`,
wantErr: false,
},
{
name: "yaml result as list",
args: args{
chart: &charts.Chart{
ValuesFiles: &charts.ValuesFiles{
MainValuesFile: &charts.ValuesFile{Values: map[string]interface{}{"key": []map[string]interface{}{{"nested": "value"}}}, URI: "file://tmp/values.yaml"},
},
},
splittedVar: []string{"key"},
},
want: `### values.yaml
[map[nested:value]]
`,
wantErr: false,
},
{
name: "subchart includes parent values",
args: args{
chart: &charts.Chart{
ValuesFiles: &charts.ValuesFiles{
MainValuesFile: &charts.ValuesFile{Values: map[string]interface{}{"global": map[string]interface{}{"key": "value"}}, URI: "file://tmp/charts/subchart/values.yaml"},
},
ParentChart: charts.ParentChart{
ParentChartURI: uri.New("file://tmp/"),
HasParent: true,
},
},
parentChart: &charts.Chart{
ValuesFiles: &charts.ValuesFiles{
MainValuesFile: &charts.ValuesFile{Values: map[string]interface{}{"global": map[string]interface{}{"key": "parentValue"}}, URI: "file://tmp/values.yaml"},
},
},
splittedVar: []string{"global", "key"},
},
want: `### values.yaml
parentValue
### charts/subchart/values.yaml
value
`,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
h := &langHandler{}
h := &langHandler{
chartStore: &charts.ChartStore{
RootURI: uri.New("file://tmp/"),
Charts: map[uri.URI]*charts.Chart{
uri.New("file://tmp/"): tt.args.parentChart,
},
},
}
got, err := h.getValueHover(tt.args.chart, tt.args.splittedVar)
if (err != nil) != tt.wantErr {
t.Errorf("langHandler.getValueHover() error = %v, wantErr %v", err, tt.wantErr)
Expand Down
Loading

0 comments on commit 9d1fcae

Please sign in to comment.