Fix very minor continuation bugs for better coverage
There were some very minor/subtle bugs in how I implemented continuation that wouldn't affect any real-world parsing we did, but still bothered me because I'm me. This fixes them (and further increases test coverage as a result).
This commit is contained in:
parent
0e00438cf2
commit
7ddf2bef73
|
|
@ -5,6 +5,7 @@ import (
|
|||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
type Metadata struct {
|
||||
|
|
@ -31,10 +32,11 @@ func ParseReader(dockerfile io.Reader) (*Metadata, error) {
|
|||
line := strings.TrimSpace(scanner.Text())
|
||||
|
||||
if line == "" {
|
||||
// ignore blank lines
|
||||
// ignore straight up blank lines (no complexity)
|
||||
continue
|
||||
}
|
||||
|
||||
// (we can't have a comment that ends in a continuation line - that's not continuation, that's part of the comment)
|
||||
if line[0] == '#' {
|
||||
// TODO handle "escape" parser directive
|
||||
// TODO handle "syntax" parser directive -- explode appropriately (since custom syntax invalidates our Dockerfile parsing)
|
||||
|
|
@ -44,20 +46,36 @@ func ParseReader(dockerfile io.Reader) (*Metadata, error) {
|
|||
|
||||
// handle line continuations
|
||||
// (TODO see note above regarding "escape" parser directive)
|
||||
for line[len(line)-1] == '\\' && scanner.Scan() {
|
||||
nextLine := strings.TrimSpace(scanner.Text())
|
||||
if nextLine == "" || nextLine[0] == '#' {
|
||||
// ignore blank lines and comments
|
||||
for line[len(line)-1] == '\\' {
|
||||
if !scanner.Scan() {
|
||||
line = line[0:len(line)-1]
|
||||
break
|
||||
}
|
||||
// "strings.TrimRightFunc(IsSpace)" because whitespace *after* the escape character is supported and ignored 🙈
|
||||
nextLine := strings.TrimRightFunc(scanner.Text(), unicode.IsSpace)
|
||||
if nextLine == "" { // if it's all space, TrimRight will be TrimSpace 😏
|
||||
// ignore "empty continuation" lines (https://github.com/moby/moby/pull/33719)
|
||||
continue
|
||||
}
|
||||
if strings.TrimLeftFunc(nextLine, unicode.IsSpace)[0] == '#' {
|
||||
// ignore comments inside continuation (https://github.com/moby/moby/issues/29005)
|
||||
continue
|
||||
}
|
||||
line = line[0:len(line)-1] + nextLine
|
||||
}
|
||||
|
||||
|
||||
// TODO *technically* a line like " RUN echo hi " should be parsed as "RUN" "echo hi" (cut off instruction, then the rest of the line with TrimSpace), but for our needs "strings.Fields" is good enough for now
|
||||
|
||||
// line = strings.TrimSpace(line) // (emulated below; "strings.Fields" does essentially the same exact thing so we don't need to do it explicitly here too)
|
||||
|
||||
fields := strings.Fields(line)
|
||||
|
||||
if len(fields) < 1 {
|
||||
// must be a much more complex empty line??
|
||||
// ignore empty lines
|
||||
continue
|
||||
}
|
||||
|
||||
instruction := strings.ToUpper(fields[0])
|
||||
|
||||
// TODO balk at ARG / $ in from values
|
||||
|
|
|
|||
|
|
@ -75,6 +75,44 @@ func TestParse(t *testing.T) {
|
|||
Froms: []string{"bash:latest", "busybox:uclibc", "bash:5", "bash:latest", "scratch", "bash:latest", "bash:5", "bash:latest"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "empty continuations",
|
||||
dockerfile: `
|
||||
\
|
||||
\
|
||||
\
|
||||
\
|
||||
\
|
||||
\
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "continuation edge cases",
|
||||
dockerfile: `
|
||||
# continuation does not apply to this comment \
|
||||
FROM scratch
|
||||
# but everything below this is part of a single continuation
|
||||
|
||||
FROM\
|
||||
|
||||
\
|
||||
\
|
||||
|
||||
\
|
||||
\
|
||||
|
||||
# comments inside are fine
|
||||
# and really yucky empty lines:
|
||||
|
||||
\
|
||||
\
|
||||
|
||||
scratch\
|
||||
`,
|
||||
metadata: dockerfile.Metadata{
|
||||
Froms: []string{"scratch", "scratch"},
|
||||
},
|
||||
},
|
||||
{
|
||||
// TODO is this even something that's supported by classic builder/buildkit? (Tianon *thinks* it was supported once, but maybe he's misremembering and it's never been a thing Dockerfiles, only docker build --target=N ?)
|
||||
name: "numbered stages",
|
||||
|
|
|
|||
Loading…
Reference in New Issue