Skip to content

Commit 811ff73

Browse files
committed
dockerfile: set error location for ONBUILD errors
Set error location for ONBUILD errors to the command that pulled in the image with ONBUILD definitions. Currently location was incorrectly set to the first line as ONBUILD was parsed as a separate source code. Location is handled both at parse time (for invalid ONBUILD definition) and run time (when command set via ONBUILD errors). Signed-off-by: Tonis Tiigi <[email protected]>
1 parent f1f24dc commit 811ff73

File tree

2 files changed

+35
-3
lines changed

2 files changed

+35
-3
lines changed

frontend/dockerfile/dockerfile2llb/convert.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,7 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
602602

603603
if len(d.image.Config.OnBuild) > 0 {
604604
if b, err := initOnBuildTriggers(d, d.image.Config.OnBuild, allDispatchStates); err != nil {
605-
return nil, err
605+
return nil, parser.SetLocation(err, d.stage.Location)
606606
} else if b {
607607
newDeps = true
608608
}
@@ -788,7 +788,7 @@ func toCommand(ic instructions.Command, allDispatchStates *dispatchStates) (comm
788788
stn, ok = allDispatchStates.findStateByName(c.From)
789789
if !ok {
790790
stn = &dispatchState{
791-
stage: instructions.Stage{BaseName: c.From, Location: ic.Location()},
791+
stage: instructions.Stage{BaseName: c.From, Location: c.Location()},
792792
deps: make(map[*dispatchState]instructions.Command),
793793
paths: make(map[string]struct{}),
794794
unregistered: true,
@@ -1113,6 +1113,9 @@ func initOnBuildTriggers(d *dispatchState, triggers []string, allDispatchStates
11131113
if len(ast.AST.Children) != 1 {
11141114
return false, errors.New("onbuild trigger should be a single expression")
11151115
}
1116+
node := ast.AST.Children[0]
1117+
// reset the location to the onbuild trigger
1118+
node.StartLine, node.EndLine = rangeStartEnd(d.stage.Location)
11161119
ic, err := instructions.ParseCommand(ast.AST.Children[0])
11171120
if err != nil {
11181121
return false, err
@@ -2517,6 +2520,23 @@ func buildMetaArgs(args *llb.EnvList, shlex *shell.Lex, argCommands []instructio
25172520
return args, allArgs, nil
25182521
}
25192522

2523+
func rangeStartEnd(r []parser.Range) (int, int) {
2524+
if len(r) == 0 {
2525+
return 0, 0
2526+
}
2527+
start := math.MaxInt32
2528+
end := 0
2529+
for _, rng := range r {
2530+
if rng.Start.Line < start {
2531+
start = rng.Start.Line
2532+
}
2533+
if rng.End.Line > end {
2534+
end = rng.End.Line
2535+
}
2536+
}
2537+
return start, end
2538+
}
2539+
25202540
type emptyEnvs struct{}
25212541

25222542
func (emptyEnvs) Get(string) (string, bool) {

frontend/dockerfile/parser/errors.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,24 @@ func withLocation(err error, start, end int) error {
3434

3535
// WithLocation extends an error with a source code location
3636
func WithLocation(err error, location []Range) error {
37+
return setLocation(err, location, true)
38+
}
39+
40+
func SetLocation(err error, location []Range) error {
41+
return setLocation(err, location, false)
42+
}
43+
44+
func setLocation(err error, location []Range, add bool) error {
3745
if err == nil {
3846
return nil
3947
}
4048
var el *ErrorLocation
4149
if errors.As(err, &el) {
42-
el.Locations = append(el.Locations, location)
50+
if add {
51+
el.Locations = append(el.Locations, location)
52+
} else {
53+
el.Locations = [][]Range{location}
54+
}
4355
return err
4456
}
4557
return stack.Enable(&ErrorLocation{

0 commit comments

Comments
 (0)