mirror of
https://github.com/moby/buildkit.git
synced 2026-11-06 05:16:45 +00:00
dockerfile: add hint suggestions to UndeclaredArgInFrom
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
4 files changed
+34
-25
No files matched your search
@@ -261,7 +261,7 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
|
||||
// set base state for every image
|
||||
for i, st := range stages {
|
||||
nameMatch, err := shlex.ProcessWordWithMatches(st.BaseName, metaArgsToMap(optMetaArgs))
|
||||
reportUnusedFromArgs(nameMatch.Unmatched, st.Location, opt.Warn)
|
||||
reportUnusedFromArgs(metaArgsKeys(optMetaArgs), nameMatch.Unmatched, st.Location, opt.Warn)
|
||||
used := nameMatch.Matched
|
||||
|
||||
if err != nil {
|
||||
@@ -285,7 +285,7 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
|
||||
|
||||
if v := st.Platform; v != "" {
|
||||
platMatch, err := shlex.ProcessWordWithMatches(v, metaArgsToMap(optMetaArgs))
|
||||
reportUnusedFromArgs(platMatch.Unmatched, st.Location, opt.Warn)
|
||||
reportUnusedFromArgs(metaArgsKeys(optMetaArgs), platMatch.Unmatched, st.Location, opt.Warn)
|
||||
|
||||
if err != nil {
|
||||
return nil, parser.WithLocation(errors.Wrapf(err, "failed to process arguments for platform %s", platMatch.Result), st.Location)
|
||||
@@ -2169,9 +2169,10 @@ func toPBLocation(sourceIndex int, location []parser.Range) pb.Location {
|
||||
}
|
||||
}
|
||||
|
||||
func reportUnusedFromArgs(unmatched map[string]struct{}, location []parser.Range, warn linter.LintWarnFunc) {
|
||||
func reportUnusedFromArgs(values []string, unmatched map[string]struct{}, location []parser.Range, warn linter.LintWarnFunc) {
|
||||
for arg := range unmatched {
|
||||
msg := linter.RuleUndeclaredArgInFrom.Format(arg)
|
||||
suggest, _ := suggest.Search(arg, values, true)
|
||||
msg := linter.RuleUndeclaredArgInFrom.Format(arg, suggest)
|
||||
linter.RuleUndeclaredArgInFrom.Run(warn, location, msg)
|
||||
}
|
||||
}
|
||||
@@ -2199,7 +2200,7 @@ func validateUsedOnce(c instructions.Command, loc *instructionTracker, warn lint
|
||||
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)
|
||||
ok, err = suggest.WrapErrorMaybe(err, k, options, true)
|
||||
if ok {
|
||||
break
|
||||
}
|
||||
|
||||
@@ -462,7 +462,7 @@ COPY Dockerfile .
|
||||
{
|
||||
RuleName: "UndeclaredArgInFrom",
|
||||
Description: "FROM command must use declared ARGs",
|
||||
Detail: "FROM argument 'BULIDPLATFORM' is not declared",
|
||||
Detail: "FROM argument 'BULIDPLATFORM' is not declared (did you mean BUILDPLATFORM?)",
|
||||
Level: 1,
|
||||
Line: 2,
|
||||
},
|
||||
@@ -484,7 +484,7 @@ COPY Dockerfile .
|
||||
{
|
||||
RuleName: "UndeclaredArgInFrom",
|
||||
Description: "FROM command must use declared ARGs",
|
||||
Detail: "FROM argument 'MYARCH' is not declared",
|
||||
Detail: "FROM argument 'MYARCH' is not declared (did you mean MY_ARCH?)",
|
||||
Level: 1,
|
||||
Line: 4,
|
||||
},
|
||||
|
||||
@@ -70,11 +70,15 @@ var (
|
||||
return "Maintainer instruction is deprecated in favor of using label"
|
||||
},
|
||||
}
|
||||
RuleUndeclaredArgInFrom = LinterRule[func(string) string]{
|
||||
RuleUndeclaredArgInFrom = LinterRule[func(string, string) string]{
|
||||
Name: "UndeclaredArgInFrom",
|
||||
Description: "FROM command must use declared ARGs",
|
||||
Format: func(baseArg string) string {
|
||||
return fmt.Sprintf("FROM argument '%s' is not declared", baseArg)
|
||||
Format: func(baseArg, suggest string) string {
|
||||
out := fmt.Sprintf("FROM argument '%s' is not declared", baseArg)
|
||||
if suggest != "" {
|
||||
out += fmt.Sprintf(" (did you mean %s?)", suggest)
|
||||
}
|
||||
return out
|
||||
},
|
||||
}
|
||||
RuleWorkdirRelativePath = LinterRule[func(workdir string) string]{
|
||||
|
||||
+19
-15
@@ -6,16 +6,7 @@ import (
|
||||
"github.com/agext/levenshtein"
|
||||
)
|
||||
|
||||
// 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, false
|
||||
}
|
||||
func Search(val string, options []string, caseSensitive bool) (string, bool) {
|
||||
orig := val
|
||||
if !caseSensitive {
|
||||
val = strings.ToLower(val)
|
||||
@@ -28,7 +19,7 @@ func WrapErrorMaybe(err error, val string, options []string, caseSensitive bool)
|
||||
}
|
||||
if val == opt {
|
||||
// exact match means error was unrelated to the value
|
||||
return err, false
|
||||
return "", false
|
||||
}
|
||||
dist := levenshtein.Distance(val, opt, nil)
|
||||
if dist < mindist {
|
||||
@@ -40,15 +31,28 @@ func WrapErrorMaybe(err error, val string, options []string, caseSensitive bool)
|
||||
mindist = dist
|
||||
}
|
||||
}
|
||||
return match, match != ""
|
||||
}
|
||||
|
||||
if match == "" {
|
||||
return err, false
|
||||
// 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) (bool, error) {
|
||||
if err == nil {
|
||||
return false, nil
|
||||
}
|
||||
match, ok := Search(val, options, caseSensitive)
|
||||
if match == "" || !ok {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return &suggestError{
|
||||
return true, &suggestError{
|
||||
err: err,
|
||||
match: match,
|
||||
}, true
|
||||
}
|
||||
}
|
||||
|
||||
type suggestError struct {
|
||||
|
||||
Reference in new issue
Block a user