Skip to content

Commit

Permalink
feat: use stdout and err to get info in realtime and not after comman…
Browse files Browse the repository at this point in the history
…ds are completed
  • Loading branch information
bjarneo committed Nov 15, 2024
1 parent e0074d7 commit a4d65b5
Showing 1 changed file with 44 additions and 9 deletions.
53 changes: 44 additions & 9 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"bufio"
"encoding/json"
"flag"
"fmt"
Expand Down Expand Up @@ -223,7 +224,7 @@ func (c *Config) ValidateConfig() error {
return nil
}

// ExecuteCommand executes a shell command and logs the output
// ExecuteCommand executes a shell command and streams the output
func ExecuteCommand(logger *Logger, command string, description string) (*CommandResult, error) {
if err := logger.Info(fmt.Sprintf("%s...", description)); err != nil {
return nil, err
Expand All @@ -233,19 +234,53 @@ func ExecuteCommand(logger *Logger, command string, description string) (*Comman
}

cmd := exec.Command("sh", "-c", command)
output, err := cmd.CombinedOutput()

stdout, err := cmd.StdoutPipe()
if err != nil {
logger.Error(fmt.Sprintf("Failed: %s", description), err)
return nil, err
return nil, fmt.Errorf("failed to create stdout pipe: %v", err)
}

result := &CommandResult{
Stdout: string(output),
Stderr: "",
stderr, err := cmd.StderrPipe()
if err != nil {
return nil, fmt.Errorf("failed to create stderr pipe: %v", err)
}

if len(output) > 0 {
logger.Info(fmt.Sprintf("Output: %s", string(output)))
if err := cmd.Start(); err != nil {
return nil, fmt.Errorf("failed to start command: %v", err)
}

// Create buffers to store complete output
var stdoutBuilder, stderrBuilder strings.Builder

// Read stdout in real-time
go func() {
scanner := bufio.NewScanner(stdout)
for scanner.Scan() {
line := scanner.Text()
fmt.Println(line)
stdoutBuilder.WriteString(line + "\n")
logger.Info(line)
}
}()

// Read stderr in real-time
go func() {
scanner := bufio.NewScanner(stderr)
for scanner.Scan() {
line := scanner.Text()
fmt.Println("ERROR:", line)
stderrBuilder.WriteString(line + "\n")
logger.Error(line, nil)
}
}()

if err := cmd.Wait(); err != nil {
return nil, fmt.Errorf("command failed: %v", err)
}

result := &CommandResult{
Stdout: stdoutBuilder.String(),
Stderr: stderrBuilder.String(),
}

return result, nil
Expand Down

0 comments on commit a4d65b5

Please sign in to comment.