Skip to content

Commit

Permalink
fix: support building features that call bundled scripts (#64)
Browse files Browse the repository at this point in the history
Co-authored-by: Aaron Lehmann <[email protected]>
  • Loading branch information
kconley-sq and aaronlehmann authored Nov 2, 2023
1 parent 1eb3514 commit e5e1a8f
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 13 deletions.
10 changes: 6 additions & 4 deletions devcontainer/devcontainer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,19 +91,21 @@ func TestCompileWithFeatures(t *testing.T) {

// We have to SHA because we get a different MD5 every time!
featureOneMD5 := md5.Sum([]byte(featureOne))
featureOneSha := fmt.Sprintf("%x", featureOneMD5[:4])
featureOneDir := fmt.Sprintf(".envbuilder/features/one-%x", featureOneMD5[:4])
featureTwoMD5 := md5.Sum([]byte(featureTwo))
featureTwoSha := fmt.Sprintf("%x", featureTwoMD5[:4])
featureTwoDir := fmt.Sprintf(".envbuilder/features/two-%x", featureTwoMD5[:4])

require.Equal(t, `FROM codercom/code-server:latest
USER root
# Rust tomato - Example description!
WORKDIR `+featureOneDir+`
ENV TOMATO=example
RUN .envbuilder/features/one-`+featureOneSha+`/install.sh
RUN ./install.sh
# Go potato - Example description!
WORKDIR `+featureTwoDir+`
ENV POTATO=example
RUN VERSION=potato .envbuilder/features/two-`+featureTwoSha+`/install.sh
RUN VERSION=potato ./install.sh
USER 1000`, params.DockerfileContent)
}

Expand Down
7 changes: 4 additions & 3 deletions devcontainer/features/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func Extract(fs billy.Filesystem, directory, reference string) (*Spec, error) {
return nil, errors.New(`devcontainer-feature.json: name is required`)
}

spec.InstallScriptPath = installScriptPath
spec.Directory = directory
return spec, nil
}

Expand All @@ -164,7 +164,7 @@ type Spec struct {
Options map[string]Option `json:"options"`
ContainerEnv map[string]string `json:"containerEnv"`

InstallScriptPath string `json:"-"`
Directory string `json:"-"`
}

// Extract unpacks the feature from the image and returns a set of lines
Expand All @@ -189,7 +189,7 @@ func (s *Spec) Compile(options map[string]any) (string, error) {
sort.Strings(runDirective)
// See https://containers.dev/implementors/features/#invoking-installsh
runDirective = append([]string{"RUN"}, runDirective...)
runDirective = append(runDirective, s.InstallScriptPath)
runDirective = append(runDirective, "./install.sh")

comment := ""
if s.Name != "" {
Expand All @@ -205,6 +205,7 @@ func (s *Spec) Compile(options map[string]any) (string, error) {
if comment != "" {
lines = append(lines, comment)
}
lines = append(lines, "WORKDIR "+s.Directory)
envKeys := make([]string, 0, len(s.ContainerEnv))
for key := range s.ContainerEnv {
envKeys = append(envKeys, key)
Expand Down
12 changes: 6 additions & 6 deletions devcontainer/features/features_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,28 +81,28 @@ func TestCompile(t *testing.T) {
t.Run("Basic", func(t *testing.T) {
t.Parallel()
spec := &features.Spec{
InstallScriptPath: "install.sh",
Directory: "/",
}
directive, err := spec.Compile(nil)
require.NoError(t, err)
require.Equal(t, "RUN install.sh", strings.TrimSpace(directive))
require.Equal(t, "WORKDIR /\nRUN ./install.sh", strings.TrimSpace(directive))
})
t.Run("ContainerEnv", func(t *testing.T) {
t.Parallel()
spec := &features.Spec{
InstallScriptPath: "install.sh",
Directory: "/",
ContainerEnv: map[string]string{
"FOO": "bar",
},
}
directive, err := spec.Compile(nil)
require.NoError(t, err)
require.Equal(t, "ENV FOO=bar\nRUN install.sh", strings.TrimSpace(directive))
require.Equal(t, "WORKDIR /\nENV FOO=bar\nRUN ./install.sh", strings.TrimSpace(directive))
})
t.Run("OptionsEnv", func(t *testing.T) {
t.Parallel()
spec := &features.Spec{
InstallScriptPath: "install.sh",
Directory: "/",
Options: map[string]features.Option{
"foo": {
Default: "bar",
Expand All @@ -111,6 +111,6 @@ func TestCompile(t *testing.T) {
}
directive, err := spec.Compile(nil)
require.NoError(t, err)
require.Equal(t, "RUN FOO=bar install.sh", strings.TrimSpace(directive))
require.Equal(t, "WORKDIR /\nRUN FOO=bar ./install.sh", strings.TrimSpace(directive))
})
}

0 comments on commit e5e1a8f

Please sign in to comment.