mirror of
https://github.com/go-delve/delve.git
synced 2025-11-02 21:40:22 +08:00
service/dap: move build error to output event (#2482)
This commit is contained in:
@ -7,6 +7,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-delve/delve/pkg/config"
|
"github.com/go-delve/delve/pkg/config"
|
||||||
@ -60,7 +61,7 @@ func GoBuild(debugname string, pkgs []string, buildflags string) error {
|
|||||||
|
|
||||||
// GoBuildCombinedOutput builds non-test files in 'pkgs' with the specified 'buildflags'
|
// GoBuildCombinedOutput builds non-test files in 'pkgs' with the specified 'buildflags'
|
||||||
// and writes the output at 'debugname'.
|
// and writes the output at 'debugname'.
|
||||||
func GoBuildCombinedOutput(debugname string, pkgs []string, buildflags string) ([]byte, error) {
|
func GoBuildCombinedOutput(debugname string, pkgs []string, buildflags string) (string, []byte, error) {
|
||||||
args := goBuildArgs(debugname, pkgs, buildflags, false)
|
args := goBuildArgs(debugname, pkgs, buildflags, false)
|
||||||
return gocommandCombinedOutput("build", args...)
|
return gocommandCombinedOutput("build", args...)
|
||||||
}
|
}
|
||||||
@ -74,7 +75,7 @@ func GoTestBuild(debugname string, pkgs []string, buildflags string) error {
|
|||||||
|
|
||||||
// GoTestBuildCombinedOutput builds test files 'pkgs' with the specified 'buildflags'
|
// GoTestBuildCombinedOutput builds test files 'pkgs' with the specified 'buildflags'
|
||||||
// and writes the output at 'debugname'.
|
// and writes the output at 'debugname'.
|
||||||
func GoTestBuildCombinedOutput(debugname string, pkgs []string, buildflags string) ([]byte, error) {
|
func GoTestBuildCombinedOutput(debugname string, pkgs []string, buildflags string) (string, []byte, error) {
|
||||||
args := goBuildArgs(debugname, pkgs, buildflags, true)
|
args := goBuildArgs(debugname, pkgs, buildflags, true)
|
||||||
return gocommandCombinedOutput("test", args...)
|
return gocommandCombinedOutput("test", args...)
|
||||||
}
|
}
|
||||||
@ -93,19 +94,21 @@ func goBuildArgs(debugname string, pkgs []string, buildflags string, isTest bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
func gocommandRun(command string, args ...string) error {
|
func gocommandRun(command string, args ...string) error {
|
||||||
goBuild := gocommandExecCmd(command, args...)
|
_, goBuild := gocommandExecCmd(command, args...)
|
||||||
goBuild.Stderr = os.Stdout
|
goBuild.Stderr = os.Stdout
|
||||||
goBuild.Stdout = os.Stderr
|
goBuild.Stdout = os.Stderr
|
||||||
return goBuild.Run()
|
return goBuild.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func gocommandCombinedOutput(command string, args ...string) ([]byte, error) {
|
func gocommandCombinedOutput(command string, args ...string) (string, []byte, error) {
|
||||||
return gocommandExecCmd(command, args...).CombinedOutput()
|
buildCmd, goBuild := gocommandExecCmd(command, args...)
|
||||||
|
out, err := goBuild.CombinedOutput()
|
||||||
|
return buildCmd, out, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func gocommandExecCmd(command string, args ...string) *exec.Cmd {
|
func gocommandExecCmd(command string, args ...string) (string, *exec.Cmd) {
|
||||||
allargs := []string{command}
|
allargs := []string{command}
|
||||||
allargs = append(allargs, args...)
|
allargs = append(allargs, args...)
|
||||||
goBuild := exec.Command("go", allargs...)
|
goBuild := exec.Command("go", allargs...)
|
||||||
return goBuild
|
return strings.Join(append([]string{"go"}, allargs...), " "), goBuild
|
||||||
}
|
}
|
||||||
|
|||||||
@ -723,17 +723,24 @@ func (s *Server) onLaunchRequest(request *dap.LaunchRequest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s.log.Debugf("building binary at %s", debugbinary)
|
s.log.Debugf("building binary at %s", debugbinary)
|
||||||
|
var cmd string
|
||||||
var out []byte
|
var out []byte
|
||||||
switch mode {
|
switch mode {
|
||||||
case "debug":
|
case "debug":
|
||||||
out, err = gobuild.GoBuildCombinedOutput(debugbinary, []string{program}, buildFlags)
|
cmd, out, err = gobuild.GoBuildCombinedOutput(debugbinary, []string{program}, buildFlags)
|
||||||
case "test":
|
case "test":
|
||||||
out, err = gobuild.GoTestBuildCombinedOutput(debugbinary, []string{program}, buildFlags)
|
cmd, out, err = gobuild.GoTestBuildCombinedOutput(debugbinary, []string{program}, buildFlags)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
s.send(&dap.OutputEvent{
|
||||||
|
Event: *newEvent("output"),
|
||||||
|
Body: dap.OutputEventBody{
|
||||||
|
Output: fmt.Sprintf("Build Error: %s\n%s (%s)\n", cmd, strings.TrimSpace(string(out)), err.Error()),
|
||||||
|
Category: "stderr",
|
||||||
|
}})
|
||||||
s.sendErrorResponse(request.Request,
|
s.sendErrorResponse(request.Request,
|
||||||
FailedToLaunch, "Failed to launch",
|
FailedToLaunch, "Failed to launch",
|
||||||
fmt.Sprintf("Build error: %s (%s)", strings.TrimSpace(string(out)), err.Error()))
|
"Build error: Check the debug console for details.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
program = debugbinary
|
program = debugbinary
|
||||||
|
|||||||
@ -3144,14 +3144,6 @@ func TestBadLaunchRequests(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expectFailedToLaunchWithMessageRegex := func(response *dap.ErrorResponse, errmsg string) {
|
|
||||||
t.Helper()
|
|
||||||
expectFailedToLaunch(response)
|
|
||||||
if matched, _ := regexp.MatchString(errmsg, response.Body.Error.Format); !matched {
|
|
||||||
t.Errorf("\ngot %q\nwant %q", response.Body.Error.Format, errmsg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test for the DAP-specific detailed error message.
|
// Test for the DAP-specific detailed error message.
|
||||||
client.LaunchRequest("exec", "", stopOnEntry)
|
client.LaunchRequest("exec", "", stopOnEntry)
|
||||||
expectFailedToLaunchWithMessage(client.ExpectInvisibleErrorResponse(t),
|
expectFailedToLaunchWithMessage(client.ExpectInvisibleErrorResponse(t),
|
||||||
@ -3233,18 +3225,34 @@ func TestBadLaunchRequests(t *testing.T) {
|
|||||||
expectFailedToLaunch(client.ExpectInvisibleErrorResponse(t)) // No such file or directory
|
expectFailedToLaunch(client.ExpectInvisibleErrorResponse(t)) // No such file or directory
|
||||||
|
|
||||||
client.LaunchRequest("debug", fixture.Path+"_does_not_exist", stopOnEntry)
|
client.LaunchRequest("debug", fixture.Path+"_does_not_exist", stopOnEntry)
|
||||||
|
oe := client.ExpectOutputEvent(t)
|
||||||
|
if !strings.HasPrefix(oe.Body.Output, "Build Error: ") || oe.Body.Category != "stderr" {
|
||||||
|
t.Errorf("got %#v, want Category=\"stderr\" Output=\"Build Error: ...\"", oe)
|
||||||
|
}
|
||||||
expectFailedToLaunch(client.ExpectInvisibleErrorResponse(t))
|
expectFailedToLaunch(client.ExpectInvisibleErrorResponse(t))
|
||||||
|
|
||||||
client.LaunchRequest("" /*debug by default*/, fixture.Path+"_does_not_exist", stopOnEntry)
|
client.LaunchRequest("" /*debug by default*/, fixture.Path+"_does_not_exist", stopOnEntry)
|
||||||
|
oe = client.ExpectOutputEvent(t)
|
||||||
|
if !strings.HasPrefix(oe.Body.Output, "Build Error: ") || oe.Body.Category != "stderr" {
|
||||||
|
t.Errorf("got %#v, want Category=\"stderr\" Output=\"Build Error: ...\"", oe)
|
||||||
|
}
|
||||||
expectFailedToLaunch(client.ExpectInvisibleErrorResponse(t))
|
expectFailedToLaunch(client.ExpectInvisibleErrorResponse(t))
|
||||||
|
|
||||||
client.LaunchRequest("exec", fixture.Source, stopOnEntry)
|
client.LaunchRequest("exec", fixture.Source, stopOnEntry)
|
||||||
expectFailedToLaunch(client.ExpectInvisibleErrorResponse(t)) // Not an executable
|
expectFailedToLaunch(client.ExpectInvisibleErrorResponse(t)) // Not an executable
|
||||||
|
|
||||||
client.LaunchRequestWithArgs(map[string]interface{}{"mode": "debug", "program": fixture.Source, "buildFlags": "-bad -flags"})
|
client.LaunchRequestWithArgs(map[string]interface{}{"mode": "debug", "program": fixture.Source, "buildFlags": "-bad -flags"})
|
||||||
expectFailedToLaunchWithMessageRegex(client.ExpectInvisibleErrorResponse(t), `Failed to launch: Build error: .*flag provided but not defined.*`)
|
oe = client.ExpectOutputEvent(t)
|
||||||
|
if !strings.HasPrefix(oe.Body.Output, "Build Error: ") || oe.Body.Category != "stderr" {
|
||||||
|
t.Errorf("got %#v, want Category=\"stderr\" Output=\"Build Error: ...\"", oe)
|
||||||
|
}
|
||||||
|
expectFailedToLaunchWithMessage(client.ExpectInvisibleErrorResponse(t), "Failed to launch: Build error: Check the debug console for details.")
|
||||||
client.LaunchRequestWithArgs(map[string]interface{}{"mode": "debug", "program": fixture.Source, "noDebug": true, "buildFlags": "-bad -flags"})
|
client.LaunchRequestWithArgs(map[string]interface{}{"mode": "debug", "program": fixture.Source, "noDebug": true, "buildFlags": "-bad -flags"})
|
||||||
expectFailedToLaunchWithMessageRegex(client.ExpectInvisibleErrorResponse(t), `Failed to launch: Build error: .*flag provided but not defined.*`)
|
oe = client.ExpectOutputEvent(t)
|
||||||
|
if !strings.HasPrefix(oe.Body.Output, "Build Error: ") || oe.Body.Category != "stderr" {
|
||||||
|
t.Errorf("got %#v, want Category=\"stderr\" Output=\"Build Error: ...\"", oe)
|
||||||
|
}
|
||||||
|
expectFailedToLaunchWithMessage(client.ExpectInvisibleErrorResponse(t), "Failed to launch: Build error: Check the debug console for details.")
|
||||||
|
|
||||||
// Bad "wd".
|
// Bad "wd".
|
||||||
client.LaunchRequestWithArgs(map[string]interface{}{"mode": "debug", "program": fixture.Source, "noDebug": false, "cwd": "dir/invalid"})
|
client.LaunchRequestWithArgs(map[string]interface{}{"mode": "debug", "program": fixture.Source, "noDebug": false, "cwd": "dir/invalid"})
|
||||||
|
|||||||
Reference in New Issue
Block a user