Skip to content

Commit e66bb49

Browse files
committed
Add tests for value substition on Dockerfile
1 parent 38be661 commit e66bb49

File tree

6 files changed

+272
-47
lines changed

6 files changed

+272
-47
lines changed

.devcontainer/devcontainer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
// "forwardPorts": [],
5959

6060
// Use 'postCreateCommand' to run commands after the container is created.
61-
"postCreateCommand": "sudo chown $(whoami) /go/pkg",
61+
"postCreateCommand": "make post-create",
6262

6363
// Uncomment to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root.
6464
"remoteUser": "vscode"

.vscode/launch.json

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,14 @@
1111
"mode": "auto",
1212
"program": "${workspaceFolder}/cmd/devcontainer",
1313
"env": {},
14-
"args": ["template", "list"]
14+
"args": ["template", "list"],
15+
"dlvLoadConfig": {
16+
"followPointers": true,
17+
"maxVariableRecurse": 1,
18+
"maxStringLen": 512,
19+
"maxArrayValues": 64,
20+
"maxStructFields": -1
21+
}
1522
},
1623
{
1724
"name": "Connect to server",
@@ -21,6 +28,13 @@
2128
"remotePath": "${workspaceFolder}",
2229
"port": 2345,
2330
"host": "127.0.0.1",
31+
"dlvLoadConfig": {
32+
"followPointers": true,
33+
"maxVariableRecurse": 1,
34+
"maxStringLen": 512,
35+
"maxArrayValues": 64,
36+
"maxStructFields": -1
37+
}
2438
},
2539
]
2640
}

.vscode/settings.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"go.delveConfig": {
3+
"dlvLoadConfig": {
4+
"followPointers": true,
5+
"maxVariableRecurse": 1,
6+
"maxStringLen": 512,
7+
"maxArrayValues": 64,
8+
"maxStructFields": -1
9+
},
10+
"apiVersion": 2,
11+
"showGlobalVariables": false,
12+
"debugAdapter": "legacy"
13+
}
14+
}

Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,9 @@ test:
3535

3636

3737
fmt:
38-
find . -name '*.go' | grep -v vendor | xargs gofmt -s -w
38+
find . -name '*.go' | grep -v vendor | xargs gofmt -s -w
39+
40+
41+
post-create:
42+
sudo chown vscode /go/pkg
43+
go get -u github.com/kyoh86/richgo

internal/pkg/devcontainers/snippet.go

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package devcontainers
22

33
import (
4-
"bytes"
54
"encoding/json"
65
"fmt"
76
"io/ioutil"
@@ -225,7 +224,7 @@ func addFolderSnippetToDevContainer(projectFolder string, snippet *DevcontainerS
225224
return fmt.Errorf("content must be set for %s actions", action.Type)
226225
}
227226
dockerfileFilename := filepath.Join(projectFolder, ".devcontainer", "Dockerfile")
228-
err = insertDockerfileSnippet(dockerfileFilename, action.Content+"\n")
227+
err = insertDockerfileSnippet(projectFolder, dockerfileFilename, action.Content+"\n")
229228
if err != nil {
230229
return err
231230
}
@@ -251,11 +250,11 @@ RUN /tmp/%[2]s
251250
`, snippet.Name, scriptFilename)
252251
dockerfileFilename := filepath.Join(projectFolder, ".devcontainer", "Dockerfile")
253252

254-
err := insertDockerfileSnippet(dockerfileFilename, snippetContent)
253+
err := insertDockerfileSnippet(projectFolder, dockerfileFilename, snippetContent)
255254
return err
256255
}
257256

258-
func insertDockerfileSnippet(dockerfileFilename string, snippetContent string) error {
257+
func insertDockerfileSnippet(projectFolder string, dockerfileFilename string, snippetContent string) error {
259258

260259
buf, err := ioutil.ReadFile(dockerfileFilename)
261260
if err != nil {
@@ -266,7 +265,7 @@ func insertDockerfileSnippet(dockerfileFilename string, snippetContent string) e
266265
dockerFileLines := strings.Split(dockerfileContent, "\n")
267266
addSeparator := false
268267
addedSnippetContent := false
269-
var newContent bytes.Buffer
268+
var newContent strings.Builder
270269
for _, line := range dockerFileLines {
271270
if addSeparator {
272271
if _, err = newContent.WriteString("\n"); err != nil {
@@ -301,7 +300,14 @@ func insertDockerfileSnippet(dockerfileFilename string, snippetContent string) e
301300
}
302301
}
303302

304-
err = ioutil.WriteFile(dockerfileFilename, newContent.Bytes(), 0)
303+
content := newContent.String()
304+
values, err := getSubstitutionValuesFromFile(filepath.Join(projectFolder, ".devcontainer/devcontainer.json"))
305+
if err != nil {
306+
return fmt.Errorf("failed to get dev container values: %s", err)
307+
}
308+
content = performSubstitutionString(values, content)
309+
310+
err = ioutil.WriteFile(dockerfileFilename, []byte(content), 0)
305311

306312
return err
307313

@@ -333,21 +339,11 @@ func mergeJSON(projectFolder string, snippet *DevcontainerSnippet, relativeMerge
333339
return err
334340
}
335341

336-
// replace __DEVCONTAINER_NAME__ with name
337-
devcontainerName, devcontainerUserName := getDevcontainerNameAndUserName(filepath.Join(projectFolder, ".devcontainer/devcontainer.json"))
338-
if devcontainerName == "" {
339-
return fmt.Errorf("failed to get dev container name")
340-
}
341-
resultJSON = strings.ReplaceAll(resultJSON, "__DEVCONTAINER_NAME__", devcontainerName)
342-
if devcontainerUserName == "" {
343-
devcontainerUserName = "root"
344-
}
345-
devcontainerHome := "/home/" + devcontainerUserName
346-
if devcontainerUserName == "root" {
347-
devcontainerHome = "/root"
342+
values, err := getSubstitutionValuesFromFile(filepath.Join(projectFolder, ".devcontainer/devcontainer.json"))
343+
if err != nil {
344+
return fmt.Errorf("failed to get dev container values: %s", err)
348345
}
349-
resultJSON = strings.ReplaceAll(resultJSON, "__DEVCONTAINER_USER_NAME__", devcontainerUserName)
350-
resultJSON = strings.ReplaceAll(resultJSON, "__DEVCONTAINER_HOME__", devcontainerHome)
346+
resultJSON = performSubstitutionString(values, resultJSON)
351347

352348
err = ioutil.WriteFile(basePath, []byte(resultJSON), 0666)
353349
if err != nil {
@@ -372,17 +368,23 @@ func loadJSONDocument(path string) (*dora_ast.RootNode, error) {
372368
return &baseDocument, nil
373369
}
374370

375-
func getDevcontainerNameAndUserName(devContainerJsonPath string) (string, string) {
371+
type SubstitutionValues struct {
372+
Name string
373+
UserName string
374+
HomeFolder string
375+
}
376+
377+
func getSubstitutionValuesFromFile(devContainerJsonPath string) (*SubstitutionValues, error) {
376378
// This doesn't use standard `json` pkg as devcontainer.json permits comments (and the default templates include them!)
377379

378380
buf, err := ioutil.ReadFile(devContainerJsonPath)
379381
if err != nil {
380-
return "", ""
382+
return nil, err
381383
}
382384

383385
c, err := dora.NewFromBytes(buf)
384386
if err != nil {
385-
return "", ""
387+
return nil, err
386388
}
387389

388390
name, err := c.GetString("$.name")
@@ -391,8 +393,24 @@ func getDevcontainerNameAndUserName(devContainerJsonPath string) (string, string
391393
}
392394
userName, err := c.GetString("$.remoteUser")
393395
if err != nil {
394-
userName = ""
396+
userName = "root"
395397
}
398+
homeFolder := "/home/" + userName
399+
if userName == "root" {
400+
homeFolder = "/root"
401+
}
402+
403+
return &SubstitutionValues{
404+
Name: name,
405+
UserName: userName,
406+
HomeFolder: homeFolder,
407+
}, nil
408+
}
396409

397-
return name, userName
410+
func performSubstitutionString(substitutionValues *SubstitutionValues, content string) string {
411+
// replace __DEVCONTAINER_NAME__ with name etc
412+
content = strings.ReplaceAll(content, "__DEVCONTAINER_NAME__", substitutionValues.Name)
413+
content = strings.ReplaceAll(content, "__DEVCONTAINER_USER_NAME__", substitutionValues.UserName)
414+
content = strings.ReplaceAll(content, "__DEVCONTAINER_HOME__", substitutionValues.HomeFolder)
415+
return content
398416
}

0 commit comments

Comments
 (0)