Skip to content

Commit 82204fd

Browse files
authored
fix: consume dockerfile arguments when parsing the image (#45)
1 parent 85f220a commit 82204fd

File tree

2 files changed

+42
-7
lines changed

2 files changed

+42
-7
lines changed

devcontainer/devcontainer.go

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -258,21 +258,34 @@ func UserFromDockerfile(dockerfileContent string) string {
258258
// ImageFromDockerfile inspects the contents of a provided Dockerfile
259259
// and returns the image that will be used to run the container.
260260
func ImageFromDockerfile(dockerfileContent string) (name.Reference, error) {
261+
args := map[string]string{}
262+
var imageRef string
261263
lines := strings.Split(dockerfileContent, "\n")
262264
// Iterate over lines in reverse
263265
for i := len(lines) - 1; i >= 0; i-- {
264266
line := lines[i]
265-
if !strings.HasPrefix(line, "FROM ") {
267+
if strings.HasPrefix(line, "ARG ") {
268+
arg := strings.TrimSpace(strings.TrimPrefix(line, "ARG "))
269+
if strings.Contains(arg, "=") {
270+
parts := strings.SplitN(arg, "=", 2)
271+
args[parts[0]] = parts[1]
272+
}
266273
continue
267274
}
268-
imageRef := strings.TrimSpace(strings.TrimPrefix(line, "FROM "))
269-
image, err := name.ParseReference(imageRef)
270-
if err != nil {
271-
return nil, fmt.Errorf("parse image ref %q: %w", imageRef, err)
275+
if imageRef == "" && strings.HasPrefix(line, "FROM ") {
276+
imageRef = strings.TrimPrefix(line, "FROM ")
272277
}
273-
return image, nil
274278
}
275-
return nil, fmt.Errorf("no FROM directive found")
279+
if imageRef == "" {
280+
return nil, fmt.Errorf("no FROM directive found")
281+
}
282+
image, err := name.ParseReference(os.Expand(imageRef, func(s string) string {
283+
return args[s]
284+
}))
285+
if err != nil {
286+
return nil, fmt.Errorf("parse image ref %q: %w", imageRef, err)
287+
}
288+
return image, nil
276289
}
277290

278291
// UserFromImage inspects the remote reference and returns the user

devcontainer/devcontainer_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,28 @@ func TestUserFromDockerfile(t *testing.T) {
151151
require.Equal(t, "kyle", user)
152152
}
153153

154+
func TestImageFromDockerfile(t *testing.T) {
155+
t.Parallel()
156+
for _, tc := range []struct {
157+
content string
158+
image string
159+
}{{
160+
content: "FROM ubuntu",
161+
image: "index.docker.io/library/ubuntu:latest",
162+
}, {
163+
content: "ARG VARIANT=ionic\nFROM ubuntu:$VARIANT",
164+
image: "index.docker.io/library/ubuntu:ionic",
165+
}} {
166+
tc := tc
167+
t.Run(tc.image, func(t *testing.T) {
168+
t.Parallel()
169+
ref, err := devcontainer.ImageFromDockerfile(tc.content)
170+
require.NoError(t, err)
171+
require.Equal(t, tc.image, ref.Name())
172+
})
173+
}
174+
}
175+
154176
func TestUserFromImage(t *testing.T) {
155177
t.Parallel()
156178
registry := registrytest.New(t)

0 commit comments

Comments
 (0)