Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dockerfile: additional expansions #1241

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions rhel/dockerfile/dockerfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@
if strings.Contains(v, `escape=`) {
eq := strings.IndexByte(v, '=')
if eq == -1 {
return fmt.Errorf("botched parser directive: %#q", i.val)
panic("string changed while parsing?")

Check warning on line 103 in rhel/dockerfile/dockerfile.go

View check run for this annotation

Codecov / codecov/patch

rhel/dockerfile/dockerfile.go#L103

Added line #L103 was not covered by tests
}
esc, _ := utf8.DecodeRuneInString(v[:eq+1])
esc, _ := utf8.DecodeRuneInString(v[eq+1:])
p.lex.Escape(esc)
p.unquote.Escape(esc)
p.vars.Escape(esc)
Expand Down
68 changes: 32 additions & 36 deletions rhel/dockerfile/dockerfile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,60 +4,56 @@ import (
"bytes"
"context"
"encoding/json"
"io/fs"
"os"
"path/filepath"
"strings"
"testing"

"github.com/google/go-cmp/cmp"
"golang.org/x/tools/txtar"
)

func TestGetLabels(t *testing.T) {
var errPrefix = []byte("error:")
ctx := context.Background()
td := os.DirFS("testdata")
de, err := fs.ReadDir(td, ".")

ms, err := filepath.Glob("testdata/*.txtar")
if err != nil {
t.Fatal(err)
}
for _, de := range de {
n := de.Name()
if !strings.HasPrefix(n, "Dockerfile") ||
strings.HasSuffix(n, ".want") ||
strings.HasSuffix(n, ".want.err") {
continue
}
t.Run(n, func(t *testing.T) {
f, err := td.Open(n)
for _, m := range ms {
t.Run(strings.TrimSuffix(filepath.Base(m), filepath.Ext(m)), func(t *testing.T) {
ar, err := txtar.ParseFile(m)
if err != nil {
t.Fatal(err)
t.Fatalf("error parsing archive: %v", err)
}
defer f.Close()
w, err := td.Open(n + ".want")
if err != nil {
t.Fatal(err)
}
defer w.Close()
wantErr, _ := fs.ReadFile(td, n+".want.err")

want := make(map[string]string)
if err := json.NewDecoder(w).Decode(&want); err != nil {
t.Error(err)
}
got, err := GetLabels(ctx, f)
if len(wantErr) == 0 {
if err != nil {
t.Error(err)
}
} else {
if err == nil {
t.Error("got nil, wanted error")
} else {
if got, want := err.Error(), string(bytes.TrimSpace(wantErr)); got != want {
t.Errorf("got: %+#q, want: %+#q", got, want)
var got, want map[string]string
wantErr := bytes.HasPrefix(ar.Comment, errPrefix)
for _, f := range ar.Files {
switch f.Name {
case "Dockerfile":
got, err = GetLabels(ctx, bytes.NewReader(f.Data))
case "Want":
want = make(map[string]string)
if err := json.Unmarshal(f.Data, &want); err != nil {
t.Fatalf("unmarshaling wanted values: %v", err)
}
default:
t.Logf("skipping unknown file: %s", f.Name)
}
}

if wantErr {
got := err.Error()
want := string(bytes.TrimSpace(bytes.TrimPrefix(ar.Comment, errPrefix)))
if got != want {
t.Error(cmp.Diff(got, want))
}
return
}
if err != nil {
t.Errorf("error parsing labels: %v", err)
}
if !cmp.Equal(got, want) {
t.Error(cmp.Diff(got, want))
}
Expand Down
25 changes: 24 additions & 1 deletion rhel/dockerfile/fuzz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,31 @@ package dockerfile

import (
"bytes"
"path/filepath"
"testing"

"golang.org/x/tools/txtar"
)

func FuzzLex(f *testing.F) {
ms, err := filepath.Glob("testdata/*.txtar")
if err != nil {
f.Fatal(err)
}
for _, m := range ms {
ar, err := txtar.ParseFile(m)
if err != nil {
f.Fatalf("error parsing archive: %v", err)
}
File:
for _, af := range ar.Files {
if af.Name == "Dockerfile" {
f.Add(af.Data)
break File
}
}
}

f.Fuzz(func(t *testing.T, b []byte) {
l := newLexer()
l.Reset(bytes.NewReader(b))
Expand All @@ -22,4 +43,6 @@ func FuzzLex(f *testing.F) {
})
}

//go:generate sh -c "go run golang.org/x/tools/cmd/file2fuzz -o testdata/fuzz/FuzzLex $(ls -1 testdata/Dockerfile* | grep -v [.]want)"
// To add new files to the fuzz corpus:
//
// go run golang.org/x/tools/cmd/file2fuzz -o testdata/fuzz/FuzzLex [FILE]
5 changes: 5 additions & 0 deletions rhel/dockerfile/generate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package dockerfile

//go:generate -command stringer go run golang.org/x/tools/cmd/stringer
//go:generate stringer -type itemKind
//go:generate stringer -type varExpand -linecomment
3 changes: 0 additions & 3 deletions rhel/dockerfile/lex.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,6 @@ type item struct {

type itemKind int

//go:generate -command stringer go run golang.org/x/tools/cmd/stringer
//go:generate stringer -type itemKind

const (
itemError itemKind = iota
itemComment
Expand Down
3 changes: 3 additions & 0 deletions rhel/dockerfile/testdata/Colon.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
error: dockerfile: bad expansion of "error": rogue colon
-- Dockerfile --
LABEL a ${error::}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
-- Dockerfile --
# Normal comments are fine
FROM scratch

Expand All @@ -7,3 +8,8 @@ LABEL \
C=D
# This comment is stripped despite the apparent continuation

-- Want --
{
"A": "B",
"C": "D"
}
15 changes: 15 additions & 0 deletions rhel/dockerfile/testdata/Default.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-- Dockerfile --
LABEL a ${unset}
LABEL b ${unset=set}
LABEL c ${unset}

LABEL null=
LABEL d ${null:=reset}
-- Want --
{
"a": "",
"b": "set",
"c": "set",
"d": "reset",
"null": ""
}
4 changes: 0 additions & 4 deletions rhel/dockerfile/testdata/Dockerfile-Comments.want

This file was deleted.

2 changes: 0 additions & 2 deletions rhel/dockerfile/testdata/Dockerfile-InvalidLabel

This file was deleted.

4 changes: 0 additions & 4 deletions rhel/dockerfile/testdata/Dockerfile-InvalidLabel.want

This file was deleted.

This file was deleted.

15 changes: 0 additions & 15 deletions rhel/dockerfile/testdata/Dockerfile-etcd-rhel7.want

This file was deleted.

3 changes: 0 additions & 3 deletions rhel/dockerfile/testdata/Dockerfile-issue526.want

This file was deleted.

20 changes: 0 additions & 20 deletions rhel/dockerfile/testdata/Dockerfile-nodejs10.want

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

20 changes: 0 additions & 20 deletions rhel/dockerfile/testdata/Dockerfile-ubi7-7.9-516.want

This file was deleted.

22 changes: 0 additions & 22 deletions rhel/dockerfile/testdata/Dockerfile-ubi8-minimal-8.4-208.want

This file was deleted.

3 changes: 3 additions & 0 deletions rhel/dockerfile/testdata/Error.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
error: dockerfile: bad expansion of "unset": should error (error if unset or null)
-- Dockerfile --
LABEL a ${unset:?should error}
8 changes: 8 additions & 0 deletions rhel/dockerfile/testdata/Escape.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-- Dockerfile --
# escape=ꙮ
LABEL a ꙮ
ꙮ$b
-- Want --
{
"a": "$b"
}
4 changes: 4 additions & 0 deletions rhel/dockerfile/testdata/InvalidLabel.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
error: invalid assignment syntax: `A=B C=D # Comments not allowed in this position`
-- Dockerfile --
LABEL A=B \
C=D # Comments not allowed in this position
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
-- Dockerfile --
FROM scratch

ENV A="B C" \
D=E

LABEL label="$A $D"
-- Want --
{
"label": "B C E"
}
Loading
Loading