Skip to content

Commit

Permalink
dockerfile: add syntax directive for introducing new features
Browse files Browse the repository at this point in the history
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
  • Loading branch information
tonistiigi committed May 14, 2018
1 parent fc888e6 commit d4d57dd
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 0 deletions.
21 changes: 21 additions & 0 deletions frontend/dockerfile/builder/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,13 @@ func Build(ctx context.Context, c client.Client) error {
return err
}

if _, ok := c.Opts()["cmdline"]; !ok {
ref, argv, ok := dockerfile2llb.DetectSyntax(bytes.NewBuffer(dtDockerfile))
if ok {
return forwardGateway(ctx, c, ref, argv)
}
}

st, img, err := dockerfile2llb.Dockerfile2LLB(ctx, dtDockerfile, dockerfile2llb.ConvertOpt{
Target: opts[keyTarget],
MetaResolver: c,
Expand Down Expand Up @@ -158,6 +165,20 @@ func Build(ctx context.Context, c client.Client) error {
return nil
}

func forwardGateway(ctx context.Context, c client.Client, ref string, argv string) error {
opts := c.Opts()
if opts == nil {
opts = map[string]string{}
}
opts["cmdline"] = argv
opts["source"] = ref
_, err := c.Solve(ctx, client.SolveRequest{
Frontend: "gateway.v0",
FrontendOpt: opts,
}, nil, true)
return err
}

func filter(opt map[string]string, key string) map[string]string {
m := map[string]string{}
for k, v := range opt {
Expand Down
38 changes: 38 additions & 0 deletions frontend/dockerfile/dockerfile2llb/directives.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package dockerfile2llb

import (
"bufio"
"io"
"regexp"
"strings"
)

const keySyntax = "syntax"

var reDirective = regexp.MustCompile(`^#\s*([a-z][a-z0-9]*)\s*=\s*(.+?)\s*$`)

func DetectSyntax(r io.Reader) (string, string, bool) {
directives := ParseDirectives(r)
if len(directives) == 0 {
return "", "", false
}
v, ok := directives[keySyntax]
if !ok {
return "", "", false
}
p := strings.SplitN(v, " ", 2)
return p[0], v, true
}

func ParseDirectives(r io.Reader) map[string]string {
m := map[string]string{}
s := bufio.NewScanner(r)
for s.Scan() {
match := reDirective.FindStringSubmatch(s.Text())
if len(match) == 0 {
return m
}
m[match[1]] = match[2]
}
return m
}
52 changes: 52 additions & 0 deletions frontend/dockerfile/dockerfile2llb/directives_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package dockerfile2llb

import (
"bytes"
"fmt"
"testing"

"github.com/stretchr/testify/require"
)

func TestDirectives(t *testing.T) {
t.Parallel()

dt := `#escape=\
# key = FOO bar
# smth
`

d := ParseDirectives(bytes.NewBuffer([]byte(dt)))
require.Equal(t, len(d), 2, fmt.Sprintf("%+v", d))

v, ok := d["escape"]
require.True(t, ok)
require.Equal(t, v, "\\")

v, ok = d["key"]
require.True(t, ok)
require.Equal(t, v, "FOO bar")
}

func TestSyntaxDirective(t *testing.T) {
t.Parallel()

dt := `# syntax = dockerfile:experimental // opts
FROM busybox
`

ref, argv, ok := DetectSyntax(bytes.NewBuffer([]byte(dt)))
require.True(t, ok)
require.Equal(t, ref, "dockerfile:experimental")
require.Equal(t, argv, "dockerfile:experimental // opts")

dt = `FROM busybox
RUN ls
`
ref, argv, ok = DetectSyntax(bytes.NewBuffer([]byte(dt)))
require.False(t, ok)
require.Equal(t, ref, "")
require.Equal(t, argv, "")

}

0 comments on commit d4d57dd

Please sign in to comment.