Files
av1-go/utils.go

112 lines
2.7 KiB
Go

package main
import (
"fmt"
"io"
"log"
"os"
"os/exec"
"runtime"
"strings"
)
var (
// Logger is the global logger
Logger *log.Logger
// LogFileHandle keeps the file handle to close it later
LogFileHandle *os.File
)
// SetupLogging configures logging to both console and file
func SetupLogging(logPath string) error {
// Close previous log file if open
if LogFileHandle != nil {
LogFileHandle.Close()
}
f, err := os.OpenFile(logPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
if err != nil {
return err
}
LogFileHandle = f
// MultiWriter to write to both stdout and file
mw := io.MultiWriter(os.Stdout, f)
Logger = log.New(mw, "", log.LstdFlags)
return nil
}
// LogInfo logs a message
func LogInfo(format string, v ...interface{}) {
if Logger != nil {
Logger.Printf(format, v...)
} else {
log.Printf(format, v...)
}
}
// RunCmd executes a command.
// If captureOutput is true, it returns the stdout as string.
// If captureOutput is false, it streams stdout/stderr to the console (and log file if possible).
func RunCmd(name string, args []string, captureOutput bool) (string, error) {
cmdStr := fmt.Sprintf("%s %s", name, strings.Join(args, " "))
LogInfo("Executing: %s", cmdStr)
cmd := exec.Command(name, args...)
if captureOutput {
output, err := cmd.Output()
if err != nil {
if exitErr, ok := err.(*exec.ExitError); ok {
return "", fmt.Errorf("command failed: %s\nstderr: %s", err, string(exitErr.Stderr))
}
return "", err
}
return string(output), nil
}
// Passthrough mode
// We want to stream to both stdout/stderr AND the log file if possible.
// However, for interactive tools or progress bars, simple MultiWriter might mess up formatting.
// For simplicity and safety with tools like av1an/ffmpeg showing progress bars,
// we will just pipe to Stdout/Stderr of the parent process.
// If we want to capture logs, we'd need a pipe that writes to file and stdout.
if LogFileHandle != nil {
cmd.Stdout = io.MultiWriter(os.Stdout, LogFileHandle)
cmd.Stderr = io.MultiWriter(os.Stderr, LogFileHandle)
} else {
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
}
err := cmd.Run()
if err != nil {
return "", err
}
return "", nil
}
// CheckTools verifies that all required tools are in PATH
func CheckTools(tools []string) {
missing := []string{}
for _, tool := range tools {
_, err := exec.LookPath(tool)
if err != nil {
missing = append(missing, tool)
}
}
if len(missing) > 0 {
fmt.Printf("Error: The following required tools are missing from PATH:\n")
for _, m := range missing {
fmt.Printf(" - %s\n", m)
}
os.Exit(1)
}
}
// GetTotalCores returns the number of logical CPUs
func GetTotalCores() int {
return runtime.NumCPU()
}