service/dap: expose sources command in evaluate request (#2797)

* service/dap: expose sources command in evaluate request
This commit is contained in:
Suzy Mueller 2021-11-24 16:38:37 -05:00 committed by GitHub
parent 389cccf08b
commit 935161f8bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 11 deletions

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"errors" "errors"
"fmt" "fmt"
"sort"
"strings" "strings"
"github.com/go-delve/delve/pkg/config" "github.com/go-delve/delve/pkg/config"
@ -37,24 +38,29 @@ type command struct {
const ( const (
msgHelp = `Prints the help message. msgHelp = `Prints the help message.
help [command] dlv help [command]
Type "help" followed by the name of a command for more information about it.` Type "help" followed by the name of a command for more information about it.`
msgConfig = `Changes configuration parameters. msgConfig = `Changes configuration parameters.
config -list dlv config -list
Show all configuration parameters. Show all configuration parameters.
config <parameter> <value> dlv config <parameter> <value>
Changes the value of a configuration parameter. Changes the value of a configuration parameter.
config substitutePath <from> <to> dlv config substitutePath <from> <to>
config substitutePath <from> dlv config substitutePath <from>
Adds or removes a path substitution rule.` Adds or removes a path substitution rule.`
msgSources = `Print list of source files.
dlv sources [<regex>]
If regex is specified only the source files matching it will be returned.`
) )
// debugCommands returns a list of commands with default commands defined. // debugCommands returns a list of commands with default commands defined.
@ -62,6 +68,7 @@ func debugCommands(s *Session) []command {
return []command{ return []command{
{aliases: []string{"help", "h"}, cmdFn: s.helpMessage, helpMsg: msgHelp}, {aliases: []string{"help", "h"}, cmdFn: s.helpMessage, helpMsg: msgHelp},
{aliases: []string{"config"}, cmdFn: s.evaluateConfig, helpMsg: msgConfig}, {aliases: []string{"config"}, cmdFn: s.evaluateConfig, helpMsg: msgConfig},
{aliases: []string{"sources", "s"}, cmdFn: s.sources, helpMsg: msgSources},
} }
} }
@ -88,14 +95,14 @@ func (s *Session) helpMessage(_, _ int, args string) (string, error) {
h = h[:idx] h = h[:idx]
} }
if len(cmd.aliases) > 1 { if len(cmd.aliases) > 1 {
fmt.Fprintf(&buf, " %s (alias: %s) \t %s\n", cmd.aliases[0], strings.Join(cmd.aliases[1:], " | "), h) fmt.Fprintf(&buf, " dlv %s (alias: %s) \t %s\n", cmd.aliases[0], strings.Join(cmd.aliases[1:], " | "), h)
} else { } else {
fmt.Fprintf(&buf, " %s \t %s\n", cmd.aliases[0], h) fmt.Fprintf(&buf, " dlv %s \t %s\n", cmd.aliases[0], h)
} }
} }
fmt.Fprintln(&buf) fmt.Fprintln(&buf)
fmt.Fprintln(&buf, "Type help followed by a command for full documentation.") fmt.Fprintln(&buf, "Type 'dlv help' followed by a command for full documentation.")
return buf.String(), nil return buf.String(), nil
} }
@ -113,3 +120,12 @@ func (s *Session) evaluateConfig(_, _ int, expr string) (string, error) {
return res, nil return res, nil
} }
} }
func (s *Session) sources(_, _ int, filter string) (string, error) {
sources, err := s.debugger.Sources(filter)
if err != nil {
return "", err
}
sort.Strings(sources)
return strings.Join(sources, "\n"), nil
}

@ -3846,10 +3846,11 @@ func TestEvaluateCommandRequest(t *testing.T) {
// Request help. // Request help.
const dlvHelp = `The following commands are available: const dlvHelp = `The following commands are available:
help (alias: h) Prints the help message. dlv help (alias: h) Prints the help message.
config Changes configuration parameters. dlv config Changes configuration parameters.
dlv sources (alias: s) Print list of source files.
Type help followed by a command for full documentation. Type 'dlv help' followed by a command for full documentation.
` `
client.EvaluateRequest("dlv help", 1000, "repl") client.EvaluateRequest("dlv help", 1000, "repl")
got := client.ExpectEvaluateResponse(t) got := client.ExpectEvaluateResponse(t)
@ -3909,6 +3910,25 @@ Type help followed by a command for full documentation.
got = client.ExpectEvaluateResponse(t) got = client.ExpectEvaluateResponse(t)
checkEval(t, got, "substitutePath\t[]\n\nUpdated", noChildren) checkEval(t, got, "substitutePath\t[]\n\nUpdated", noChildren)
// Test sources.
client.EvaluateRequest("dlv sources", 1000, "repl")
got = client.ExpectEvaluateResponse(t)
if !strings.Contains(got.Body.Result, fixture.Source) {
t.Errorf("\ngot: %#v, want sources contains %s", got, fixture.Source)
}
client.EvaluateRequest(fmt.Sprintf("dlv sources .*%s", strings.ReplaceAll(filepath.Base(fixture.Source), ".", "\\.")), 1000, "repl")
got = client.ExpectEvaluateResponse(t)
if got.Body.Result != fixture.Source {
t.Errorf("\ngot: %#v, want sources=%q", got, fixture.Source)
}
client.EvaluateRequest("dlv sources nonexistentsource", 1000, "repl")
got = client.ExpectEvaluateResponse(t)
if got.Body.Result != "" {
t.Errorf("\ngot: %#v, want sources=\"\"", got)
}
// Test bad inputs. // Test bad inputs.
client.EvaluateRequest("dlv help bad", 1000, "repl") client.EvaluateRequest("dlv help bad", 1000, "repl")
client.ExpectErrorResponse(t) client.ExpectErrorResponse(t)