refactor: Extract runBdCommand helper to DRY mail package (gt-8i6bg)
Extracted duplicate bd command execution pattern from mailbox.go and router.go into a new helper function in bd.go. This reduces code duplication and provides consistent error handling via the bdError type. Changes: - Added internal/mail/bd.go with runBdCommand helper and bdError type - Refactored 5 functions in mailbox.go to use runBdCommand - Refactored 5 functions in router.go to use runBdCommand - Net reduction of 55 lines of code 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
committed by
Steve Yegge
parent
254288800d
commit
4ebb96fbbc
62
internal/mail/bd.go
Normal file
62
internal/mail/bd.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package mail
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// bdError represents an error from running a bd command.
|
||||
// It wraps the underlying error and includes the stderr output for inspection.
|
||||
type bdError struct {
|
||||
Err error
|
||||
Stderr string
|
||||
}
|
||||
|
||||
// Error implements the error interface.
|
||||
func (e *bdError) Error() string {
|
||||
if e.Stderr != "" {
|
||||
return e.Stderr
|
||||
}
|
||||
if e.Err != nil {
|
||||
return e.Err.Error()
|
||||
}
|
||||
return "unknown bd error"
|
||||
}
|
||||
|
||||
// Unwrap returns the underlying error for errors.Is/As compatibility.
|
||||
func (e *bdError) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
// ContainsError checks if the stderr message contains the given substring.
|
||||
func (e *bdError) ContainsError(substr string) bool {
|
||||
return strings.Contains(e.Stderr, substr)
|
||||
}
|
||||
|
||||
// runBdCommand executes a bd command with proper environment setup.
|
||||
// workDir is the directory to run the command in.
|
||||
// beadsDir is the BEADS_DIR environment variable value.
|
||||
// extraEnv contains additional environment variables to set (e.g., "BD_IDENTITY=...").
|
||||
// Returns stdout bytes on success, or a *bdError on failure.
|
||||
func runBdCommand(args []string, workDir, beadsDir string, extraEnv ...string) ([]byte, error) {
|
||||
cmd := exec.Command("bd", args...) //nolint:gosec // G204: bd is a trusted internal tool
|
||||
cmd.Dir = workDir
|
||||
|
||||
env := append(cmd.Environ(), "BEADS_DIR="+beadsDir)
|
||||
env = append(env, extraEnv...)
|
||||
cmd.Env = env
|
||||
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = &stderr
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
return nil, &bdError{
|
||||
Err: err,
|
||||
Stderr: strings.TrimSpace(stderr.String()),
|
||||
}
|
||||
}
|
||||
|
||||
return stdout.Bytes(), nil
|
||||
}
|
||||
Reference in New Issue
Block a user