From d63f1d9fd11a3d44b80a3099d7b3dcc81fde479b Mon Sep 17 00:00:00 2001 From: Remy Suen Date: Sat, 2 Aug 2025 08:42:13 -0400 Subject: [PATCH 1/3] Refactor URI handling code in Bake inlay hints for \\wsl$ URIs Signed-off-by: Remy Suen --- internal/bake/hcl/inlayHint.go | 4 +- internal/bake/hcl/inlayHint_test.go | 124 +++++++++++++++++----------- 2 files changed, 79 insertions(+), 49 deletions(-) diff --git a/internal/bake/hcl/inlayHint.go b/internal/bake/hcl/inlayHint.go index 519b036..1ac3830 100644 --- a/internal/bake/hcl/inlayHint.go +++ b/internal/bake/hcl/inlayHint.go @@ -25,9 +25,9 @@ func InlayHint(docs *document.Manager, doc document.BakeHCLDocument, rng protoco if block.Type == "target" && len(block.Labels) > 0 { if attribute, ok := block.Body.Attributes["args"]; ok { if expr, ok := attribute.Expr.(*hclsyntax.ObjectConsExpr); ok && len(expr.Items) > 0 { - dockerfilePath, err := doc.DockerfileForTarget(block) + dockerfileURI, dockerfilePath, err := doc.DockerfileDocumentPathForTarget(block) if dockerfilePath != "" && err == nil { - _, nodes := document.OpenDockerfile(context.Background(), docs, "", dockerfilePath) + _, nodes := document.OpenDockerfile(context.Background(), docs, dockerfileURI, dockerfilePath) args := map[string]string{} for _, child := range nodes { if strings.EqualFold(child.Value, "ARG") { diff --git a/internal/bake/hcl/inlayHint_test.go b/internal/bake/hcl/inlayHint_test.go index 143ee0b..5afebf0 100644 --- a/internal/bake/hcl/inlayHint_test.go +++ b/internal/bake/hcl/inlayHint_test.go @@ -15,40 +15,86 @@ import ( "go.lsp.dev/uri" ) -func TestInlayHint(t *testing.T) { - testCases := []struct { - name string - content string - dockerfileContent string - rng protocol.Range - items []protocol.InlayHint - }{ - { - name: "args lookup", - content: "target t1 {\n args = {\n undefined = \"test\"\n empty = \"test\"\n defined = \"test\"\n}\n}", - dockerfileContent: "FROM scratch\nARG undefined\nARG empty=\nARG defined=value\n", - rng: protocol.Range{ - Start: protocol.Position{Line: 0, Character: 0}, - End: protocol.Position{Line: 5, Character: 0}, - }, - items: []protocol.InlayHint{ - { - Label: "(default value: value)", - PaddingLeft: types.CreateBoolPointer(true), - Position: protocol.Position{Line: 4, Character: 20}, - }, - }, +var testCases = []struct { + name string + content string + dockerfileContent string + rng protocol.Range + items []protocol.InlayHint +}{ + { + name: "args lookup", + content: "target t1 {\n args = {\n undefined = \"test\"\n empty = \"test\"\n defined = \"test\"\n}\n}", + dockerfileContent: "FROM scratch\nARG undefined\nARG empty=\nARG defined=value\n", + rng: protocol.Range{ + Start: protocol.Position{Line: 0, Character: 0}, + End: protocol.Position{Line: 5, Character: 0}, }, - { - name: "args lookup outside the range", - content: "target t1 {\n args = {\n undefined = \"test\"\n empty = \"test\"\n defined = \"test\"\n}\n}\n\n\n\n", - dockerfileContent: "FROM scratch\nARG undefined\nARG empty=\nARG defined=value\n", - rng: protocol.Range{ - Start: protocol.Position{Line: 8, Character: 0}, - End: protocol.Position{Line: 8, Character: 0}, + items: []protocol.InlayHint{ + { + Label: "(default value: value)", + PaddingLeft: types.CreateBoolPointer(true), + Position: protocol.Position{Line: 4, Character: 20}, }, - items: []protocol.InlayHint{}, }, + }, + { + name: "args lookup outside the range", + content: "target t1 {\n args = {\n undefined = \"test\"\n empty = \"test\"\n defined = \"test\"\n}\n}\n\n\n\n", + dockerfileContent: "FROM scratch\nARG undefined\nARG empty=\nARG defined=value\n", + rng: protocol.Range{ + Start: protocol.Position{Line: 8, Character: 0}, + End: protocol.Position{Line: 8, Character: 0}, + }, + items: []protocol.InlayHint{}, + }, +} + +func TestInlayHint(t *testing.T) { + bakeFileURI := uri.URI("file:///tmp/docker-bake.hcl") + dockerfileURI := uri.URI("file:///tmp/Dockerfile") + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + manager := document.NewDocumentManager() + changed, err := manager.Write(context.Background(), dockerfileURI, protocol.DockerfileLanguage, 1, []byte(tc.dockerfileContent)) + require.NoError(t, err) + require.True(t, changed) + + doc := document.NewBakeHCLDocument(bakeFileURI, 1, []byte(tc.content)) + items, err := InlayHint(manager, doc, tc.rng) + require.NoError(t, err) + require.Equal(t, tc.items, items) + }) + } +} + +func TestInlayHint_WSL(t *testing.T) { + dockerfileURI := uri.URI("file://wsl%24/docker-desktop/tmp/Dockerfile") + bakeFileURI := uri.URI("file://wsl%24/docker-desktop/tmp/docker-bake.hcl") + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + manager := document.NewDocumentManager() + changed, err := manager.Write(context.Background(), dockerfileURI, protocol.DockerfileLanguage, 1, []byte(tc.dockerfileContent)) + require.NoError(t, err) + require.True(t, changed) + + doc := document.NewBakeHCLDocument(bakeFileURI, 1, []byte(tc.content)) + items, err := InlayHint(manager, doc, tc.rng) + require.NoError(t, err) + require.Equal(t, tc.items, items) + }) + } +} + +func TestInlayHint_TestFiles(t *testing.T) { + testCases := []struct { + name string + content string + rng protocol.Range + items []protocol.InlayHint + }{ { name: "args lookup to a different context folder", content: "target \"backend\" {\n context = \"./backend\"\n args = {\n BACKEND_VAR=\"changed\"\n }\n}", @@ -70,28 +116,12 @@ func TestInlayHint(t *testing.T) { require.NoError(t, err) projectRoot := filepath.Dir(filepath.Dir(filepath.Dir(wd))) inlayHintTestFolderPath := filepath.Join(projectRoot, "testdata", "inlayHint") - dockerfilePath := filepath.Join(inlayHintTestFolderPath, "Dockerfile") bakeFilePath := filepath.Join(inlayHintTestFolderPath, "docker-bake.hcl") bakeFileURI := uri.URI(fmt.Sprintf("file:///%v", strings.TrimPrefix(filepath.ToSlash(bakeFilePath), "/"))) - dockerfileURI := uri.URI(fmt.Sprintf("file:///%v", strings.TrimPrefix(filepath.ToSlash(dockerfilePath), "/"))) for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { manager := document.NewDocumentManager() - if len(tc.content) > 0 { - changed, err := manager.Write(context.Background(), dockerfileURI, protocol.DockerfileLanguage, 1, []byte(tc.dockerfileContent)) - defer manager.Remove(dockerfileURI) - require.NoError(t, err) - require.True(t, changed) - } - bytes := []byte(tc.content) - err := os.WriteFile(bakeFilePath, bytes, 0644) - require.NoError(t, err) - t.Cleanup(func() { - err := os.Remove(bakeFilePath) - require.NoError(t, err) - }) - doc := document.NewBakeHCLDocument(bakeFileURI, 1, []byte(tc.content)) items, err := InlayHint(manager, doc, tc.rng) require.NoError(t, err) From b2fc816798d366eeb1193ce60436920e597ae82e Mon Sep 17 00:00:00 2001 From: Remy Suen Date: Sat, 2 Aug 2025 08:43:05 -0400 Subject: [PATCH 2/3] Add the fix to the changelog Signed-off-by: Remy Suen --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4174fcb..9ab42d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ All notable changes to the Docker Language Server will be documented in this fil - handle WSL URIs with a dollar sign properly to fix build ARG reference lookups on those hosts ([#393](https://github.com/docker/docker-language-server/issues/393)) - textDocument/documentLink - convert links properly if a WSL URI with a dollar sign is used ([#378](https://github.com/docker/docker-language-server/issues/378)) + - textDocument/inlayHint + - refactor the URI handling code so it will process a WSL URI with a dollar sign correctly ([#395](https://github.com/docker/docker-language-server/issues/395)) - textDocument/inlineCompletion - convert links properly if a WSL URI with a dollar sign is used ([#384](https://github.com/docker/docker-language-server/issues/384)) - textDocument/publishDiagnostics From b95842588a143c20c28b5b9e36cd29a16db43c5f Mon Sep 17 00:00:00 2001 From: Remy Suen Date: Sat, 2 Aug 2025 09:14:52 -0400 Subject: [PATCH 3/3] Fix the test path so it can work on all operating systems Signed-off-by: Remy Suen --- internal/bake/hcl/inlayHint_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/bake/hcl/inlayHint_test.go b/internal/bake/hcl/inlayHint_test.go index 5afebf0..f40e794 100644 --- a/internal/bake/hcl/inlayHint_test.go +++ b/internal/bake/hcl/inlayHint_test.go @@ -51,8 +51,9 @@ var testCases = []struct { } func TestInlayHint(t *testing.T) { - bakeFileURI := uri.URI("file:///tmp/docker-bake.hcl") - dockerfileURI := uri.URI("file:///tmp/Dockerfile") + tempDir := os.TempDir() + dockerfileURI := uri.URI(fmt.Sprintf("file:///%v", strings.TrimPrefix(filepath.ToSlash(filepath.Join(tempDir, "Dockerfile")), "/"))) + bakeFileURI := uri.URI(fmt.Sprintf("file:///%v", strings.TrimPrefix(filepath.ToSlash(filepath.Join(tempDir, "docker-bake.hcl")), "/"))) for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) {