Skip to content

Commit 555ea7d

Browse files
committed
dockerfile: add hint suggestions to UndeclaredArgInFrom
Signed-off-by: Tonis Tiigi <[email protected]>
1 parent 05782a7 commit 555ea7d

File tree

4 files changed

+34
-25
lines changed

4 files changed

+34
-25
lines changed

frontend/dockerfile/dockerfile2llb/convert.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
261261
// set base state for every image
262262
for i, st := range stages {
263263
nameMatch, err := shlex.ProcessWordWithMatches(st.BaseName, metaArgsToMap(optMetaArgs))
264-
reportUnusedFromArgs(nameMatch.Unmatched, st.Location, opt.Warn)
264+
reportUnusedFromArgs(metaArgsKeys(optMetaArgs), nameMatch.Unmatched, st.Location, opt.Warn)
265265
used := nameMatch.Matched
266266

267267
if err != nil {
@@ -285,7 +285,7 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
285285

286286
if v := st.Platform; v != "" {
287287
platMatch, err := shlex.ProcessWordWithMatches(v, metaArgsToMap(optMetaArgs))
288-
reportUnusedFromArgs(platMatch.Unmatched, st.Location, opt.Warn)
288+
reportUnusedFromArgs(metaArgsKeys(optMetaArgs), platMatch.Unmatched, st.Location, opt.Warn)
289289

290290
if err != nil {
291291
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 {
21692169
}
21702170
}
21712171

2172-
func reportUnusedFromArgs(unmatched map[string]struct{}, location []parser.Range, warn linter.LintWarnFunc) {
2172+
func reportUnusedFromArgs(values []string, unmatched map[string]struct{}, location []parser.Range, warn linter.LintWarnFunc) {
21732173
for arg := range unmatched {
2174-
msg := linter.RuleUndeclaredArgInFrom.Format(arg)
2174+
suggest, _ := suggest.Search(arg, values, true)
2175+
msg := linter.RuleUndeclaredArgInFrom.Format(arg, suggest)
21752176
linter.RuleUndeclaredArgInFrom.Run(warn, location, msg)
21762177
}
21772178
}
@@ -2199,7 +2200,7 @@ func validateUsedOnce(c instructions.Command, loc *instructionTracker, warn lint
21992200
func wrapSuggestAny(err error, keys map[string]struct{}, options []string) error {
22002201
for k := range keys {
22012202
var ok bool
2202-
err, ok = suggest.WrapErrorMaybe(err, k, options, true)
2203+
ok, err = suggest.WrapErrorMaybe(err, k, options, true)
22032204
if ok {
22042205
break
22052206
}

frontend/dockerfile/dockerfile_lint_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ COPY Dockerfile .
462462
{
463463
RuleName: "UndeclaredArgInFrom",
464464
Description: "FROM command must use declared ARGs",
465-
Detail: "FROM argument 'BULIDPLATFORM' is not declared",
465+
Detail: "FROM argument 'BULIDPLATFORM' is not declared (did you mean BUILDPLATFORM?)",
466466
Level: 1,
467467
Line: 2,
468468
},
@@ -484,7 +484,7 @@ COPY Dockerfile .
484484
{
485485
RuleName: "UndeclaredArgInFrom",
486486
Description: "FROM command must use declared ARGs",
487-
Detail: "FROM argument 'MYARCH' is not declared",
487+
Detail: "FROM argument 'MYARCH' is not declared (did you mean MY_ARCH?)",
488488
Level: 1,
489489
Line: 4,
490490
},

frontend/dockerfile/linter/ruleset.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,15 @@ var (
7070
return "Maintainer instruction is deprecated in favor of using label"
7171
},
7272
}
73-
RuleUndeclaredArgInFrom = LinterRule[func(string) string]{
73+
RuleUndeclaredArgInFrom = LinterRule[func(string, string) string]{
7474
Name: "UndeclaredArgInFrom",
7575
Description: "FROM command must use declared ARGs",
76-
Format: func(baseArg string) string {
77-
return fmt.Sprintf("FROM argument '%s' is not declared", baseArg)
76+
Format: func(baseArg, suggest string) string {
77+
out := fmt.Sprintf("FROM argument '%s' is not declared", baseArg)
78+
if suggest != "" {
79+
out += fmt.Sprintf(" (did you mean %s?)", suggest)
80+
}
81+
return out
7882
},
7983
}
8084
RuleWorkdirRelativePath = LinterRule[func(workdir string) string]{

util/suggest/error.go

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,7 @@ import (
66
"github.com/agext/levenshtein"
77
)
88

9-
// WrapError wraps error with a suggestion for fixing it
10-
func WrapError(err error, val string, options []string, caseSensitive bool) error {
11-
err, _ = WrapErrorMaybe(err, val, options, caseSensitive)
12-
return err
13-
}
14-
15-
func WrapErrorMaybe(err error, val string, options []string, caseSensitive bool) (error, bool) {
16-
if err == nil {
17-
return nil, false
18-
}
9+
func Search(val string, options []string, caseSensitive bool) (string, bool) {
1910
orig := val
2011
if !caseSensitive {
2112
val = strings.ToLower(val)
@@ -28,7 +19,7 @@ func WrapErrorMaybe(err error, val string, options []string, caseSensitive bool)
2819
}
2920
if val == opt {
3021
// exact match means error was unrelated to the value
31-
return err, false
22+
return "", false
3223
}
3324
dist := levenshtein.Distance(val, opt, nil)
3425
if dist < mindist {
@@ -40,15 +31,28 @@ func WrapErrorMaybe(err error, val string, options []string, caseSensitive bool)
4031
mindist = dist
4132
}
4233
}
34+
return match, match != ""
35+
}
4336

44-
if match == "" {
45-
return err, false
37+
// WrapError wraps error with a suggestion for fixing it
38+
func WrapError(err error, val string, options []string, caseSensitive bool) error {
39+
_, err = WrapErrorMaybe(err, val, options, caseSensitive)
40+
return err
41+
}
42+
43+
func WrapErrorMaybe(err error, val string, options []string, caseSensitive bool) (bool, error) {
44+
if err == nil {
45+
return false, nil
46+
}
47+
match, ok := Search(val, options, caseSensitive)
48+
if match == "" || !ok {
49+
return false, err
4650
}
4751

48-
return &suggestError{
52+
return true, &suggestError{
4953
err: err,
5054
match: match,
51-
}, true
55+
}
5256
}
5357

5458
type suggestError struct {

0 commit comments

Comments
 (0)