Skip to content

Commit 758ea75

Browse files
authored
Merge pull request #3235 from jsternberg/dap-handler
dap: add debug adapter implementation
2 parents 87371a8 + 42599a7 commit 758ea75

File tree

27 files changed

+4034
-213
lines changed

27 files changed

+4034
-213
lines changed

build/build.go

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -313,9 +313,12 @@ func toRepoOnly(in string) (string, error) {
313313
return strings.Join(out, ","), nil
314314
}
315315

316-
type Handler struct {
317-
Evaluate func(ctx context.Context, c gateway.Client, res *gateway.Result) error
318-
}
316+
type (
317+
EvaluateFunc func(ctx context.Context, name string, c gateway.Client, res *gateway.Result) error
318+
Handler struct {
319+
Evaluate EvaluateFunc
320+
}
321+
)
319322

320323
func Build(ctx context.Context, nodes []builder.Node, opts map[string]Options, docker *dockerutil.Client, cfg *confutil.Config, w progress.Writer) (resp map[string]*client.SolveResponse, err error) {
321324
return BuildWithResultHandler(ctx, nodes, opts, docker, cfg, w, nil)
@@ -510,12 +513,25 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opts map[
510513
rKey := resultKey(dp.driverIndex, k)
511514
results.Set(rKey, res)
512515

516+
forceEval := false
513517
if children := childTargets[rKey]; len(children) > 0 {
514-
if err := waitForChildren(ctx, bh, c, res, results, children); err != nil {
518+
// wait for the child targets to register their LLB before evaluating
519+
_, err := results.Get(ctx, children...)
520+
if err != nil {
515521
return nil, err
516522
}
517-
} else if bh != nil && bh.Evaluate != nil {
518-
if err := bh.Evaluate(ctx, c, res); err != nil {
523+
forceEval = true
524+
}
525+
526+
// invoke custom evaluate handler if it is present
527+
if bh != nil && bh.Evaluate != nil {
528+
if err := bh.Evaluate(ctx, k, c, res); err != nil {
529+
return nil, err
530+
}
531+
} else if forceEval {
532+
if err := res.EachRef(func(ref gateway.Reference) error {
533+
return ref.Evaluate(ctx)
534+
}); err != nil {
519535
return nil, err
520536
}
521537
}
@@ -1199,29 +1215,6 @@ func solve(ctx context.Context, c gateway.Client, req gateway.SolveRequest) (*ga
11991215
return res, nil
12001216
}
12011217

1202-
func waitForChildren(ctx context.Context, bh *Handler, c gateway.Client, res *gateway.Result, results *waitmap.Map, children []string) error {
1203-
// wait for the child targets to register their LLB before evaluating
1204-
_, err := results.Get(ctx, children...)
1205-
if err != nil {
1206-
return err
1207-
}
1208-
// we need to wait until the child targets have completed before we can release
1209-
eg, ctx := errgroup.WithContext(ctx)
1210-
eg.Go(func() error {
1211-
if bh != nil && bh.Evaluate != nil {
1212-
return bh.Evaluate(ctx, c, res)
1213-
}
1214-
return res.EachRef(func(ref gateway.Reference) error {
1215-
return ref.Evaluate(ctx)
1216-
})
1217-
})
1218-
eg.Go(func() error {
1219-
_, err := results.Get(ctx, children...)
1220-
return err
1221-
})
1222-
return eg.Wait()
1223-
}
1224-
12251218
func catchFrontendError(retErr, frontendErr *error) {
12261219
*frontendErr = *retErr
12271220
if errors.Is(*retErr, ErrRestart) {

build/invoke.go

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,18 @@ import (
1414
)
1515

1616
type InvokeConfig struct {
17-
Entrypoint []string
18-
Cmd []string
19-
NoCmd bool
20-
Env []string
21-
User string
22-
NoUser bool
23-
Cwd string
24-
NoCwd bool
25-
Tty bool
26-
Rollback bool
27-
Initial bool
28-
SuspendOn SuspendOn
17+
Entrypoint []string `json:"entrypoint,omitempty"`
18+
Cmd []string `json:"cmd,omitempty"`
19+
NoCmd bool `json:"noCmd,omitempty"`
20+
Env []string `json:"env,omitempty"`
21+
User string `json:"user,omitempty"`
22+
NoUser bool `json:"noUser,omitempty"`
23+
Cwd string `json:"cwd,omitempty"`
24+
NoCwd bool `json:"noCwd,omitempty"`
25+
Tty bool `json:"tty,omitempty"`
26+
Rollback bool `json:"rollback,omitempty"`
27+
Initial bool `json:"initial,omitempty"`
28+
SuspendOn SuspendOn `json:"suspendOn,omitempty"`
2929
}
3030

3131
func (cfg *InvokeConfig) NeedsDebug(err error) bool {
@@ -43,6 +43,18 @@ func (s SuspendOn) DebugEnabled(err error) bool {
4343
return err != nil || s == SuspendAlways
4444
}
4545

46+
func (s *SuspendOn) UnmarshalText(text []byte) error {
47+
switch string(text) {
48+
case "error":
49+
*s = SuspendError
50+
case "always":
51+
*s = SuspendAlways
52+
default:
53+
return errors.Errorf("unknown suspend name: %s", string(text))
54+
}
55+
return nil
56+
}
57+
4658
type Container struct {
4759
cancelOnce sync.Once
4860
containerCancel func(error)

build/result.go

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,18 @@ import (
1616
"github.com/sirupsen/logrus"
1717
)
1818

19-
// NewResultHandle stores a gateway client, gateway result, and the error from
19+
// NewResultHandle stores a gateway client, gateway reference, and the error from
2020
// an evaluate call if it is present.
2121
//
2222
// This ResultHandle can be used to execute additional build steps in the same
2323
// context as the build occurred, which can allow easy debugging of build
2424
// failures and successes.
2525
//
2626
// If the returned ResultHandle is not nil, the caller must call Done() on it.
27-
func NewResultHandle(ctx context.Context, c gateway.Client, res *gateway.Result, err error) *ResultHandle {
27+
func NewResultHandle(ctx context.Context, c gateway.Client, ref gateway.Reference, meta map[string][]byte, err error) *ResultHandle {
2828
rCtx := &ResultHandle{
29-
res: res,
29+
ref: ref,
30+
meta: meta,
3031
gwClient: c,
3132
}
3233
if err != nil && !errors.As(err, &rCtx.solveErr) {
@@ -37,8 +38,9 @@ func NewResultHandle(ctx context.Context, c gateway.Client, res *gateway.Result,
3738

3839
// ResultHandle is a build result with the client that built it.
3940
type ResultHandle struct {
40-
res *gateway.Result
41+
ref gateway.Reference
4142
solveErr *errdefs.SolveError
43+
meta map[string][]byte
4244
gwClient gateway.Client
4345

4446
doneOnce sync.Once
@@ -74,9 +76,9 @@ func (r *ResultHandle) NewContainer(ctx context.Context, cfg *InvokeConfig) (gat
7476
}
7577

7678
func (r *ResultHandle) getContainerConfig(cfg *InvokeConfig) (containerCfg gateway.NewContainerRequest, _ error) {
77-
if r.res != nil && r.solveErr == nil {
79+
if r.ref != nil && r.solveErr == nil {
7880
logrus.Debugf("creating container from successful build")
79-
ccfg, err := containerConfigFromResult(r.res, cfg)
81+
ccfg, err := containerConfigFromResult(r.ref, cfg)
8082
if err != nil {
8183
return containerCfg, err
8284
}
@@ -94,9 +96,9 @@ func (r *ResultHandle) getContainerConfig(cfg *InvokeConfig) (containerCfg gatew
9496

9597
func (r *ResultHandle) getProcessConfig(cfg *InvokeConfig, stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser) (_ gateway.StartRequest, err error) {
9698
processCfg := newStartRequest(stdin, stdout, stderr)
97-
if r.res != nil && r.solveErr == nil {
99+
if r.ref != nil && r.solveErr == nil {
98100
logrus.Debugf("creating container from successful build")
99-
if err := populateProcessConfigFromResult(&processCfg, r.res, cfg); err != nil {
101+
if err := populateProcessConfigFromResult(&processCfg, r.meta, cfg); err != nil {
100102
return processCfg, err
101103
}
102104
} else {
@@ -108,20 +110,11 @@ func (r *ResultHandle) getProcessConfig(cfg *InvokeConfig, stdin io.ReadCloser,
108110
return processCfg, nil
109111
}
110112

111-
func containerConfigFromResult(res *gateway.Result, cfg *InvokeConfig) (*gateway.NewContainerRequest, error) {
113+
func containerConfigFromResult(ref gateway.Reference, cfg *InvokeConfig) (*gateway.NewContainerRequest, error) {
112114
if cfg.Initial {
113115
return nil, errors.Errorf("starting from the container from the initial state of the step is supported only on the failed steps")
114116
}
115117

116-
ps, err := exptypes.ParsePlatforms(res.Metadata)
117-
if err != nil {
118-
return nil, err
119-
}
120-
ref, ok := res.FindRef(ps.Platforms[0].ID)
121-
if !ok {
122-
return nil, errors.Errorf("no reference found")
123-
}
124-
125118
return &gateway.NewContainerRequest{
126119
Mounts: []gateway.Mount{
127120
{
@@ -133,8 +126,8 @@ func containerConfigFromResult(res *gateway.Result, cfg *InvokeConfig) (*gateway
133126
}, nil
134127
}
135128

136-
func populateProcessConfigFromResult(req *gateway.StartRequest, res *gateway.Result, cfg *InvokeConfig) error {
137-
imgData := res.Metadata[exptypes.ExporterImageConfigKey]
129+
func populateProcessConfigFromResult(req *gateway.StartRequest, meta map[string][]byte, cfg *InvokeConfig) error {
130+
imgData := meta[exptypes.ExporterImageConfigKey]
138131
var img *ocispecs.Image
139132
if len(imgData) > 0 {
140133
img = &ocispecs.Image{}

0 commit comments

Comments
 (0)