Skip to content

Commit

Permalink
Merge pull request #58 from mrjosh/feat-multiple-charts
Browse files Browse the repository at this point in the history
Multiple Charts, Subcharts and multiple Values file support
  • Loading branch information
qvalentin authored Feb 3, 2024
2 parents 5e4af6e + 534adde commit 87cbae4
Show file tree
Hide file tree
Showing 43 changed files with 1,734 additions and 606 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/artifacts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
with:
go-version: ${{ matrix.go-version }}
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: build
run: |
make build-release
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ jobs:
steps:

- name: Install Go
uses: actions/setup-go@v2
uses: actions/setup-go@v4
with:
go-version: ${{ matrix.go-version }}

- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Lint
run: make lint
32 changes: 30 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
branches:
- "master"
pull_request:
types: [synchronize]

jobs:

Expand All @@ -18,12 +19,39 @@ jobs:
steps:

- name: Install Go
uses: actions/setup-go@v2
uses: actions/setup-go@v4
with:
go-version: ${{ matrix.go-version }}

- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Run tests
run: make test

tests-windows:
name: tests
strategy:
matrix:
go-version: [1.19.1]
os: [windows-2019]
runs-on: ${{ matrix.os }}
steps:

- name: Install Go
uses: actions/setup-go@v4
with:
go-version: ${{ matrix.go-version }}

- name: Set up MinGW
uses: egor-tensin/setup-mingw@v2
with:
version: 12.2.0

- name: Checkout code
uses: actions/checkout@v4

- name: Run tests
run: make test
env:
CC: "cc"
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
/bin
/dist
__debug_bin*
.vscode
.coverage
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export GOBIN?=$(BIN)
export GO=$(shell which go)
export PACKAGE_NAME=github.com/mrjosh/helm-ls
export GOLANG_CROSS_VERSION=v1.20.6
export CGO_ENABLED=1

$(eval GIT_COMMIT=$(shell git rev-parse --short HEAD))
$(eval BRANCH_NAME=$(shell git symbolic-ref -q --short HEAD || git describe --tags --exact-match))
Expand Down Expand Up @@ -57,6 +58,9 @@ install-metalinter:
test:
@$(GO) test ./... -v -race

coverage:
@$(GO) test -coverprofile=.coverage ./internal/... && go tool cover -html=.coverage

.PHONY: build-release
build-release:
@docker run \
Expand Down
22 changes: 17 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ Helm-ls is a [helm](https://github.com/helm/helm) language server protocol [LSP]
* [Make it executable](#make-it-executable)
* [Integration with yaml-language-server](#integration-with-yaml-language-server)
* [Configuration options](#configuration-options)
* [LSP Server](#lsp-server)
* [General](#general)
* [Values Files](#values-files)
* [yaml-language-server config](#yaml-language-server-config)
* [Default Configuration](#default-configuration)
* [Editor Config examples](#editor-config-examples)
Expand Down Expand Up @@ -93,10 +94,16 @@ kind: ScaledObject
You can configure helm-ls with lsp workspace configurations.
### LSP Server
### General
- **Log Level**: Adjust log verbosity.
### Values Files
- **Main Values File**: Path to the main values file (values.yaml per default)
- **Lint Overlay Values File**: Path to the lint overlay values file, which will be merged with the main values file for linting
- **Additional Values Files Glob Pattern**: Pattern for additional values files, which will be shown for completion and hover
### yaml-language-server config
- **Enable yaml-language-server**: Toggle support of this feature.
Expand All @@ -116,19 +123,24 @@ You can configure helm-ls with lsp workspace configurations.
```lua
settings = {
['helm-ls'] = {
logLevel = "debug",
logLevel = "info",
valuesFiles = {
mainValuesFile = "values.yaml",
lintOverlayValuesFile = "values.lint.yaml",
additionalValuesFilesGlobPattern = "values*.yaml"
},
yamlls = {
enabled = true,
diagnosticsLimit = 50,
showDiagnosticsDirectly = false,
path = "yaml-language-server",
config = {
schemas = {
kubernetes = "**",
kubernetes = "templates/**",
},
completion = true,
hover = true,
-- any other config: https://github.com/redhat-developer/yaml-language-server#language-server-settings
-- any other config from https://github.com/redhat-developer/yaml-language-server#language-server-settings
}
}
}
Expand Down
11 changes: 9 additions & 2 deletions cmds/lint.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"os"

"github.com/mrjosh/helm-ls/internal/charts"
locallsp "github.com/mrjosh/helm-ls/internal/lsp"
"github.com/spf13/cobra"
"go.lsp.dev/uri"
Expand All @@ -14,12 +15,18 @@ func newLintCmd() *cobra.Command {
Use: "lint",
Short: "Lint a helm project",
RunE: func(cmd *cobra.Command, args []string) error {

if len(args) == 0 {
args = append(args, os.Getenv("PWD"))
}

msgs, err := locallsp.GetDiagnostics(uri.New(args[0]))
rootPath := uri.File(args[0])
chartStore := charts.NewChartStore(rootPath, charts.NewChart)
chart, err := chartStore.GetChartForURI(rootPath)
if err != nil {
return err
}

msgs, err := locallsp.GetDiagnostics(rootPath, chart.ValuesFiles.MainValuesFile.Values)
if err != nil {
return err
}
Expand Down
1 change: 0 additions & 1 deletion internal/adapter/fs/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ func (fs *FileStorage) Canonical(path string) string {
}

func (fs *FileStorage) FileExists(path string) (bool, error) {

fi, err := fs.fileInfo(path)
if err != nil {
return false, err
Expand Down
6 changes: 3 additions & 3 deletions internal/adapter/yamlls/trimTemplate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,12 +307,12 @@ func TestTrimTemplate(t *testing.T) {
func testTrimTemplateWithTestData(t *testing.T, testData TrimTemplateTestData) {
doc := &lsplocal.Document{
Content: testData.documentText,
Ast: lsplocal.ParseAst(testData.documentText),
Ast: lsplocal.ParseAst(nil, testData.documentText),
}

var trimmed = trimTemplateForYamllsFromAst(doc.Ast, testData.documentText)
trimmed := trimTemplateForYamllsFromAst(doc.Ast, testData.documentText)

var result = trimmed == testData.trimmedText
result := trimmed == testData.trimmedText

if !result {
t.Errorf("Trimmed templated was not as expected but was %s ", trimmed)
Expand Down
57 changes: 57 additions & 0 deletions internal/charts/chart.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package charts

import (
"github.com/mrjosh/helm-ls/internal/log"
"github.com/mrjosh/helm-ls/internal/util"
"go.lsp.dev/uri"
)

var logger = log.GetLogger()

type Chart struct {
ValuesFiles *ValuesFiles
ChartMetadata *ChartMetadata
RootURI uri.URI
ParentChart ParentChart
}

func NewChart(rootURI uri.URI, valuesFilesConfig util.ValuesFilesConfig) *Chart {
return &Chart{
ValuesFiles: NewValuesFiles(rootURI,
valuesFilesConfig.MainValuesFileName,
valuesFilesConfig.LintOverlayValuesFileName,
valuesFilesConfig.AdditionalValuesFilesGlobPattern),
ChartMetadata: NewChartMetadata(rootURI),
RootURI: rootURI,
ParentChart: newParentChart(rootURI),
}
}

type QueriedValuesFiles struct {
Selector []string
ValuesFiles *ValuesFiles
}

// ResolveValueFiles returns a list of all values files in the chart
// and all parent charts if the query tries to access global values
func (c *Chart) ResolveValueFiles(query []string, chartStore *ChartStore) []*QueriedValuesFiles {
ownResult := []*QueriedValuesFiles{{Selector: query, ValuesFiles: c.ValuesFiles}}
if len(query) == 0 {
return ownResult
}

parentChart := c.ParentChart.GetParentChart(chartStore)
if parentChart == nil {
return ownResult
}

if query[0] == "global" {
return append(ownResult,
parentChart.ResolveValueFiles(query, chartStore)...)
}

chartName := c.ChartMetadata.Metadata.Name
extendedQuery := append([]string{chartName}, query...)
return append(ownResult,
parentChart.ResolveValueFiles(extendedQuery, chartStore)...)
}
70 changes: 70 additions & 0 deletions internal/charts/chart_for_document.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package charts

import (
"fmt"
"os"
"path/filepath"
"strings"

"github.com/mrjosh/helm-ls/pkg/chartutil"
lsp "go.lsp.dev/protocol"
"go.lsp.dev/uri"
)

func (s *ChartStore) GetChartForDoc(uri lsp.DocumentURI) (*Chart, error) {
chart := s.getChartFromCache(uri)
if chart != nil {
return chart, nil
}

chart, err := s.getChartFromFilesystemForTemplates(uri.Filename())
s.Charts[chart.RootURI] = chart
if err != nil {
return chart, ErrChartNotFound{
URI: uri,
}
}
return chart, nil
}

func (s *ChartStore) getChartFromCache(uri lsp.DocumentURI) *Chart {
for chartURI, chart := range s.Charts {
if strings.HasPrefix(uri.Filename(), filepath.Join(chartURI.Filename(), "template")) {
return chart
}
}
return nil
}

func (s *ChartStore) getChartFromFilesystemForTemplates(path string) (*Chart, error) {
directory := filepath.Dir(path)
if filepath.Base(directory) == "templates" {
templatesDir := directory
expectedChartDir := filepath.Dir(templatesDir)

// check if Chart.yaml exists
if isChartDirectory(expectedChartDir) {
return s.newChart(uri.File(expectedChartDir), s.valuesFilesConfig), nil
}
}

rootDirectory := s.RootURI.Filename()
if directory == rootDirectory || directory == path {
return s.newChart(uri.File(directory), s.valuesFilesConfig), ErrChartNotFound{}
}

return s.getChartFromFilesystemForTemplates(directory)
}

func isChartDirectory(expectedChartDir string) bool {
_, err := os.Stat(filepath.Join(expectedChartDir, chartutil.ChartfileName))
return err == nil
}

type ErrChartNotFound struct {
URI lsp.DocumentURI
}

func (e ErrChartNotFound) Error() string {
return fmt.Sprintf("Chart not found for file: %s. Using fallback", e.URI)
}
Loading

0 comments on commit 87cbae4

Please sign in to comment.