Skip to content

Commit aef293c

Browse files
authored
Merge pull request #27 from stuartleeks/sl/set-devcontainer-name
Set devcontainer.json name property when adding a template
2 parents 12a2ed3 + b88a5a0 commit aef293c

File tree

3 files changed

+90
-1
lines changed

3 files changed

+90
-1
lines changed

cmd/devcontainer/template.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"io/ioutil"
66
"os"
7+
"path/filepath"
78
"sort"
89
"text/tabwriter"
910

@@ -63,6 +64,7 @@ func createTemplateListCommand() *cobra.Command {
6364
}
6465

6566
func createTemplateAddCommand() *cobra.Command {
67+
var devcontainerName string
6668
cmd := &cobra.Command{
6769
Use: "add TEMPLATE_NAME",
6870
Short: "add devcontainer from template",
@@ -94,7 +96,22 @@ func createTemplateAddCommand() *cobra.Command {
9496
if err = ioutil2.CopyFolder(template.Path, currentDirectory+"/.devcontainer"); err != nil {
9597
return fmt.Errorf("Error copying folder: %s\n", err)
9698
}
97-
return err
99+
100+
// by default the "name" in devcontainer.json is set to the name of the template
101+
// override it here with the value passed in as --devcontainer-name (or the containing folder if not set)
102+
if devcontainerName == "" {
103+
devcontainerName, err = devcontainers.GetDefaultDevcontainerNameForFolder(currentDirectory)
104+
if err != nil {
105+
return fmt.Errorf("Error getting default devcontainer name: %s", err)
106+
}
107+
}
108+
devcontainerJsonPath := filepath.Join(currentDirectory, ".devcontainer/devcontainer.json")
109+
err = devcontainers.SetDevcontainerName(devcontainerJsonPath, devcontainerName)
110+
if err != nil {
111+
return fmt.Errorf("Error setting devcontainer name: %s", err)
112+
}
113+
114+
return nil
98115
},
99116
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
100117
// only completing the first arg (template name)
@@ -113,6 +130,7 @@ func createTemplateAddCommand() *cobra.Command {
113130
return names, cobra.ShellCompDirectiveNoFileComp
114131
},
115132
}
133+
cmd.Flags().StringVar(&devcontainerName, "devcontainer-name", "", "Value to set the devcontainer.json name property to (default is folder name)")
116134
return cmd
117135
}
118136

internal/pkg/devcontainers/template.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"io/ioutil"
66
"os"
77
"path/filepath"
8+
"regexp"
89
"sort"
910

1011
"github.com/stuartleeks/devcontainer-cli/internal/pkg/config"
@@ -86,3 +87,33 @@ func getTemplatesFromFolder(folder string) ([]DevcontainerTemplate, error) {
8687
}
8788
return templates, nil
8889
}
90+
91+
func GetDefaultDevcontainerNameForFolder(folderPath string) (string, error) {
92+
93+
absPath, err := filepath.Abs(folderPath)
94+
if err != nil {
95+
return "", err
96+
}
97+
98+
_, folderName := filepath.Split(absPath)
99+
return folderName, nil
100+
}
101+
102+
func SetDevcontainerName(devContainerJsonPath string, name string) error {
103+
// This doesn't use `json` as devcontainer.json permits comments (and the default templates include them!)
104+
105+
buf, err := ioutil.ReadFile(devContainerJsonPath)
106+
if err != nil {
107+
return fmt.Errorf("error reading file %q: %s", devContainerJsonPath, err)
108+
}
109+
110+
r := regexp.MustCompile("(\"name\"\\s*:\\s*\")[^\"]*(\")")
111+
replacement := []byte("${1}" + name + "${2}")
112+
buf = r.ReplaceAll(buf, replacement)
113+
114+
if err = ioutil.WriteFile(devContainerJsonPath, buf, 0777); err != nil {
115+
return fmt.Errorf("error writing file %q: %s", devContainerJsonPath, err)
116+
}
117+
118+
return nil
119+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package devcontainers
2+
3+
import (
4+
"io/ioutil"
5+
"os"
6+
"testing"
7+
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
func TestSetDevcontainerName(t *testing.T) {
12+
13+
f, err := ioutil.TempFile("", "test.json")
14+
assert.NoError(t, err)
15+
defer os.Remove(f.Name())
16+
17+
_, _ = f.WriteString(`{
18+
"name": "initial",
19+
// here's a comment!
20+
"otherProperties": [
21+
"something",
22+
"here"
23+
]
24+
}`)
25+
26+
err = SetDevcontainerName(f.Name(), "newName")
27+
assert.NoError(t, err)
28+
29+
buf, err := ioutil.ReadFile(f.Name())
30+
assert.NoError(t, err)
31+
32+
assert.Equal(t, `{
33+
"name": "newName",
34+
// here's a comment!
35+
"otherProperties": [
36+
"something",
37+
"here"
38+
]
39+
}`, string(buf))
40+
}

0 commit comments

Comments
 (0)