Skip to content

Commit 8fa2d88

Browse files
committed
Support network names in Compose completion items
Signed-off-by: Remy Suen <[email protected]>
1 parent a017089 commit 8fa2d88

File tree

3 files changed

+146
-19
lines changed

3 files changed

+146
-19
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ All notable changes to the Docker Language Server will be documented in this fil
1010
- updated Compose schema to the latest version ([#117](https://github.com/docker/docker-language-server/issues/117))
1111
- textDocument/completion
1212
- suggest dependent service names for the `depends_on` attribute ([#131](https://github.com/docker/docker-language-server/issues/131))
13+
- suggest dependent networks names for the `networks` attribute ([#132](https://github.com/docker/docker-language-server/issues/132))
1314

1415
### Fixed
1516

internal/compose/completion.go

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -156,13 +156,13 @@ func Completion(ctx context.Context, params *protocol.CompletionParams, doc docu
156156
return &protocol.CompletionList{Items: items}, nil
157157
}
158158

159-
func findServices(file *ast.File) []string {
159+
func findDependencies(file *ast.File, dependencyType string) []string {
160160
services := []string{}
161161
for _, documentNode := range file.Docs {
162162
if mappingNode, ok := documentNode.Body.(*ast.MappingNode); ok {
163163
for _, n := range mappingNode.Values {
164164
if s, ok := n.Key.(*ast.StringNode); ok {
165-
if s.Value == "services" {
165+
if s.Value == dependencyType {
166166
if mappingNode, ok := n.Value.(*ast.MappingNode); ok {
167167
for _, service := range mappingNode.Values {
168168
services = append(services, service.Key.GetToken().Value)
@@ -177,27 +177,33 @@ func findServices(file *ast.File) []string {
177177
}
178178

179179
func dependencyCompletionItems(file *ast.File, path []*ast.MappingValueNode, params *protocol.CompletionParams, prefixLength protocol.UInteger) []protocol.CompletionItem {
180-
if len(path) == 3 && path[2].Key.GetToken().Value == "depends_on" {
181-
items := []protocol.CompletionItem{}
182-
for _, service := range findServices(file) {
183-
if service != path[1].Key.GetToken().Value {
184-
item := protocol.CompletionItem{
185-
Label: service,
186-
TextEdit: protocol.TextEdit{
187-
NewText: service,
188-
Range: protocol.Range{
189-
Start: protocol.Position{
190-
Line: params.Position.Line,
191-
Character: params.Position.Character - prefixLength,
180+
dependency := map[string]string{
181+
"depends_on": "services",
182+
"networks": "networks",
183+
}
184+
for key, value := range dependency {
185+
if len(path) == 3 && path[2].Key.GetToken().Value == key {
186+
items := []protocol.CompletionItem{}
187+
for _, service := range findDependencies(file, value) {
188+
if service != path[1].Key.GetToken().Value {
189+
item := protocol.CompletionItem{
190+
Label: service,
191+
TextEdit: protocol.TextEdit{
192+
NewText: service,
193+
Range: protocol.Range{
194+
Start: protocol.Position{
195+
Line: params.Position.Line,
196+
Character: params.Position.Character - prefixLength,
197+
},
198+
End: params.Position,
192199
},
193-
End: params.Position,
194200
},
195-
},
201+
}
202+
items = append(items, item)
196203
}
197-
items = append(items, item)
198204
}
205+
return items
199206
}
200-
return items
201207
}
202208
return nil
203209
}

internal/compose/completion_test.go

Lines changed: 121 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,7 @@ func serviceProperties(line, character, prefixLength protocol.UInteger) []protoc
561561
}
562562
}
563563

564-
func TestCompletion(t *testing.T) {
564+
func TestCompletion_Schema(t *testing.T) {
565565
testCases := []struct {
566566
name string
567567
content string
@@ -1832,6 +1832,37 @@ networks:
18321832
character: 2,
18331833
list: nil,
18341834
},
1835+
}
1836+
1837+
composeFileURI := fmt.Sprintf("file:///%v", strings.TrimPrefix(filepath.ToSlash(filepath.Join(os.TempDir(), "compose.yaml")), "/"))
1838+
1839+
for _, tc := range testCases {
1840+
t.Run(tc.name, func(t *testing.T) {
1841+
doc := document.NewComposeDocument(uri.URI(composeFileURI), 1, []byte(tc.content))
1842+
list, err := Completion(context.Background(), &protocol.CompletionParams{
1843+
TextDocumentPositionParams: protocol.TextDocumentPositionParams{
1844+
TextDocument: protocol.TextDocumentIdentifier{URI: composeFileURI},
1845+
Position: protocol.Position{Line: tc.line, Character: tc.character},
1846+
},
1847+
}, doc)
1848+
require.NoError(t, err)
1849+
if tc.list == nil {
1850+
require.Nil(t, list)
1851+
} else {
1852+
require.Equal(t, tc.list, list)
1853+
}
1854+
})
1855+
}
1856+
}
1857+
1858+
func TestCompletion_Custom(t *testing.T) {
1859+
testCases := []struct {
1860+
name string
1861+
content string
1862+
line uint32
1863+
character uint32
1864+
list *protocol.CompletionList
1865+
}{
18351866
{
18361867
name: "depends_on array items",
18371868
content: `
@@ -1906,6 +1937,95 @@ services:
19061937
image: alpine
19071938
depends_on:
19081939
1940+
test2:
1941+
image: alpine`,
1942+
line: 5,
1943+
character: 6,
1944+
list: &protocol.CompletionList{
1945+
Items: []protocol.CompletionItem{
1946+
{
1947+
Label: "test2",
1948+
TextEdit: textEdit("test2", 5, 6, 0),
1949+
},
1950+
},
1951+
},
1952+
},
1953+
{
1954+
name: "networks array items",
1955+
content: `
1956+
services:
1957+
test:
1958+
image: alpine
1959+
networks:
1960+
-
1961+
networks:
1962+
test2:
1963+
image: alpine`,
1964+
line: 5,
1965+
character: 8,
1966+
list: &protocol.CompletionList{
1967+
Items: []protocol.CompletionItem{
1968+
{
1969+
Label: "test2",
1970+
TextEdit: textEdit("test2", 5, 8, 0),
1971+
},
1972+
},
1973+
},
1974+
},
1975+
{
1976+
name: "networks array items across two files",
1977+
content: `
1978+
---
1979+
services:
1980+
test:
1981+
image: alpine
1982+
networks:
1983+
-
1984+
---
1985+
networks:
1986+
test2:`,
1987+
line: 6,
1988+
character: 8,
1989+
list: &protocol.CompletionList{
1990+
Items: []protocol.CompletionItem{
1991+
{
1992+
Label: "test2",
1993+
TextEdit: textEdit("test2", 6, 8, 0),
1994+
},
1995+
},
1996+
},
1997+
},
1998+
{
1999+
name: "networks array items",
2000+
content: `
2001+
services:
2002+
test:
2003+
image: alpine
2004+
networks:
2005+
- t
2006+
networks:
2007+
test2:
2008+
image: alpine`,
2009+
line: 5,
2010+
character: 9,
2011+
list: &protocol.CompletionList{
2012+
Items: []protocol.CompletionItem{
2013+
{
2014+
Label: "test2",
2015+
TextEdit: textEdit("test2", 5, 9, 1),
2016+
},
2017+
},
2018+
},
2019+
},
2020+
{
2021+
name: "networks service object",
2022+
content: `
2023+
services:
2024+
test:
2025+
image: alpine
2026+
networks:
2027+
2028+
networks:
19092029
test2:
19102030
image: alpine`,
19112031
line: 5,

0 commit comments

Comments
 (0)