@@ -162,17 +162,44 @@ func asConstraints(opts ...ValidationOpt) llb.ConstraintsOpt {
162162 })
163163}
164164
165- // For each llb.StateOption, set the state option on the original state
165+ // mergeStateOptions merges multiple llb.StateOptions into a single llb.StateOption.
166+ //
167+ // Each option is applied independently to the same input state.
168+ // Conceptually:
169+ //
170+ // 1. Start from origState
171+ // 2. For each option:
172+ // - create a temporary branch: diff(origState, stateN)
173+ // 3. Merge all resulting branches back together
174+ //
175+ // No option sees the effects of any other option.
176+ //
166177// Example:
167- // origState:
168- // |-apply(opt) -> state1
169- // |-apply(opt) -> state2
170- // |-apply(opt) -> state3
171178//
172- // In the above example, each of the new states (state1,state2,state3) are direct decendants
179+ // input
180+ // |
181+ // +-------+-------+
182+ // | | |
183+ // apply apply apply
184+ // opt1 opt2 opt3
185+ // | | |
186+ // diff1 diff2 diff3
187+ // | | |
188+ // +-------+-------+
189+ // |
190+ // merge(input, diff1, diff2, diff3)
191+ // |
192+ // output
193+ //
194+ // All intermediate states (state1, state2, state3) are direct descendants
173195// of origState.
174- // If you are expecting states to apply in order (origState -> state1 -> state2 -> state3),
175- // this is not the function you are looking for, see [withOptions] instead.
196+ //
197+ // If you expect options to apply sequentially
198+ // (origState -> state1 -> state2 -> state3),
199+ // This is NOT the function you want.
200+ //
201+ // This is NOT a generic solution and is only intended to be used within the context of
202+ // what is needed to run a spec's tests since we know the caller is resetting the state back to the original state.
176203func mergeStateOptions (stateOpts []llb.StateOption , opts ... ValidationOpt ) llb.StateOption {
177204 return func (in llb.State ) llb.State {
178205 if len (stateOpts ) == 0 {
@@ -186,21 +213,14 @@ func mergeStateOptions(stateOpts []llb.StateOption, opts ...ValidationOpt) llb.S
186213
187214 states := make ([]llb.State , 0 , len (opts ))
188215 for _ , o := range stateOpts {
189- states = append (states , in .With (o ))
216+ diff := llb .Diff (in , in .With (o ), asConstraints (opts ... ))
217+ states = append (states , diff )
190218 }
191- return dalec .MergeAtPath (in , states , "/" , asConstraints (opts ... ))
192- }
193- }
194219
195- // withOptions applies multiple llb.StateOption to a state in order
196- func withOptions (opts []llb.StateOption ) llb.StateOption {
197- return func (in llb.State ) llb.State {
198- out := in
220+ merged := llb .Merge (states , asConstraints (opts ... ))
221+ diff := llb .Diff (in , merged , asConstraints (opts ... ))
199222
200- for _ , opt := range opts {
201- out = out .With (opt )
202- }
203- return out
223+ return llb .Merge ([]llb.State {in , diff }, asConstraints (opts ... ))
204224 }
205225}
206226
0 commit comments