Skip to content

Commit

Permalink
service/dap: accept a string list as launch request's buildFlags
Browse files Browse the repository at this point in the history
This change accepts both string type and []string (actually,
[]interface{} type due to Go's json decoding behavior.

Fixes go-delve#2718
For golang/vscode-go#1831, golang/vscode-go#1027
  • Loading branch information
hyangah committed Sep 7, 2023
1 parent f469a0a commit 84a23b1
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 7 deletions.
44 changes: 40 additions & 4 deletions pkg/gobuild/gobuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,11 @@ func GoBuild(debugname string, pkgs []string, buildflags string) error {

// GoBuildCombinedOutput builds non-test files in 'pkgs' with the specified 'buildflags'
// and writes the output at 'debugname'.
func GoBuildCombinedOutput(debugname string, pkgs []string, buildflags string) (string, []byte, error) {
args := goBuildArgs(debugname, pkgs, buildflags, false)
func GoBuildCombinedOutput(debugname string, pkgs []string, buildflags interface{}) (string, []byte, error) {
args, err := goBuildArgs2(debugname, pkgs, buildflags, false)
if err != nil {
return "", nil, err
}
return gocommandCombinedOutput("build", args...)
}

Expand All @@ -55,8 +58,11 @@ func GoTestBuild(debugname string, pkgs []string, buildflags string) error {

// GoTestBuildCombinedOutput builds test files 'pkgs' with the specified 'buildflags'
// and writes the output at 'debugname'.
func GoTestBuildCombinedOutput(debugname string, pkgs []string, buildflags string) (string, []byte, error) {
args := goBuildArgs(debugname, pkgs, buildflags, true)
func GoTestBuildCombinedOutput(debugname string, pkgs []string, buildflags interface{}) (string, []byte, error) {
args, err := goBuildArgs2(debugname, pkgs, buildflags, true)
if err != nil {
return "", nil, err
}
return gocommandCombinedOutput("test", args...)
}

Expand Down Expand Up @@ -84,6 +90,36 @@ func goBuildArgs(debugname string, pkgs []string, buildflags string, isTest bool
return args
}

// goBuildArgs2 is like goBuildArgs, but takes either string, []string, or []interface{}.
func goBuildArgs2(debugname string, pkgs []string, buildflags interface{}, isTest bool) ([]string, error) {
var args []string
switch buildflags := buildflags.(type) {
case string:
return goBuildArgs(debugname, pkgs, buildflags, false), nil
case nil:
case []string:
args = append(args, buildflags...)
case []interface{}:
for _, flag := range buildflags {
switch flag := flag.(type) {
case string:
args = append(args, flag)
default:
return nil, fmt.Errorf("invalid buildflags element type %T (%q)", flag, flag)
}
}
default:
return nil, fmt.Errorf("invalid buildflags type %T", buildflags)
}

args = append(args, "-o", debugname)
if isTest {
args = append([]string{"-c"}, args...)
}
args = append(args, "-gcflags", "all=-N -l")
return append(args, pkgs...), nil
}

func gocommandRun(command string, args ...string) error {
_, goBuild := gocommandExecCmd(command, args...)
goBuild.Stderr = os.Stdout
Expand Down
12 changes: 12 additions & 0 deletions service/dap/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5594,6 +5594,18 @@ func TestLaunchRequestWithBuildFlags(t *testing.T) {
})
}

func TestLaunchRequestWithBuildFlags2(t *testing.T) {
runTest(t, "buildflagtest", func(client *daptest.Client, fixture protest.Fixture) {
runDebugSession(t, client, "launch", func() {
// We reuse the harness that builds, but ignore the built binary,
// only relying on the source to be built in response to LaunchRequest.
client.LaunchRequestWithArgs(map[string]interface{}{
"mode": "debug", "program": fixture.Source, "output": "__mybin",
"buildFlags": []string{"-ldflags", "-X main.Hello=World"}})
})
})
}

func TestLaunchRequestWithEnv(t *testing.T) {
// testenv fixture will lookup SOMEVAR with
// x, y := os.Lookup("SOMEVAR")
Expand Down
12 changes: 9 additions & 3 deletions service/dap/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,15 @@ type LaunchConfig struct {
// Relative paths used in BuildFlags will be interpreted as paths
// relative to Delve's current working directory.
//
// It is like `dlv --build-flags`. For example,
// "buildFlags": "-tags=integration -mod=vendor -cover -v"
BuildFlags string `json:"buildFlags,omitempty"`
// It should be a string like `dlv --build-flags`, or
// an array of strings that is augmented when invoking the go build or
// test command through os/exec.Command API.
// For example, both forms are acceptible.
// "buildFlags": "-tags=integration -ldflags='-X main.Hello=World'"
// or
// "buildFlags": ["-tags=integration", "-ldflags=-X main.Hello=World"]
// Using other types is an error.
BuildFlags interface{} `json:"buildFlags,omitempty"`

// Output path for the binary of the debuggee.
// Relative path is interpreted as the path relative to
Expand Down

0 comments on commit 84a23b1

Please sign in to comment.