Skip to content

Commit 439b64b

Browse files
author
rsora
committed
Extract recipe creation from debug command
1 parent 19c3235 commit 439b64b

File tree

1 file changed

+58
-57
lines changed

1 file changed

+58
-57
lines changed

commands/debug/debug.go

Lines changed: 58 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,62 @@ import (
3535
dbg "github.com/arduino/arduino-cli/rpc/debug"
3636
)
3737

38-
// Debug FIXMEDOC
38+
// Debug command launches a debug tool for a sketch.
39+
// It also implements streams routing:
40+
// gRPC In -> tool stdIn
41+
// grpc Out <- tool stdOut
42+
// grpc Out <- tool stdErr
43+
// It also implements tool process lifecycle management
3944
func Debug(ctx context.Context, req *dbg.DebugConfigReq, inStream io.Reader, out io.Writer) (*dbg.DebugResp, error) {
4045

46+
// get tool commandLine from core recipe
47+
commandLine, err := getCommandLine(req)
48+
if err != nil {
49+
return nil, fmt.Errorf("cannot get command line for tool: %s", err)
50+
}
51+
52+
// Run Tool
53+
cmd, err := executils.Command(commandLine)
54+
if err != nil {
55+
return nil, fmt.Errorf("cannot execute debug tool: %s", err)
56+
}
57+
58+
// Get stdIn pipe from tool
59+
in, err := cmd.StdinPipe()
60+
if err != nil {
61+
fmt.Printf("%v\n", err)
62+
return &dbg.DebugResp{Error: err.Error()}, nil
63+
}
64+
defer in.Close()
65+
66+
// Merge tool StdOut and StdErr to stream them in the io.Writer passed stream
67+
cmd.Stdout = out
68+
cmd.Stderr = out
69+
70+
// Start the debug command
71+
if err := cmd.Start(); err != nil {
72+
fmt.Printf("%v\n", err)
73+
return &dbg.DebugResp{Error: err.Error()}, nil
74+
}
75+
76+
go func() {
77+
// copy data from passed inStream into command stdIn
78+
io.Copy(in, inStream)
79+
// In any case, try process termination after a second to avoid leaving
80+
// zombie process.
81+
time.Sleep(time.Second)
82+
cmd.Process.Kill()
83+
}()
84+
85+
// Wait for process to finish
86+
if err := cmd.Wait(); err != nil {
87+
return &dbg.DebugResp{Error: err.Error()}, nil
88+
}
89+
return &dbg.DebugResp{}, nil
90+
}
91+
92+
// getCommandLine compose a debug command represented by a core recipe
93+
func getCommandLine(req *dbg.DebugConfigReq) ([]string, error) {
4194
// TODO: make a generic function to extract sketch from request
4295
// and remove duplication in commands/compile.go
4396
if req.GetSketchPath() == "" {
@@ -52,7 +105,7 @@ func Debug(ctx context.Context, req *dbg.DebugConfigReq, inStream io.Reader, out
52105
// FIXME: make a specification on how a port is specified via command line
53106
port := req.GetPort()
54107
if port == "" {
55-
return nil, fmt.Errorf("no upload port provided")
108+
return nil, fmt.Errorf("no debug port provided")
56109
}
57110

58111
fqbnIn := req.GetFqbn()
@@ -98,7 +151,7 @@ func Debug(ctx context.Context, req *dbg.DebugConfigReq, inStream io.Reader, out
98151
}
99152
}
100153

101-
// Build configuration for upload
154+
// Build configuration for debug
102155
toolProperties := properties.NewMap()
103156
if referencedPlatformRelease != nil {
104157
toolProperties.Merge(referencedPlatformRelease.Properties)
@@ -109,26 +162,13 @@ func Debug(ctx context.Context, req *dbg.DebugConfigReq, inStream io.Reader, out
109162

110163
requestedToolProperties := toolProperties.SubTree("tools." + toolName)
111164
toolProperties.Merge(requestedToolProperties)
112-
113165
if requiredTools, err := pm.FindToolsRequiredForBoard(board); err == nil {
114166
for _, requiredTool := range requiredTools {
115-
logrus.WithField("tool", requiredTool).Info("Tool required for upload")
167+
logrus.WithField("tool", requiredTool).Info("Tool required for debug")
116168
toolProperties.Merge(requiredTool.RuntimeProperties())
117169
}
118170
}
119171

120-
// Set properties for verbose upload
121-
verbose := req.GetVerbose()
122-
if verbose {
123-
if v, ok := toolProperties.GetOk("debug.params.verbose"); ok {
124-
toolProperties.Set("debug.verbose", v)
125-
}
126-
} else {
127-
if v, ok := toolProperties.GetOk("debug.params.quiet"); ok {
128-
toolProperties.Set("debug.verbose", v)
129-
}
130-
}
131-
132172
// Set path to compiled binary
133173
// Make the filename without the FQBN configs part
134174
fqbn.Configs = properties.NewMap()
@@ -179,44 +219,5 @@ func Debug(ctx context.Context, req *dbg.DebugConfigReq, inStream io.Reader, out
179219
if err != nil {
180220
return nil, fmt.Errorf("invalid recipe '%s': %s", recipe, err)
181221
}
182-
183-
// for _, arg := range cmdArgs {
184-
// fmt.Println(">>", arg)
185-
// }
186-
// time.Sleep(time.Hour)
187-
188-
// Run Tool
189-
cmd, err := executils.Command(cmdArgs)
190-
if err != nil {
191-
return nil, fmt.Errorf("cannot execute upload tool: %s", err)
192-
}
193-
194-
in, err := cmd.StdinPipe()
195-
if err != nil {
196-
fmt.Printf("%v\n", err)
197-
return &dbg.DebugResp{Error: err.Error()}, nil
198-
}
199-
defer in.Close()
200-
201-
cmd.Stdout = out
202-
cmd.Stderr = out
203-
204-
if err := cmd.Start(); err != nil {
205-
fmt.Printf("%v\n", err)
206-
return &dbg.DebugResp{Error: err.Error()}, nil
207-
}
208-
209-
// now we can read the other commands and re-route to the Debug Client...
210-
go func() {
211-
io.Copy(in, inStream)
212-
// In any case, try process termination after a second to avoid leaving
213-
// zombie process.
214-
time.Sleep(time.Second)
215-
cmd.Process.Kill()
216-
}()
217-
218-
if err := cmd.Wait(); err != nil {
219-
return &dbg.DebugResp{Error: err.Error()}, nil
220-
}
221-
return &dbg.DebugResp{}, nil
222+
return cmdArgs, nil
222223
}

0 commit comments

Comments
 (0)