Repository: go-delve/delve
Pull request #2040 (2020-05-05 18:07:15)

Adds launch request support for program args
Updates #1515 


Patch:
diff --git a/pkg/config/config.go b/pkg/config/config.go
index 1ac146c7..34fd6426 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -57,11 +57,24 @@ type Config struct {
 	// here: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors)
 	SourceListLineColor int `yaml:"source-list-line-color"`
 
+	// number of lines to list above and below cursor when printfile() is
+	// called (i.e. when execution stops, listCommand is used, etc)
+	SourceListLineCount *int `yaml:"source-list-line-count,omitempty"`
+
 	// DebugFileDirectories is the list of directories Delve will use
 	// in order to resolve external debug info files.
 	DebugInfoDirectories []string `yaml:"debug-info-directories"`
 }
 
+func (c *Config) GetSourceListLineCount() int {
+	n := 5 // default value
+	lcp := c.SourceListLineCount
+	if lcp != nil && *lcp >= 0 {
+		n = *lcp
+	}
+	return n
+}
+
 // LoadConfig attempts to populate a Config object from the config.yml file.
 func LoadConfig() *Config {
 	err := createConfigPath()
@@ -204,6 +217,10 @@ func writeDefaultConfig(f *os.File) error {
 # dark blue) See https://en.wikipedia.org/wiki/ANSI_escape_code#3/4_bit
 # source-list-line-color: 34
 
+# Uncomment to change the number of lines printed above and below cursor when
+# listing source code.
+# source-list-line-count: 5
+
 # Provided aliases will be added to the default aliases for a given command.
 aliases:
   # command: ["alias1", "alias2"]
diff --git a/pkg/gobuild/gobuild.go b/pkg/gobuild/gobuild.go
index e8a04b7a..fde64f80 100644
--- a/pkg/gobuild/gobuild.go
+++ b/pkg/gobuild/gobuild.go
@@ -68,5 +68,6 @@ func gocommand(command string, args ...string) error {
 	allargs = append(allargs, args...)
 	goBuild := exec.Command("go", allargs...)
 	goBuild.Stderr = os.Stderr
+	goBuild.Stdout = os.Stdout
 	return goBuild.Run()
 }
diff --git a/pkg/terminal/command.go b/pkg/terminal/command.go
index 5e9c2e7f..94f28459 100644
--- a/pkg/terminal/command.go
+++ b/pkg/terminal/command.go
@@ -2227,20 +2227,22 @@ func printfile(t *Term, filename string, line int, showArrow bool) error {
 		fmt.Println("Warning: listing may not match stale executable")
 	}
 
+	lineCount := t.conf.GetSourceListLineCount()
+
 	buf := bufio.NewScanner(file)
 	l := line
-	for i := 1; i < l-5; i++ {
+	for i := 1; i < l-lineCount; i++ {
 		if !buf.Scan() {
 			return nil
 		}
 	}
 
-	s := l - 5
+	s := l - lineCount
 	if s < 1 {
 		s = 1
 	}
 
-	for i := s; i <= l+5; i++ {
+	for i := s; i <= l+lineCount; i++ {
 		if !buf.Scan() {
 			return nil
 		}
diff --git a/service/dap/server.go b/service/dap/server.go
index 847de76f..eb140818 100644
--- a/service/dap/server.go
+++ b/service/dap/server.go
@@ -434,13 +434,33 @@ func (s *Server) onLaunchRequest(request *dap.LaunchRequest) {
 	stop, ok := request.Arguments["stopOnEntry"]
 	s.stopOnEntry = ok && stop == true
 
-	// TODO(polina): support target args
-	s.config.ProcessArgs = []string{program}
+	var targetArgs []string
+	args, ok := request.Arguments["args"]
+	if ok {
+		argsParsed, ok := args.([]interface{})
+		if !ok {
+			s.sendErrorResponse(request.Request,
+				FailedToContinue, "Failed to launch",
+				fmt.Sprintf("'args' attribute '%v' in debug configuration is not an array.", args))
+			return
+		}
+		for _, arg := range argsParsed {
+			argParsed, ok := arg.(string)
+			if !ok {
+				s.sendErrorResponse(request.Request,
+					FailedToContinue, "Failed to launch",
+					fmt.Sprintf("value '%v' in 'args' attribute in debug configuration is not a string.", arg))
+				return
+			}
+			targetArgs = append(targetArgs, argParsed)
+		}
+	}
+
+	s.config.ProcessArgs = append([]string{program}, targetArgs...)
 	s.config.Debugger.WorkingDir = filepath.Dir(program)
 
-	config := s.config.Debugger
 	var err error
-	if s.debugger, err = debugger.New(&config, s.config.ProcessArgs); err != nil {
+	if s.debugger, err = debugger.New(&s.config.Debugger, s.config.ProcessArgs); err != nil {
 		s.sendErrorResponse(request.Request,
 			FailedToContinue, "Failed to launch", err.Error())
 		return
@@ -686,7 +706,7 @@ func (s *Server) onCancelRequest(request *dap.CancelRequest) {
 	s.sendNotYetImplementedErrorResponse(request.Request)
 }
 
-func (s *Server) sendErrorResponse(request dap.Request, id int, summary string, details string) {
+func (s *Server) sendErrorResponse(request dap.Request, id int, summary, details string) {
 	er := &dap.ErrorResponse{}
 	er.Type = "response"
 	er.Command = request.Command


Test patch:
diff --git a/service/dap/server_test.go b/service/dap/server_test.go
index 2577419e..d020f16e 100644
--- a/service/dap/server_test.go
+++ b/service/dap/server_test.go
@@ -366,6 +366,16 @@ func TestLaunchTestRequest(t *testing.T) {
 	})
 }
 
+func TestLaunchRequestWithArgs(t *testing.T) {
+	runTest(t, "testargs", func(client *daptest.Client, fixture protest.Fixture) {
+		runDebugSession(t, client, func() {
+			client.LaunchRequestWithArgs(map[string]interface{}{
+				"mode": "exec", "program": fixture.Path,
+				"args": []string{"test", "pass flag"}})
+		})
+	})
+}
+
 func TestUnupportedCommandResponses(t *testing.T) {
 	var got *dap.ErrorResponse
 	runTest(t, "increment", func(client *daptest.Client, fixture protest.Fixture) {
@@ -564,6 +574,18 @@ func TestBadLaunchRequests(t *testing.T) {
 		expectFailedToLaunchWithMessage(client.ExpectErrorResponse(t),
 			"Failed to launch: Unsupported 'mode' value %!q(float64=12345) in debug configuration.")
 
+		client.LaunchRequestWithArgs(map[string]interface{}{"mode": "exec", "program": fixture.Path, "args": nil})
+		expectFailedToLaunchWithMessage(client.ExpectErrorResponse(t),
+			"Failed to launch: 'args' attribute '<nil>' in debug configuration is not an array.")
+
+		client.LaunchRequestWithArgs(map[string]interface{}{"mode": "exec", "program": fixture.Path, "args": 12345})
+		expectFailedToLaunchWithMessage(client.ExpectErrorResponse(t),
+			"Failed to launch: 'args' attribute '12345' in debug configuration is not an array.")
+
+		client.LaunchRequestWithArgs(map[string]interface{}{"mode": "exec", "program": fixture.Path, "args": []int{1, 2}})
+		expectFailedToLaunchWithMessage(client.ExpectErrorResponse(t),
+			"Failed to launch: value '1' in 'args' attribute in debug configuration is not a string.")
+
 		// Skip detailed message checks for potentially different OS-specific errors.
 		client.LaunchRequest("exec", fixture.Path+"_does_not_exist", stopOnEntry)
 		expectFailedToLaunch(client.ExpectErrorResponse(t))