/* goredo -- redo implementation on pure Go Copyright (C) 2020 Sergey Matveev This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package main import ( "flag" "fmt" "os" "strings" ) const ( EnvStatusFd = "REDO_STATUS_FD" EnvNoStatus = "REDO_NO_STATUS" StatusRun = iota StatusDone StatusWait StatusWaited ) var ( FdStatus *os.File flagNoStatus = flag.Bool("no-status", false, "disable statusline (REDO_NO_STATUS=1)") ) func statusInit() { if *flagNoStatus { return } if v := os.Getenv(EnvNoStatus); v == "1" { return } if v := os.Getenv(EnvStatusFd); v != "" { if v == "NO" { return } FdStatus = mustParseFd(v, EnvStatusFd) return } var r *os.File var err error r, FdStatus, err = os.Pipe() if err != nil { panic(err) } go func() { running := 0 waiting := 0 done := 0 var out string outLenPrev := 0 buf := make([]byte, 1) var n int for { n, err = r.Read(buf) if err != nil || n != 1 { break } switch buf[0] { case StatusRun: running++ case StatusDone: running-- done++ case StatusWait: waiting++ case StatusWaited: waiting-- } if NoColor { out = fmt.Sprintf( "\rrun: %d wait: %d done: %d\r", running, waiting, done, ) } else { out = fmt.Sprintf( "\rrun: %s%d%s wait: %s%d%s done: %s%d%s\r", CRedo, running, CReset, CWait, waiting, CReset, CJS, done, CReset, ) } if len(out) < outLenPrev { outLenPrev = len(out) out += strings.Repeat(" ", outLenPrev-len(out)) } else { outLenPrev = len(out) } LogMutex.Lock() os.Stderr.WriteString(out) LogMutex.Unlock() } }() }