blob: 0ff58be012af4a4c54b2ccb3a1b5fb07e71b12df [file] [log] [blame]
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package log
import (
"log"
"os"
"os/exec"
"path/filepath"
"strings"
shellquote "github.com/kballard/go-shellquote"
)
var (
cmdLog, actLog *log.Logger
cmdOn, actOn = false, false
envMap map[string]string
)
func init() {
cmdLog = log.New(os.Stdout, "[shell] ", 0)
actLog = log.New(os.Stderr, "[sweet] ", 0)
envMap = makeEnvironMap()
}
func makeEnvironMap() map[string]string {
env := os.Environ()
envmap := make(map[string]string)
for _, e := range env {
s := strings.SplitN(e, "=", 2)
if len(s) != 2 {
continue
}
envmap[s[0]] = s[1]
}
return envmap
}
func SetCommandTrace(on bool) {
cmdOn = on
}
func SetActivityLog(on bool) {
actOn = on
}
func filterEnviron(env []string) []string {
fenv := make([]string, 0, len(env))
for _, e := range env {
s := strings.SplitN(e, "=", 2)
if len(s) != 2 {
continue
}
if v, ok := envMap[s[0]]; ok && v == s[1] {
continue
}
fenv = append(fenv, e)
}
return fenv
}
func TraceCommand(cmd *exec.Cmd, background bool) {
if !cmdOn {
return
}
senv := ""
if len(cmd.Env) != 0 {
senv = strings.Join(filterEnviron(cmd.Env), " ")
}
if cmd.Dir != "" {
cmdLog.Printf("pushd %s", cmd.Dir)
}
sbg := ""
if background {
sbg = " &"
}
sarg := shellquote.Join(cmd.Args...)
if senv != "" {
cmdLog.Printf("%s %s%s", senv, sarg, sbg)
} else {
cmdLog.Printf("%s%s", sarg, sbg)
}
if cmd.Dir != "" {
cmdLog.Printf("popd")
}
}
func TraceKill(cmd *exec.Cmd) {
if !cmdOn {
return
}
cmdLog.Printf("killall -SIGINT %s", filepath.Base(cmd.Path))
}
func CommandPrintf(format string, args ...interface{}) {
if !cmdOn {
return
}
cmdLog.Printf(format, args...)
}
func Printf(format string, args ...interface{}) {
if !actOn {
return
}
actLog.Printf(format, args...)
}
func Print(args ...interface{}) {
if !actOn {
return
}
actLog.Print(args...)
}
func Error(err error) {
actLog.Printf("error: %v", err)
if e, ok := err.(*exec.ExitError); ok {
actLog.Printf("output:\n%s", string(e.Stderr))
}
}