@@ -196,8 +196,8 @@ func (d *devcontainerCLI) Up(ctx context.Context, workspaceFolder, configPath st
196
196
cmd .Stderr = io .MultiWriter (stderrWriters ... )
197
197
198
198
if err := cmd .Run ();err != nil {
199
- var result devcontainerCLIResult
200
- if err2 := parseDevcontainerCLILastLine ( ctx , logger , stdoutBuf . Bytes (), & result ); err2 != nil {
199
+ result , err2 := parseDevcontainerCLILastLine [ devcontainerCLIResult ]( ctx , logger , stdoutBuf . Bytes ())
200
+ if err2 != nil {
201
201
err = errors .Join (err ,err2 )
202
202
}
203
203
if err2 := result .Err ();err2 != nil {
@@ -206,8 +206,8 @@ func (d *devcontainerCLI) Up(ctx context.Context, workspaceFolder, configPath st
206
206
return "" ,err
207
207
}
208
208
209
- var result devcontainerCLIResult
210
- if err := parseDevcontainerCLILastLine ( ctx , logger , stdoutBuf . Bytes (), & result ); err != nil {
209
+ result , err := parseDevcontainerCLILastLine [ devcontainerCLIResult ]( ctx , logger , stdoutBuf . Bytes ())
210
+ if err != nil {
211
211
return "" ,err
212
212
}
213
213
if err := result .Err ();err != nil {
@@ -286,8 +286,8 @@ func (d *devcontainerCLI) ReadConfig(ctx context.Context, workspaceFolder, confi
286
286
return DevcontainerConfig {},xerrors .Errorf ("devcontainer read-configuration failed: %w" ,err )
287
287
}
288
288
289
- var config DevcontainerConfig
290
- if err := parseDevcontainerCLILastLine ( ctx , logger , stdoutBuf . Bytes (), & config ); err != nil {
289
+ config , err := parseDevcontainerCLILastLine [ DevcontainerConfig ]( ctx , logger , stdoutBuf . Bytes ())
290
+ if err != nil {
291
291
return DevcontainerConfig {},err
292
292
}
293
293
@@ -296,7 +296,9 @@ func (d *devcontainerCLI) ReadConfig(ctx context.Context, workspaceFolder, confi
296
296
297
297
// parseDevcontainerCLILastLine parses the last line of the devcontainer CLI output
298
298
// which is a JSON object.
299
- func parseDevcontainerCLILastLine [T any ](ctx context.Context ,logger slog.Logger ,p []byte ,result T )error {
299
+ func parseDevcontainerCLILastLine [T any ](ctx context.Context ,logger slog.Logger ,p []byte ) (T ,error ) {
300
+ var result T
301
+
300
302
s := bufio .NewScanner (bytes .NewReader (p ))
301
303
var lastLine []byte
302
304
for s .Scan () {
@@ -307,18 +309,18 @@ func parseDevcontainerCLILastLine[T any](ctx context.Context, logger slog.Logger
307
309
lastLine = b
308
310
}
309
311
if err := s .Err ();err != nil {
310
- return err
312
+ return result , err
311
313
}
312
314
if len (lastLine )== 0 || lastLine [0 ]!= '{' {
313
315
logger .Error (ctx ,"devcontainer result is not json" ,slog .F ("result" ,string (lastLine )))
314
- return xerrors .Errorf ("devcontainer result is not json: %q" ,string (lastLine ))
316
+ return result , xerrors .Errorf ("devcontainer result is not json: %q" ,string (lastLine ))
315
317
}
316
318
if err := json .Unmarshal (lastLine ,& result );err != nil {
317
319
logger .Error (ctx ,"parse devcontainer result failed" ,slog .Error (err ),slog .F ("result" ,string (lastLine )))
318
- return err
320
+ return result , err
319
321
}
320
322
321
- return nil
323
+ return result , nil
322
324
}
323
325
324
326
// devcontainerCLIResult is the result of the devcontainer CLI command.