Unverified Commit d41da430 authored by Cristian Maglie's avatar Cristian Maglie Committed by GitHub

Added `debug check` command to check if a combination of board/programmer...

Added `debug check` command to check if a combination of board/programmer supports debugging. (#2443)

* Moved rcp message to proper position

* Added gRPC command to check for debugger support

* Made debug flags var non-global

* Implementation of 'debug check' command

* Implementation of cli command 'debug check'

* added integration test

* Renamed field for clarity

* Added minimum debug_fqbn computation in 'debug check' command
parent 5d3f7c5f
...@@ -30,6 +30,16 @@ type FQBN struct { ...@@ -30,6 +30,16 @@ type FQBN struct {
Configs *properties.Map Configs *properties.Map
} }
// MustParseFQBN extract an FQBN object from the input string
// or panics if the input is not a valid FQBN.
func MustParseFQBN(fqbnIn string) *FQBN {
res, err := ParseFQBN(fqbnIn)
if err != nil {
panic(err)
}
return res
}
// ParseFQBN extract an FQBN object from the input string // ParseFQBN extract an FQBN object from the input string
func ParseFQBN(fqbnIn string) (*FQBN, error) { func ParseFQBN(fqbnIn string) (*FQBN, error) {
// Split fqbn // Split fqbn
......
...@@ -66,3 +66,9 @@ func (s *ArduinoCoreServerImpl) GetDebugConfig(ctx context.Context, req *rpc.Get ...@@ -66,3 +66,9 @@ func (s *ArduinoCoreServerImpl) GetDebugConfig(ctx context.Context, req *rpc.Get
res, err := cmd.GetDebugConfig(ctx, req) res, err := cmd.GetDebugConfig(ctx, req)
return res, convertErrorToRPCStatus(err) return res, convertErrorToRPCStatus(err)
} }
// IsDebugSupported checks if debugging is supported for a given configuration
func (s *ArduinoCoreServerImpl) IsDebugSupported(ctx context.Context, req *rpc.IsDebugSupportedRequest) (*rpc.IsDebugSupportedResponse, error) {
res, err := cmd.IsDebugSupported(ctx, req)
return res, convertErrorToRPCStatus(err)
}
...@@ -118,7 +118,7 @@ func Debug(ctx context.Context, req *rpc.GetDebugConfigRequest, inStream io.Read ...@@ -118,7 +118,7 @@ func Debug(ctx context.Context, req *rpc.GetDebugConfigRequest, inStream io.Read
// getCommandLine compose a debug command represented by a core recipe // getCommandLine compose a debug command represented by a core recipe
func getCommandLine(req *rpc.GetDebugConfigRequest, pme *packagemanager.Explorer) ([]string, error) { func getCommandLine(req *rpc.GetDebugConfigRequest, pme *packagemanager.Explorer) ([]string, error) {
debugInfo, err := getDebugProperties(req, pme) debugInfo, err := getDebugProperties(req, pme, false)
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -18,6 +18,8 @@ package debug ...@@ -18,6 +18,8 @@ package debug
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"errors"
"reflect"
"slices" "slices"
"strconv" "strconv"
"strings" "strings"
...@@ -41,25 +43,83 @@ func GetDebugConfig(ctx context.Context, req *rpc.GetDebugConfigRequest) (*rpc.G ...@@ -41,25 +43,83 @@ func GetDebugConfig(ctx context.Context, req *rpc.GetDebugConfigRequest) (*rpc.G
return nil, &arduino.InvalidInstanceError{} return nil, &arduino.InvalidInstanceError{}
} }
defer release() defer release()
return getDebugProperties(req, pme) return getDebugProperties(req, pme, false)
} }
func getDebugProperties(req *rpc.GetDebugConfigRequest, pme *packagemanager.Explorer) (*rpc.GetDebugConfigResponse, error) { // IsDebugSupported checks if the given board/programmer configuration supports debugging.
// TODO: make a generic function to extract sketch from request func IsDebugSupported(ctx context.Context, req *rpc.IsDebugSupportedRequest) (*rpc.IsDebugSupportedResponse, error) {
// and remove duplication in commands/compile.go pme, release := instances.GetPackageManagerExplorer(req.GetInstance())
if req.GetSketchPath() == "" { if pme == nil {
return nil, &arduino.MissingSketchPathError{} return nil, &arduino.InvalidInstanceError{}
}
defer release()
configRequest := &rpc.GetDebugConfigRequest{
Instance: req.GetInstance(),
Fqbn: req.GetFqbn(),
SketchPath: "",
Port: req.GetPort(),
Interpreter: req.GetInterpreter(),
ImportDir: "",
Programmer: req.GetProgrammer(),
}
expectedOutput, err := getDebugProperties(configRequest, pme, true)
var x *arduino.FailedDebugError
if errors.As(err, &x) {
return &rpc.IsDebugSupportedResponse{DebuggingSupported: false}, nil
} }
sketchPath := paths.New(req.GetSketchPath())
sk, err := sketch.New(sketchPath)
if err != nil { if err != nil {
return nil, &arduino.CantOpenSketchError{Cause: err} return nil, err
}
// Compute the minimum FQBN required to get the same debug configuration.
// (i.e. the FQBN cleaned up of the options that do not affect the debugger configuration)
minimumFQBN := cores.MustParseFQBN(req.GetFqbn())
for _, config := range minimumFQBN.Configs.Keys() {
checkFQBN := minimumFQBN.Clone()
checkFQBN.Configs.Remove(config)
configRequest.Fqbn = checkFQBN.String()
checkOutput, err := getDebugProperties(configRequest, pme, true)
if err == nil && reflect.DeepEqual(expectedOutput, checkOutput) {
minimumFQBN.Configs.Remove(config)
}
}
return &rpc.IsDebugSupportedResponse{
DebuggingSupported: true,
DebugFqbn: minimumFQBN.String(),
}, nil
}
func getDebugProperties(req *rpc.GetDebugConfigRequest, pme *packagemanager.Explorer, skipSketchChecks bool) (*rpc.GetDebugConfigResponse, error) {
var (
sketchName string
sketchDefaultFQBN string
sketchDefaultBuildPath *paths.Path
)
if !skipSketchChecks {
// TODO: make a generic function to extract sketch from request
// and remove duplication in commands/compile.go
if req.GetSketchPath() == "" {
return nil, &arduino.MissingSketchPathError{}
}
sketchPath := paths.New(req.GetSketchPath())
sk, err := sketch.New(sketchPath)
if err != nil {
return nil, &arduino.CantOpenSketchError{Cause: err}
}
sketchName = sk.Name
sketchDefaultFQBN = sk.GetDefaultFQBN()
sketchDefaultBuildPath = sk.DefaultBuildPath()
} else {
// Use placeholder sketch data
sketchName = "Sketch"
sketchDefaultFQBN = ""
sketchDefaultBuildPath = paths.New("SketchBuildPath")
} }
// XXX Remove this code duplication!! // XXX Remove this code duplication!!
fqbnIn := req.GetFqbn() fqbnIn := req.GetFqbn()
if fqbnIn == "" && sk != nil { if fqbnIn == "" {
fqbnIn = sk.GetDefaultFQBN() fqbnIn = sketchDefaultFQBN
} }
if fqbnIn == "" { if fqbnIn == "" {
return nil, &arduino.MissingFQBNError{} return nil, &arduino.MissingFQBNError{}
...@@ -109,16 +169,18 @@ func getDebugProperties(req *rpc.GetDebugConfigRequest, pme *packagemanager.Expl ...@@ -109,16 +169,18 @@ func getDebugProperties(req *rpc.GetDebugConfigRequest, pme *packagemanager.Expl
if importDir := req.GetImportDir(); importDir != "" { if importDir := req.GetImportDir(); importDir != "" {
importPath = paths.New(importDir) importPath = paths.New(importDir)
} else { } else {
importPath = sk.DefaultBuildPath() importPath = sketchDefaultBuildPath
}
if !importPath.Exist() {
return nil, &arduino.NotFoundError{Message: tr("Compiled sketch not found in %s", importPath)}
} }
if !importPath.IsDir() { if !skipSketchChecks {
return nil, &arduino.NotFoundError{Message: tr("Expected compiled sketch in directory %s, but is a file instead", importPath)} if !importPath.Exist() {
return nil, &arduino.NotFoundError{Message: tr("Compiled sketch not found in %s", importPath)}
}
if !importPath.IsDir() {
return nil, &arduino.NotFoundError{Message: tr("Expected compiled sketch in directory %s, but is a file instead", importPath)}
}
} }
toolProperties.SetPath("build.path", importPath) toolProperties.SetPath("build.path", importPath)
toolProperties.Set("build.project_name", sk.Name+".ino") toolProperties.Set("build.project_name", sketchName+".ino")
// Set debug port property // Set debug port property
port := req.GetPort() port := req.GetPort()
......
...@@ -36,27 +36,31 @@ import ( ...@@ -36,27 +36,31 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
var ( var tr = i18n.Tr
fqbnArg arguments.Fqbn
portArgs arguments.Port
interpreter string
importDir string
printInfo bool
programmer arguments.Programmer
tr = i18n.Tr
)
// NewCommand created a new `upload` command // NewCommand created a new `upload` command
func NewCommand() *cobra.Command { func NewCommand() *cobra.Command {
var (
fqbnArg arguments.Fqbn
portArgs arguments.Port
interpreter string
importDir string
printInfo bool
programmer arguments.Programmer
)
debugCommand := &cobra.Command{ debugCommand := &cobra.Command{
Use: "debug", Use: "debug",
Short: tr("Debug Arduino sketches."), Short: tr("Debug Arduino sketches."),
Long: tr("Debug Arduino sketches. (this command opens an interactive gdb session)"), Long: tr("Debug Arduino sketches. (this command opens an interactive gdb session)"),
Example: " " + os.Args[0] + " debug -b arduino:samd:mkr1000 -P atmel_ice /home/user/Arduino/MySketch", Example: " " + os.Args[0] + " debug -b arduino:samd:mkr1000 -P atmel_ice /home/user/Arduino/MySketch",
Args: cobra.MaximumNArgs(1), Args: cobra.MaximumNArgs(1),
Run: runDebugCommand, Run: func(cmd *cobra.Command, args []string) {
runDebugCommand(args, &portArgs, &fqbnArg, interpreter, importDir, &programmer, printInfo)
},
} }
debugCommand.AddCommand(newDebugCheckCommand())
fqbnArg.AddToCommand(debugCommand) fqbnArg.AddToCommand(debugCommand)
portArgs.AddToCommand(debugCommand) portArgs.AddToCommand(debugCommand)
programmer.AddToCommand(debugCommand) programmer.AddToCommand(debugCommand)
...@@ -67,7 +71,8 @@ func NewCommand() *cobra.Command { ...@@ -67,7 +71,8 @@ func NewCommand() *cobra.Command {
return debugCommand return debugCommand
} }
func runDebugCommand(command *cobra.Command, args []string) { func runDebugCommand(args []string, portArgs *arguments.Port, fqbnArg *arguments.Fqbn,
interpreter string, importDir string, programmer *arguments.Programmer, printInfo bool) {
instance := instance.CreateAndInit() instance := instance.CreateAndInit()
logrus.Info("Executing `arduino-cli debug`") logrus.Info("Executing `arduino-cli debug`")
...@@ -81,7 +86,7 @@ func runDebugCommand(command *cobra.Command, args []string) { ...@@ -81,7 +86,7 @@ func runDebugCommand(command *cobra.Command, args []string) {
if err != nil { if err != nil {
feedback.FatalError(err, feedback.ErrGeneric) feedback.FatalError(err, feedback.ErrGeneric)
} }
fqbn, port := arguments.CalculateFQBNAndPort(&portArgs, &fqbnArg, instance, sk.GetDefaultFqbn(), sk.GetDefaultPort(), sk.GetDefaultProtocol()) fqbn, port := arguments.CalculateFQBNAndPort(portArgs, fqbnArg, instance, sk.GetDefaultFqbn(), sk.GetDefaultPort(), sk.GetDefaultProtocol())
debugConfigRequested := &rpc.GetDebugConfigRequest{ debugConfigRequested := &rpc.GetDebugConfigRequest{
Instance: instance, Instance: instance,
Fqbn: fqbn, Fqbn: fqbn,
......
// This file is part of arduino-cli.
//
// Copyright 2023 ARDUINO SA (http://www.arduino.cc/)
//
// This software is released under the GNU General Public License version 3,
// which covers the main part of arduino-cli.
// The terms of this license can be found at:
// https://www.gnu.org/licenses/gpl-3.0.en.html
//
// You can be released from the requirements of the above licenses by purchasing
// a commercial license. Buying such a license is mandatory if you want to
// modify or otherwise use the software for commercial activities involving the
// Arduino software without disclosing the source code of your own applications.
// To purchase a commercial license, send an email to license@arduino.cc.
package debug
import (
"context"
"os"
"github.com/arduino/arduino-cli/commands/debug"
"github.com/arduino/arduino-cli/internal/cli/arguments"
"github.com/arduino/arduino-cli/internal/cli/feedback"
"github.com/arduino/arduino-cli/internal/cli/feedback/result"
"github.com/arduino/arduino-cli/internal/cli/instance"
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
func newDebugCheckCommand() *cobra.Command {
var (
fqbnArg arguments.Fqbn
portArgs arguments.Port
interpreter string
programmer arguments.Programmer
)
debugCheckCommand := &cobra.Command{
Use: "check",
Short: tr("Check if the given board/programmer combination supports debugging."),
Example: " " + os.Args[0] + " debug check -b arduino:samd:mkr1000 -P atmel_ice",
Run: func(cmd *cobra.Command, args []string) {
runDebugCheckCommand(&portArgs, &fqbnArg, interpreter, &programmer)
},
}
fqbnArg.AddToCommand(debugCheckCommand)
portArgs.AddToCommand(debugCheckCommand)
programmer.AddToCommand(debugCheckCommand)
debugCheckCommand.Flags().StringVar(&interpreter, "interpreter", "console", tr("Debug interpreter e.g.: %s", "console, mi, mi1, mi2, mi3"))
return debugCheckCommand
}
func runDebugCheckCommand(portArgs *arguments.Port, fqbnArg *arguments.Fqbn, interpreter string, programmerArg *arguments.Programmer) {
instance := instance.CreateAndInit()
logrus.Info("Executing `arduino-cli debug`")
port, err := portArgs.GetPort(instance, "", "")
if err != nil {
feedback.FatalError(err, feedback.ErrBadArgument)
}
fqbn := fqbnArg.String()
resp, err := debug.IsDebugSupported(context.Background(), &rpc.IsDebugSupportedRequest{
Instance: instance,
Fqbn: fqbn,
Port: port,
Interpreter: interpreter,
Programmer: programmerArg.String(instance, fqbn),
})
if err != nil {
feedback.FatalError(err, feedback.ErrGeneric)
}
feedback.PrintResult(&debugCheckResult{result.NewIsDebugSupportedResponse(resp)})
}
type debugCheckResult struct {
Result *result.IsDebugSupportedResponse
}
func (d *debugCheckResult) Data() interface{} {
return d.Result
}
func (d *debugCheckResult) String() string {
if d.Result.DebuggingSupported {
return tr("The given board/programmer configuration supports debugging.")
}
return tr("The given board/programmer configuration does NOT support debugging.")
}
...@@ -1057,3 +1057,15 @@ func NewCompileDiagnosticNote(cdn *rpc.CompileDiagnosticNote) *CompileDiagnostic ...@@ -1057,3 +1057,15 @@ func NewCompileDiagnosticNote(cdn *rpc.CompileDiagnosticNote) *CompileDiagnostic
Column: cdn.GetColumn(), Column: cdn.GetColumn(),
} }
} }
type IsDebugSupportedResponse struct {
DebuggingSupported bool `json:"debugging_supported"`
DebugFQBN string `json:"debug_fqbn,omitempty"`
}
func NewIsDebugSupportedResponse(resp *rpc.IsDebugSupportedResponse) *IsDebugSupportedResponse {
return &IsDebugSupportedResponse{
DebuggingSupported: resp.GetDebuggingSupported(),
DebugFQBN: resp.GetDebugFqbn(),
}
}
...@@ -217,6 +217,10 @@ func TestAllFieldAreMapped(t *testing.T) { ...@@ -217,6 +217,10 @@ func TestAllFieldAreMapped(t *testing.T) {
compileDiagnosticNoteRpc := &rpc.CompileDiagnosticNote{} compileDiagnosticNoteRpc := &rpc.CompileDiagnosticNote{}
compileDiagnosticNoteResult := result.NewCompileDiagnosticNote(compileDiagnosticNoteRpc) compileDiagnosticNoteResult := result.NewCompileDiagnosticNote(compileDiagnosticNoteRpc)
mustContainsAllPropertyOfRpcStruct(t, compileDiagnosticNoteRpc, compileDiagnosticNoteResult) mustContainsAllPropertyOfRpcStruct(t, compileDiagnosticNoteRpc, compileDiagnosticNoteResult)
isDebugSupportedResponseRpc := &rpc.IsDebugSupportedResponse{}
isDebugSupportedResponseResult := result.NewIsDebugSupportedResponse(isDebugSupportedResponseRpc)
mustContainsAllPropertyOfRpcStruct(t, isDebugSupportedResponseRpc, isDebugSupportedResponseResult)
} }
func TestEnumsMapsEveryRpcCounterpart(t *testing.T) { func TestEnumsMapsEveryRpcCounterpart(t *testing.T) {
......
...@@ -33,13 +33,22 @@ func TestDebug(t *testing.T) { ...@@ -33,13 +33,22 @@ func TestDebug(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// Install cores // Install cores
_, _, err = cli.Run("core", "install", "arduino:avr")
require.NoError(t, err)
_, _, err = cli.Run("core", "install", "arduino:samd") _, _, err = cli.Run("core", "install", "arduino:samd")
require.NoError(t, err) require.NoError(t, err)
// Install custom core
customHw, err := paths.New("testdata", "hardware").Abs()
require.NoError(t, err)
err = customHw.CopyDirTo(cli.SketchbookDir().Join("hardware"))
require.NoError(t, err)
integrationtest.CLISubtests{ integrationtest.CLISubtests{
{"Start", testDebuggerStarts}, {"Start", testDebuggerStarts},
{"WithPdeSketchStarts", testDebuggerWithPdeSketchStarts}, {"WithPdeSketchStarts", testDebuggerWithPdeSketchStarts},
{"DebugInformation", testAllDebugInformation}, {"DebugInformation", testAllDebugInformation},
{"DebugCheck", testDebugCheck},
}.Run(t, env, cli) }.Run(t, env, cli)
} }
...@@ -99,12 +108,6 @@ func testAllDebugInformation(t *testing.T, env *integrationtest.Environment, cli ...@@ -99,12 +108,6 @@ func testAllDebugInformation(t *testing.T, env *integrationtest.Environment, cli
_, _, err := cli.Run("sketch", "new", sketchPath.String()) _, _, err := cli.Run("sketch", "new", sketchPath.String())
require.NoError(t, err) require.NoError(t, err)
// Install custom core
customHw, err := paths.New("testdata", "hardware").Abs()
require.NoError(t, err)
err = customHw.CopyDirTo(cli.SketchbookDir().Join("hardware"))
require.NoError(t, err)
// Build sketch // Build sketch
_, _, err = cli.Run("compile", "-b", "my:samd:my", sketchPath.String(), "--format", "json") _, _, err = cli.Run("compile", "-b", "my:samd:my", sketchPath.String(), "--format", "json")
require.NoError(t, err) require.NoError(t, err)
...@@ -331,3 +334,45 @@ func testAllDebugInformation(t *testing.T, env *integrationtest.Environment, cli ...@@ -331,3 +334,45 @@ func testAllDebugInformation(t *testing.T, env *integrationtest.Environment, cli
} }
} }
} }
func testDebugCheck(t *testing.T, env *integrationtest.Environment, cli *integrationtest.ArduinoCLI) {
_, _, err := cli.Run("debug", "check", "-b", "arduino:samd:mkr1000")
require.Error(t, err)
out, _, err := cli.Run("debug", "check", "-b", "arduino:samd:mkr1000", "-P", "atmel_ice")
require.NoError(t, err)
require.Contains(t, string(out), "The given board/programmer configuration supports debugging.")
out, _, err = cli.Run("debug", "check", "-b", "arduino:samd:mkr1000", "-P", "atmel_ice", "--format", "json")
require.NoError(t, err)
requirejson.Query(t, out, `.debugging_supported`, `true`)
out, _, err = cli.Run("debug", "check", "-b", "arduino:avr:uno", "-P", "atmel_ice")
require.NoError(t, err)
require.Contains(t, string(out), "The given board/programmer configuration does NOT support debugging.")
out, _, err = cli.Run("debug", "check", "-b", "arduino:avr:uno", "-P", "atmel_ice", "--format", "json")
require.NoError(t, err)
requirejson.Query(t, out, `.debugging_supported`, `false`)
// Test minimum FQBN compute
out, _, err = cli.Run("debug", "check", "-b", "my:samd:my5", "-P", "atmel_ice", "--format", "json")
require.NoError(t, err)
requirejson.Contains(t, out, `{ "debugging_supported" : false }`)
out, _, err = cli.Run("debug", "check", "-b", "my:samd:my5:dbg=on", "-P", "atmel_ice", "--format", "json")
require.NoError(t, err)
requirejson.Contains(t, out, `{ "debugging_supported" : true, "debug_fqbn" : "my:samd:my5:dbg=on" }`)
out, _, err = cli.Run("debug", "check", "-b", "my:samd:my5:dbg=on,cpu=150m", "-P", "atmel_ice", "--format", "json")
require.NoError(t, err)
requirejson.Contains(t, out, `{ "debugging_supported" : true, "debug_fqbn" : "my:samd:my5:dbg=on" }`)
out, _, err = cli.Run("debug", "check", "-b", "my:samd:my6", "-P", "atmel_ice", "--format", "json")
require.NoError(t, err)
requirejson.Contains(t, out, `{ "debugging_supported" : true, "debug_fqbn" : "my:samd:my6" }`)
out, _, err = cli.Run("debug", "check", "-b", "my:samd:my6:dbg=on", "-P", "atmel_ice", "--format", "json")
require.NoError(t, err)
requirejson.Contains(t, out, `{ "debugging_supported" : true, "debug_fqbn" : "my:samd:my6" }`)
}
...@@ -112,3 +112,39 @@ my4.build.mcu=test2 ...@@ -112,3 +112,39 @@ my4.build.mcu=test2
# this one will be overwritten by additional_config # this one will be overwritten by additional_config
my4.debug.svd_file=svd-file my4.debug.svd_file=svd-file
my4.debug.additional_config=build.debug.config.{build.mcu} my4.debug.additional_config=build.debug.config.{build.mcu}
# menu options for the following boards
menu.dbg=Debugger
menu.cpu=CPU Speed
# This does not support debug by default but only after selecting a menu option
my5.name=5th Board
my5.build.core=arduino:arduino
my5.build.variant=arduino:mkr1000
my5.debug.toolchain.path=gcc-path
my5.debug.toolchain.prefix=gcc-prefix
my5.debug.server.openocd.path=openocd-path
my5.debug.server.openocd.scripts_dir=openocd-scripts-dir
my5.debug.server.openocd.script=single-script
my5.debug.executable=
my5.menu.dbg.off=Debug Disabled
my5.menu.dbg.on=Debug Enabled
my5.menu.dbg.on.debug.executable=YES
my5.menu.cpu.100m=100Mhz
my5.menu.cpu.150m=150Mhz
# this one has debugger enabled by default
my6.name=5th Board
my6.build.core=arduino:arduino
my6.build.variant=arduino:mkr1000
my6.debug.toolchain.path=gcc-path
my6.debug.toolchain.prefix=gcc-prefix
my6.debug.server.openocd.path=openocd-path
my6.debug.server.openocd.scripts_dir=openocd-scripts-dir
my6.debug.server.openocd.script=single-script
my6.debug.executable=
my6.menu.dbg.on=Debug Enabled
my6.menu.dbg.on.debug.executable=YES
my6.menu.dbg.off=Debug Disabled
my6.menu.cpu.100m=100Mhz
my6.menu.cpu.150m=150Mhz
\ No newline at end of file
...@@ -182,6 +182,11 @@ service ArduinoCoreService { ...@@ -182,6 +182,11 @@ service ArduinoCoreService {
// Start a debug session and communicate with the debugger tool. // Start a debug session and communicate with the debugger tool.
rpc Debug(stream DebugRequest) returns (stream DebugResponse) {} rpc Debug(stream DebugRequest) returns (stream DebugResponse) {}
// Determine if debugging is suported given a specific configuration.
rpc IsDebugSupported(IsDebugSupportedRequest)
returns (IsDebugSupportedResponse) {}
// Query the debugger information given a specific configuration.
rpc GetDebugConfig(GetDebugConfigRequest) returns (GetDebugConfigResponse) {} rpc GetDebugConfig(GetDebugConfigRequest) returns (GetDebugConfigResponse) {}
// List all the settings. // List all the settings.
......
...@@ -73,6 +73,7 @@ const ( ...@@ -73,6 +73,7 @@ const (
ArduinoCoreService_Monitor_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/Monitor" ArduinoCoreService_Monitor_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/Monitor"
ArduinoCoreService_EnumerateMonitorPortSettings_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/EnumerateMonitorPortSettings" ArduinoCoreService_EnumerateMonitorPortSettings_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/EnumerateMonitorPortSettings"
ArduinoCoreService_Debug_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/Debug" ArduinoCoreService_Debug_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/Debug"
ArduinoCoreService_IsDebugSupported_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/IsDebugSupported"
ArduinoCoreService_GetDebugConfig_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/GetDebugConfig" ArduinoCoreService_GetDebugConfig_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/GetDebugConfig"
ArduinoCoreService_SettingsGetAll_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/SettingsGetAll" ArduinoCoreService_SettingsGetAll_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/SettingsGetAll"
ArduinoCoreService_SettingsMerge_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/SettingsMerge" ArduinoCoreService_SettingsMerge_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/SettingsMerge"
...@@ -172,6 +173,9 @@ type ArduinoCoreServiceClient interface { ...@@ -172,6 +173,9 @@ type ArduinoCoreServiceClient interface {
EnumerateMonitorPortSettings(ctx context.Context, in *EnumerateMonitorPortSettingsRequest, opts ...grpc.CallOption) (*EnumerateMonitorPortSettingsResponse, error) EnumerateMonitorPortSettings(ctx context.Context, in *EnumerateMonitorPortSettingsRequest, opts ...grpc.CallOption) (*EnumerateMonitorPortSettingsResponse, error)
// Start a debug session and communicate with the debugger tool. // Start a debug session and communicate with the debugger tool.
Debug(ctx context.Context, opts ...grpc.CallOption) (ArduinoCoreService_DebugClient, error) Debug(ctx context.Context, opts ...grpc.CallOption) (ArduinoCoreService_DebugClient, error)
// Determine if debugging is suported given a specific configuration.
IsDebugSupported(ctx context.Context, in *IsDebugSupportedRequest, opts ...grpc.CallOption) (*IsDebugSupportedResponse, error)
// Query the debugger information given a specific configuration.
GetDebugConfig(ctx context.Context, in *GetDebugConfigRequest, opts ...grpc.CallOption) (*GetDebugConfigResponse, error) GetDebugConfig(ctx context.Context, in *GetDebugConfigRequest, opts ...grpc.CallOption) (*GetDebugConfigResponse, error)
// List all the settings. // List all the settings.
SettingsGetAll(ctx context.Context, in *SettingsGetAllRequest, opts ...grpc.CallOption) (*SettingsGetAllResponse, error) SettingsGetAll(ctx context.Context, in *SettingsGetAllRequest, opts ...grpc.CallOption) (*SettingsGetAllResponse, error)
...@@ -1027,6 +1031,15 @@ func (x *arduinoCoreServiceDebugClient) Recv() (*DebugResponse, error) { ...@@ -1027,6 +1031,15 @@ func (x *arduinoCoreServiceDebugClient) Recv() (*DebugResponse, error) {
return m, nil return m, nil
} }
func (c *arduinoCoreServiceClient) IsDebugSupported(ctx context.Context, in *IsDebugSupportedRequest, opts ...grpc.CallOption) (*IsDebugSupportedResponse, error) {
out := new(IsDebugSupportedResponse)
err := c.cc.Invoke(ctx, ArduinoCoreService_IsDebugSupported_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *arduinoCoreServiceClient) GetDebugConfig(ctx context.Context, in *GetDebugConfigRequest, opts ...grpc.CallOption) (*GetDebugConfigResponse, error) { func (c *arduinoCoreServiceClient) GetDebugConfig(ctx context.Context, in *GetDebugConfigRequest, opts ...grpc.CallOption) (*GetDebugConfigResponse, error) {
out := new(GetDebugConfigResponse) out := new(GetDebugConfigResponse)
err := c.cc.Invoke(ctx, ArduinoCoreService_GetDebugConfig_FullMethodName, in, out, opts...) err := c.cc.Invoke(ctx, ArduinoCoreService_GetDebugConfig_FullMethodName, in, out, opts...)
...@@ -1180,6 +1193,9 @@ type ArduinoCoreServiceServer interface { ...@@ -1180,6 +1193,9 @@ type ArduinoCoreServiceServer interface {
EnumerateMonitorPortSettings(context.Context, *EnumerateMonitorPortSettingsRequest) (*EnumerateMonitorPortSettingsResponse, error) EnumerateMonitorPortSettings(context.Context, *EnumerateMonitorPortSettingsRequest) (*EnumerateMonitorPortSettingsResponse, error)
// Start a debug session and communicate with the debugger tool. // Start a debug session and communicate with the debugger tool.
Debug(ArduinoCoreService_DebugServer) error Debug(ArduinoCoreService_DebugServer) error
// Determine if debugging is suported given a specific configuration.
IsDebugSupported(context.Context, *IsDebugSupportedRequest) (*IsDebugSupportedResponse, error)
// Query the debugger information given a specific configuration.
GetDebugConfig(context.Context, *GetDebugConfigRequest) (*GetDebugConfigResponse, error) GetDebugConfig(context.Context, *GetDebugConfigRequest) (*GetDebugConfigResponse, error)
// List all the settings. // List all the settings.
SettingsGetAll(context.Context, *SettingsGetAllRequest) (*SettingsGetAllResponse, error) SettingsGetAll(context.Context, *SettingsGetAllRequest) (*SettingsGetAllResponse, error)
...@@ -1317,6 +1333,9 @@ func (UnimplementedArduinoCoreServiceServer) EnumerateMonitorPortSettings(contex ...@@ -1317,6 +1333,9 @@ func (UnimplementedArduinoCoreServiceServer) EnumerateMonitorPortSettings(contex
func (UnimplementedArduinoCoreServiceServer) Debug(ArduinoCoreService_DebugServer) error { func (UnimplementedArduinoCoreServiceServer) Debug(ArduinoCoreService_DebugServer) error {
return status.Errorf(codes.Unimplemented, "method Debug not implemented") return status.Errorf(codes.Unimplemented, "method Debug not implemented")
} }
func (UnimplementedArduinoCoreServiceServer) IsDebugSupported(context.Context, *IsDebugSupportedRequest) (*IsDebugSupportedResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method IsDebugSupported not implemented")
}
func (UnimplementedArduinoCoreServiceServer) GetDebugConfig(context.Context, *GetDebugConfigRequest) (*GetDebugConfigResponse, error) { func (UnimplementedArduinoCoreServiceServer) GetDebugConfig(context.Context, *GetDebugConfigRequest) (*GetDebugConfigResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetDebugConfig not implemented") return nil, status.Errorf(codes.Unimplemented, "method GetDebugConfig not implemented")
} }
...@@ -2126,6 +2145,24 @@ func (x *arduinoCoreServiceDebugServer) Recv() (*DebugRequest, error) { ...@@ -2126,6 +2145,24 @@ func (x *arduinoCoreServiceDebugServer) Recv() (*DebugRequest, error) {
return m, nil return m, nil
} }
func _ArduinoCoreService_IsDebugSupported_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(IsDebugSupportedRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ArduinoCoreServiceServer).IsDebugSupported(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ArduinoCoreService_IsDebugSupported_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ArduinoCoreServiceServer).IsDebugSupported(ctx, req.(*IsDebugSupportedRequest))
}
return interceptor(ctx, in, info, handler)
}
func _ArduinoCoreService_GetDebugConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { func _ArduinoCoreService_GetDebugConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetDebugConfigRequest) in := new(GetDebugConfigRequest)
if err := dec(in); err != nil { if err := dec(in); err != nil {
...@@ -2331,6 +2368,10 @@ var ArduinoCoreService_ServiceDesc = grpc.ServiceDesc{ ...@@ -2331,6 +2368,10 @@ var ArduinoCoreService_ServiceDesc = grpc.ServiceDesc{
MethodName: "EnumerateMonitorPortSettings", MethodName: "EnumerateMonitorPortSettings",
Handler: _ArduinoCoreService_EnumerateMonitorPortSettings_Handler, Handler: _ArduinoCoreService_EnumerateMonitorPortSettings_Handler,
}, },
{
MethodName: "IsDebugSupported",
Handler: _ArduinoCoreService_IsDebugSupported_Handler,
},
{ {
MethodName: "GetDebugConfig", MethodName: "GetDebugConfig",
Handler: _ArduinoCoreService_GetDebugConfig_Handler, Handler: _ArduinoCoreService_GetDebugConfig_Handler,
......
This diff is collapsed.
...@@ -43,6 +43,39 @@ message DebugRequest { ...@@ -43,6 +43,39 @@ message DebugRequest {
bool send_interrupt = 3; bool send_interrupt = 3;
} }
// The streaming response may contain chunks of data from the debugger or an
// error.
message DebugResponse {
// Incoming data from the debugger tool.
bytes data = 1;
// Incoming error output from the debugger tool.
string error = 2;
}
message IsDebugSupportedRequest {
// Arduino Core Service instance from the `Init` response.
Instance instance = 1;
// Fully qualified board name of the board in use (e.g.,
// `arduino:samd:mkr1000`).
string fqbn = 2;
// Port of the debugger (optional).
Port port = 3;
// Which GDB command interpreter to use.
string interpreter = 4;
// The programmer to use for debugging.
string programmer = 5;
}
message IsDebugSupportedResponse {
// True if debugging is supported
bool debugging_supported = 1;
// This is the same FQBN given in the IsDebugSupportedRequest but cleaned
// up of the board options that do not affect the debugger configuration.
// It may be used by clients/IDE to group slightly different boards option
// selections under the same debug configuration.
string debug_fqbn = 2;
}
message GetDebugConfigRequest { message GetDebugConfigRequest {
// Arduino Core Service instance from the `Init` response. // Arduino Core Service instance from the `Init` response.
Instance instance = 1; Instance instance = 1;
...@@ -65,14 +98,6 @@ message GetDebugConfigRequest { ...@@ -65,14 +98,6 @@ message GetDebugConfigRequest {
string programmer = 9; string programmer = 9;
} }
//
message DebugResponse {
// Incoming data from the debugger tool.
bytes data = 1;
// Incoming error output from the debugger tool.
string error = 2;
}
message GetDebugConfigResponse { message GetDebugConfigResponse {
// The executable binary to debug // The executable binary to debug
string executable = 1; string executable = 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment