Skip to content

Commit

Permalink
dockerfile: improve error messages and add suggest to platform flag p…
Browse files Browse the repository at this point in the history
…arsing

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
  • Loading branch information
tonistiigi committed May 14, 2024
1 parent 6acf12f commit 1c57c6e
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 7 deletions.
30 changes: 29 additions & 1 deletion frontend/dockerfile/dockerfile2llb/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,9 +291,18 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
return nil, parser.WithLocation(errors.Wrapf(err, "failed to process arguments for platform %s", platMatch.Result), st.Location)
}

if platMatch.Result == "" {
err := errors.Errorf("empty platform value from expression %s", v)
err = parser.WithLocation(err, st.Location)
err = wrapSuggestAny(err, platMatch.Unmatched, metaArgsKeys(optMetaArgs))
return nil, err
}

p, err := platforms.Parse(platMatch.Result)
if err != nil {
return nil, parser.WithLocation(errors.Wrapf(err, "failed to parse platform %s", platMatch.Result), st.Location)
err = parser.WithLocation(err, st.Location)
err = wrapSuggestAny(err, platMatch.Unmatched, metaArgsKeys(optMetaArgs))
return nil, parser.WithLocation(errors.Wrapf(err, "failed to parse platform %s", v), st.Location)
}

for k := range platMatch.Matched {
Expand Down Expand Up @@ -687,6 +696,14 @@ func metaArgsToMap(metaArgs []instructions.KeyValuePairOptional) map[string]stri
return m
}

func metaArgsKeys(metaArgs []instructions.KeyValuePairOptional) []string {
s := make([]string, 0, len(metaArgs))
for _, arg := range metaArgs {
s = append(s, arg.Key)
}
return s
}

func toCommand(ic instructions.Command, allDispatchStates *dispatchStates) (command, error) {
cmd := command{Command: ic}
if c, ok := ic.(*instructions.CopyCommand); ok {
Expand Down Expand Up @@ -2178,3 +2195,14 @@ func validateUsedOnce(c instructions.Command, loc *instructionTracker, warn lint
}
loc.MarkUsed(c.Location())
}

func wrapSuggestAny(err error, keys map[string]struct{}, options []string) error {
for k := range keys {
var ok bool
err, ok = suggest.WrapErrorMaybe(err, k, options, true)
if ok {
break
}
}
return err
}
26 changes: 24 additions & 2 deletions frontend/dockerfile/dockerfile_lint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -467,11 +467,33 @@ COPY Dockerfile .
Line: 2,
},
},
StreamBuildErr: "failed to solve: failed to parse platform : \"\" is an invalid component of \"\": platform specifier component must match \"^[A-Za-z0-9_-]+$\": invalid argument",
UnmarshalBuildErr: "failed to parse platform : \"\" is an invalid component of \"\": platform specifier component must match \"^[A-Za-z0-9_-]+$\": invalid argument",
StreamBuildErr: "failed to solve: empty platform value from expression $BULIDPLATFORM (did you mean BUILDPLATFORM?)",
UnmarshalBuildErr: "empty platform value from expression $BULIDPLATFORM (did you mean BUILDPLATFORM?)",
BuildErrLocation: 2,
})

dockerfile = []byte(`
ARG MY_OS=linux
ARG MY_ARCH=amd64
FROM --platform=linux/${MYARCH} busybox
COPY Dockerfile .
`)
checkLinterWarnings(t, sb, &lintTestParams{
Dockerfile: dockerfile,
Warnings: []expectedLintWarning{
{
RuleName: "UndeclaredArgInFrom",
Description: "FROM command must use declared ARGs",
Detail: "FROM argument 'MYARCH' is not declared",
Level: 1,
Line: 4,
},
},
StreamBuildErr: "failed to solve: failed to parse platform linux/: \"\" is an invalid component of \"linux/\": platform specifier component must match \"^[A-Za-z0-9_-]+$\": invalid argument (did you mean MY_ARCH?)",
UnmarshalBuildErr: "failed to parse platform linux/: \"\" is an invalid component of \"linux/\": platform specifier component must match \"^[A-Za-z0-9_-]+$\": invalid argument (did you mean MY_ARCH?)",
BuildErrLocation: 4,
})

dockerfile = []byte(`
ARG tag=latest
FROM busybox:${tag}${version} AS b
Expand Down
13 changes: 9 additions & 4 deletions util/suggest/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@ import (

// WrapError wraps error with a suggestion for fixing it
func WrapError(err error, val string, options []string, caseSensitive bool) error {
err, _ = WrapErrorMaybe(err, val, options, caseSensitive)
return err
}

func WrapErrorMaybe(err error, val string, options []string, caseSensitive bool) (error, bool) {
if err == nil {
return nil
return nil, false
}
orig := val
if !caseSensitive {
Expand All @@ -23,7 +28,7 @@ func WrapError(err error, val string, options []string, caseSensitive bool) erro
}
if val == opt {
// exact match means error was unrelated to the value
return err
return err, false
}
dist := levenshtein.Distance(val, opt, nil)
if dist < mindist {
Expand All @@ -37,13 +42,13 @@ func WrapError(err error, val string, options []string, caseSensitive bool) erro
}

if match == "" {
return err
return err, false
}

return &suggestError{
err: err,
match: match,
}
}, true
}

type suggestError struct {
Expand Down

0 comments on commit 1c57c6e

Please sign in to comment.