Skip to content

Commit ce43466

Browse files
authored
Merge pull request moby#5397 from tonistiigi/onbuild-fixes
Multiple fixes for ONBUILD behavior
2 parents 7fc8434 + 811ff73 commit ce43466

File tree

2 files changed

+44
-4
lines changed

2 files changed

+44
-4
lines changed

frontend/dockerfile/dockerfile2llb/convert.go

Lines changed: 31 additions & 3 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,
@@ -860,6 +860,7 @@ func (e *envsFromState) Keys() []string {
860860
}
861861

862862
func dispatch(d *dispatchState, cmd command, opt dispatchOpt) error {
863+
d.cmdIsOnBuild = cmd.isOnBuild
863864
var err error
864865
// ARG command value could be ignored, so defer handling the expansion error
865866
_, isArg := cmd.Command.(*instructions.ArgCommand)
@@ -1015,6 +1016,7 @@ type dispatchState struct {
10151016
unregistered bool
10161017
stageName string
10171018
cmdIndex int
1019+
cmdIsOnBuild bool
10181020
cmdTotal int
10191021
prefixPlatform bool
10201022
outline outlineCapture
@@ -1093,7 +1095,8 @@ func (dss *dispatchStates) lastTarget() *dispatchState {
10931095

10941096
type command struct {
10951097
instructions.Command
1096-
sources []*dispatchState
1098+
sources []*dispatchState
1099+
isOnBuild bool
10971100
}
10981101

10991102
// initOnBuildTriggers initializes the onbuild triggers and creates the commands and dependecies for them.
@@ -1110,6 +1113,9 @@ func initOnBuildTriggers(d *dispatchState, triggers []string, allDispatchStates
11101113
if len(ast.AST.Children) != 1 {
11111114
return false, errors.New("onbuild trigger should be a single expression")
11121115
}
1116+
node := ast.AST.Children[0]
1117+
// reset the location to the onbuild trigger
1118+
node.StartLine, node.EndLine = rangeStartEnd(d.stage.Location)
11131119
ic, err := instructions.ParseCommand(ast.AST.Children[0])
11141120
if err != nil {
11151121
return false, err
@@ -1118,6 +1124,7 @@ func initOnBuildTriggers(d *dispatchState, triggers []string, allDispatchStates
11181124
if err != nil {
11191125
return false, err
11201126
}
1127+
cmd.isOnBuild = true
11211128
if len(cmd.sources) > 0 {
11221129
hasNewDeps = true
11231130
}
@@ -1134,6 +1141,7 @@ func initOnBuildTriggers(d *dispatchState, triggers []string, allDispatchStates
11341141
}
11351142
}
11361143
d.commands = append(commands, d.commands...)
1144+
d.cmdTotal += len(commands)
11371145

11381146
return hasNewDeps, nil
11391147
}
@@ -2065,6 +2073,9 @@ func prefixCommand(ds *dispatchState, str string, prefixPlatform bool, platform
20652073
}
20662074
ds.cmdIndex++
20672075
out += fmt.Sprintf("%*d/%d] ", int(1+math.Log10(float64(ds.cmdTotal))), ds.cmdIndex, ds.cmdTotal)
2076+
if ds.cmdIsOnBuild {
2077+
out += "ONBUILD "
2078+
}
20682079
return out + str
20692080
}
20702081

@@ -2509,6 +2520,23 @@ func buildMetaArgs(args *llb.EnvList, shlex *shell.Lex, argCommands []instructio
25092520
return args, allArgs, nil
25102521
}
25112522

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+
25122540
type emptyEnvs struct{}
25132541

25142542
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)