Files
buildx/commands/dap.go
T
Jonathan A. Sternberg 42599a7d49 dap: add debug adapter implementation
Adds a simple implementation of the debug adapter that supports the very
basics of a debug adapter.

It supports the launch request, the configuration done request, the
creation of threads, stopping, resuming, and disconnecting from server.

It does not support custom breakpoints, stack traces, or variable
inspection yet. These are planned to be added in the future.

Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com>
2025-06-30 10:51:20 -05:00

82 lines
2.0 KiB
Go

package commands
import (
"context"
"github.com/docker/buildx/dap"
"github.com/docker/buildx/util/cobrautil"
"github.com/docker/buildx/util/ioset"
"github.com/docker/buildx/util/progress"
"github.com/docker/cli/cli/command"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
func dapCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
var options dapOptions
cmd := &cobra.Command{
Use: "dap",
Short: "Start debug adapter protocol compatible debugger",
}
cobrautil.MarkCommandExperimental(cmd)
flags := cmd.Flags()
flags.StringVar(&options.OnFlag, "on", "error", "When to pause the adapter ([always, error])")
cobrautil.MarkFlagsExperimental(flags, "on")
dapBuildCmd := buildCmd(dockerCli, rootOpts, &options)
dapBuildCmd.Args = cobra.RangeArgs(0, 1)
cmd.AddCommand(dapBuildCmd)
return cmd
}
type dapOptions struct {
// OnFlag is a flag to configure the timing of launching the debugger.
OnFlag string
}
func (d *dapOptions) New(in ioset.In) (debuggerInstance, error) {
invokeConfig, err := parseInvokeConfig("", d.OnFlag)
if err != nil {
return nil, err
}
conn := dap.NewConn(in.Stdin, in.Stdout)
return &adapterProtocolDebugger{
Adapter: dap.New[LaunchConfig](invokeConfig),
conn: conn,
}, nil
}
type LaunchConfig struct {
Dockerfile string `json:"dockerfile,omitempty"`
ContextPath string `json:"contextPath,omitempty"`
Target string `json:"target,omitempty"`
}
type adapterProtocolDebugger struct {
*dap.Adapter[LaunchConfig]
conn dap.Conn
}
func (d *adapterProtocolDebugger) Start(printer *progress.Printer, opts *BuildOptions) error {
cfg, err := d.Adapter.Start(context.Background(), d.conn)
if err != nil {
return errors.Wrap(err, "debug adapter did not start")
}
if cfg.Dockerfile != "" {
opts.DockerfileName = cfg.Dockerfile
}
if cfg.ContextPath != "" {
opts.ContextPath = cfg.ContextPath
}
return nil
}
func (d *adapterProtocolDebugger) Stop() error {
defer d.conn.Close()
return d.Adapter.Stop()
}