Skip to content

Commit 4f9f47d

Browse files
authored
Merge pull request #3341 from jsternberg/dap-persistent-exec
dap: make exec shell persistent across the build
2 parents da81bc1 + dbda218 commit 4f9f47d

File tree

5 files changed

+414
-62
lines changed

5 files changed

+414
-62
lines changed

build/result.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
package build
22

33
import (
4+
"cmp"
45
"context"
56
_ "crypto/sha256" // ensure digests can be computed
67
"encoding/json"
78
"io"
9+
iofs "io/fs"
10+
"path/filepath"
11+
"slices"
12+
"strings"
813
"sync"
914

1015
"github.com/moby/buildkit/exporter/containerimage/exptypes"
@@ -14,6 +19,7 @@ import (
1419
ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
1520
"github.com/pkg/errors"
1621
"github.com/sirupsen/logrus"
22+
"github.com/tonistiigi/fsutil/types"
1723
)
1824

1925
// NewResultHandle stores a gateway client, gateway reference, and the error from
@@ -75,6 +81,40 @@ func (r *ResultHandle) NewContainer(ctx context.Context, cfg *InvokeConfig) (gat
7581
return r.gwClient.NewContainer(ctx, req)
7682
}
7783

84+
func (r *ResultHandle) StatFile(ctx context.Context, fpath string, cfg *InvokeConfig) (*types.Stat, error) {
85+
containerCfg, err := r.getContainerConfig(cfg)
86+
if err != nil {
87+
return nil, err
88+
}
89+
90+
candidateMounts := make([]gateway.Mount, 0, len(containerCfg.Mounts))
91+
for _, m := range containerCfg.Mounts {
92+
if strings.HasPrefix(fpath, m.Dest) {
93+
candidateMounts = append(candidateMounts, m)
94+
}
95+
}
96+
if len(candidateMounts) == 0 {
97+
return nil, iofs.ErrNotExist
98+
}
99+
100+
slices.SortFunc(candidateMounts, func(a, b gateway.Mount) int {
101+
return cmp.Compare(len(a.Dest), len(b.Dest))
102+
})
103+
104+
m := candidateMounts[len(candidateMounts)-1]
105+
relpath, err := filepath.Rel(m.Dest, fpath)
106+
if err != nil {
107+
return nil, err
108+
}
109+
110+
if m.Ref == nil {
111+
return nil, iofs.ErrNotExist
112+
}
113+
114+
req := gateway.StatRequest{Path: filepath.ToSlash(relpath)}
115+
return m.Ref.StatFile(ctx, req)
116+
}
117+
78118
func (r *ResultHandle) getContainerConfig(cfg *InvokeConfig) (containerCfg gateway.NewContainerRequest, _ error) {
79119
if r.ref != nil && r.solveErr == nil {
80120
logrus.Debugf("creating container from successful build")

dap/adapter.go

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,14 @@ type Adapter[C LaunchConfig] struct {
3838
threadsMu sync.RWMutex
3939
nextThreadID int
4040

41+
sharedState
42+
}
43+
44+
type sharedState struct {
4145
breakpointMap *breakpointMap
42-
sourceMap sourceMap
46+
sourceMap *sourceMap
4347
idPool *idPool
48+
sh *shell
4449
}
4550

4651
func New[C LaunchConfig]() *Adapter[C] {
@@ -51,8 +56,12 @@ func New[C LaunchConfig]() *Adapter[C] {
5156
evaluateReqCh: make(chan *evaluateRequest),
5257
threads: make(map[int]*thread),
5358
nextThreadID: 1,
54-
breakpointMap: newBreakpointMap(),
55-
idPool: new(idPool),
59+
sharedState: sharedState{
60+
breakpointMap: newBreakpointMap(),
61+
sourceMap: new(sourceMap),
62+
idPool: new(idPool),
63+
sh: newShell(),
64+
},
5665
}
5766
d.srv = NewServer(d.dapHandler())
5867
return d
@@ -233,12 +242,10 @@ func (d *Adapter[C]) newThread(ctx Context, name string) (t *thread) {
233242
d.threadsMu.Lock()
234243
id := d.nextThreadID
235244
t = &thread{
236-
id: id,
237-
name: name,
238-
sourceMap: &d.sourceMap,
239-
breakpointMap: d.breakpointMap,
240-
idPool: d.idPool,
241-
variables: newVariableReferences(),
245+
id: id,
246+
name: name,
247+
sharedState: d.sharedState,
248+
variables: newVariableReferences(),
242249
}
243250
d.threads[t.id] = t
244251
d.nextThreadID++
@@ -261,20 +268,6 @@ func (d *Adapter[C]) getThread(id int) (t *thread) {
261268
return t
262269
}
263270

264-
func (d *Adapter[C]) getFirstThread() (t *thread) {
265-
d.threadsMu.Lock()
266-
defer d.threadsMu.Unlock()
267-
268-
for _, thread := range d.threads {
269-
if thread.isPaused() {
270-
if t == nil || thread.id < t.id {
271-
t = thread
272-
}
273-
}
274-
}
275-
return t
276-
}
277-
278271
func (d *Adapter[C]) deleteThread(ctx Context, t *thread) {
279272
d.threadsMu.Lock()
280273
if t := d.threads[t.id]; t != nil {

0 commit comments

Comments
 (0)