mirror of
https://github.com/crunchy-labs/crunchy-cli.git
synced 2026-01-21 12:12:00 -06:00
Fixed logger to properly delete current line before overwriting
This commit is contained in:
parent
e785cb580b
commit
252762f410
1 changed files with 89 additions and 124 deletions
|
|
@ -1,19 +1,18 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type progress struct {
|
type progress struct {
|
||||||
status bool
|
|
||||||
message string
|
message string
|
||||||
|
stop bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type logger struct {
|
type logger struct {
|
||||||
|
|
@ -23,26 +22,21 @@ type logger struct {
|
||||||
|
|
||||||
devView bool
|
devView bool
|
||||||
|
|
||||||
progressWG sync.Mutex
|
progress chan progress
|
||||||
progress chan progress
|
done chan interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newLogger(debug, info, err bool, color bool) *logger {
|
func newLogger(debug, info, err bool) *logger {
|
||||||
debugLog, infoLog, errLog := log.New(io.Discard, "=> ", 0), log.New(io.Discard, "=> ", 0), log.New(io.Discard, "=> ", 0)
|
debugLog, infoLog, errLog := log.New(io.Discard, "➞ ", 0), log.New(io.Discard, "➞ ", 0), log.New(io.Discard, "➞ ", 0)
|
||||||
|
|
||||||
debugColor, infoColor, errColor := "", "", ""
|
|
||||||
if color && runtime.GOOS != "windows" {
|
|
||||||
debugColor, infoColor, errColor = "\033[95m", "\033[96m", "\033[31m"
|
|
||||||
}
|
|
||||||
|
|
||||||
if debug {
|
if debug {
|
||||||
debugLog.SetOutput(&loggerWriter{original: os.Stdout, color: debugColor})
|
debugLog.SetOutput(os.Stdout)
|
||||||
}
|
}
|
||||||
if info {
|
if info {
|
||||||
infoLog.SetOutput(&loggerWriter{original: os.Stdout, color: infoColor})
|
infoLog.SetOutput(os.Stdout)
|
||||||
}
|
}
|
||||||
if err {
|
if err {
|
||||||
errLog.SetOutput(&loggerWriter{original: os.Stdout, color: errColor})
|
errLog.SetOutput(os.Stderr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if debug {
|
if debug {
|
||||||
|
|
@ -60,140 +54,111 @@ func newLogger(debug, info, err bool, color bool) *logger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *logger) IsDev() bool {
|
||||||
|
return l.devView
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *logger) IsQuiet() bool {
|
||||||
|
return l.DebugLog.Writer() == io.Discard && l.InfoLog.Writer() == io.Discard && l.ErrLog.Writer() == io.Discard
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *logger) Debug(format string, v ...interface{}) {
|
||||||
|
l.DebugLog.Printf(format, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *logger) Info(format string, v ...interface{}) {
|
||||||
|
l.InfoLog.Printf(format, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *logger) Err(format string, v ...interface{}) {
|
||||||
|
l.ErrLog.Printf(format, v...)
|
||||||
|
}
|
||||||
|
|
||||||
func (l *logger) Empty() {
|
func (l *logger) Empty() {
|
||||||
if !l.devView && l.InfoLog.Writer() != io.Discard {
|
if l.InfoLog.Writer() != io.Discard {
|
||||||
fmt.Println()
|
fmt.Println("")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *logger) StartProgress(message string) {
|
func (l *logger) SetProgress(format string, v ...interface{}) {
|
||||||
if l.devView {
|
if out.InfoLog.Writer() == io.Discard {
|
||||||
l.InfoLog.Println(message)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message := fmt.Sprintf(format, v...)
|
||||||
|
|
||||||
|
if l.progress != nil {
|
||||||
|
l.progress <- progress{
|
||||||
|
message: message,
|
||||||
|
stop: false,
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
l.progress = make(chan progress)
|
l.progress = make(chan progress)
|
||||||
|
l.done = make(chan interface{})
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
states := []string{"-", "\\", "|", "/"}
|
states := []string{"-", "\\", "|", "/"}
|
||||||
|
var count int
|
||||||
|
|
||||||
for i := 0; ; i++ {
|
for i := 0; ; i++ {
|
||||||
l.progressWG.Lock()
|
ctx, cancel := context.WithTimeout(context.Background(), 35*time.Millisecond)
|
||||||
select {
|
select {
|
||||||
case p := <-l.progress:
|
case p := <-l.progress:
|
||||||
// clearing the last line
|
cancel()
|
||||||
fmt.Printf("\r%s\r", strings.Repeat(" ", len(l.InfoLog.Prefix())+len(message)+2))
|
|
||||||
if p.status {
|
if p.stop {
|
||||||
successTag := "✔"
|
if !l.devView {
|
||||||
if runtime.GOOS == "windows" {
|
fmt.Printf("\r" + strings.Repeat(" ", 2+len(message)))
|
||||||
successTag = "~"
|
fmt.Printf("\r➞ %s\n", p.message)
|
||||||
|
} else {
|
||||||
|
l.Debug(message)
|
||||||
}
|
}
|
||||||
l.InfoLog.Printf("%s %s", successTag, p.message)
|
|
||||||
|
l.progress = nil
|
||||||
|
|
||||||
|
if count > 0 {
|
||||||
|
fmt.Printf("↳ %s\n", p.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
l.done <- nil
|
||||||
|
return
|
||||||
} else {
|
} else {
|
||||||
errorTag := "✘"
|
if !l.devView {
|
||||||
if runtime.GOOS == "windows" {
|
fmt.Printf("\r↓ %s\n", message)
|
||||||
errorTag = "!"
|
} else {
|
||||||
|
l.Debug(message)
|
||||||
}
|
}
|
||||||
l.ErrLog.Printf("%s %s", errorTag, p.message)
|
|
||||||
|
l.progress = make(chan progress)
|
||||||
|
count++
|
||||||
|
|
||||||
|
if !l.devView {
|
||||||
|
fmt.Printf("\r" + strings.Repeat(" ", 2+len(message)))
|
||||||
|
fmt.Printf("\r➞ %s\n", p.message)
|
||||||
|
} else {
|
||||||
|
l.Debug(p.message)
|
||||||
|
}
|
||||||
|
message = p.message
|
||||||
}
|
}
|
||||||
l.progress = nil
|
case <-ctx.Done():
|
||||||
l.progressWG.Unlock()
|
if !l.devView && i%10 == 0 {
|
||||||
return
|
fmt.Printf("\r%s %s", states[i/10%4], message)
|
||||||
default:
|
|
||||||
if i%10 == 0 {
|
|
||||||
fmt.Printf("\r%s%s %s", l.InfoLog.Prefix(), states[i/10%4], message)
|
|
||||||
}
|
}
|
||||||
time.Sleep(35 * time.Millisecond)
|
|
||||||
l.progressWG.Unlock()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *logger) StartProgressf(message string, a ...interface{}) {
|
func (l *logger) StopProgress(format string, v ...interface{}) {
|
||||||
l.StartProgress(fmt.Sprintf(message, a...))
|
if out.InfoLog.Writer() == io.Discard {
|
||||||
}
|
|
||||||
|
|
||||||
func (l *logger) EndProgress(successful bool, message string) {
|
|
||||||
if l.devView {
|
|
||||||
if successful {
|
|
||||||
l.InfoLog.Print(message)
|
|
||||||
} else {
|
|
||||||
l.ErrLog.Print(message)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
} else if l.progress != nil {
|
|
||||||
l.progress <- progress{
|
|
||||||
status: successful,
|
|
||||||
message: message,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *logger) EndProgressf(successful bool, message string, a ...interface{}) {
|
|
||||||
l.EndProgress(successful, fmt.Sprintf(message, a...))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *logger) Debugln(v ...interface{}) {
|
|
||||||
l.print(0, v...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *logger) Debugf(message string, a ...interface{}) {
|
|
||||||
l.print(0, fmt.Sprintf(message, a...))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *logger) Infoln(v ...interface{}) {
|
|
||||||
l.print(1, v...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *logger) Infof(message string, a ...interface{}) {
|
|
||||||
l.print(1, fmt.Sprintf(message, a...))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *logger) Errln(v ...interface{}) {
|
|
||||||
l.print(2, v...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *logger) Errf(message string, a ...interface{}) {
|
|
||||||
l.print(2, fmt.Sprintf(message, a...))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *logger) Fatalln(v ...interface{}) {
|
|
||||||
l.print(2, v...)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *logger) Fatalf(message string, a ...interface{}) {
|
|
||||||
l.print(2, fmt.Sprintf(message, a...))
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *logger) print(level int, v ...interface{}) {
|
|
||||||
if l.progress != nil {
|
|
||||||
l.progressWG.Lock()
|
|
||||||
defer l.progressWG.Unlock()
|
|
||||||
fmt.Print("\r")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch level {
|
l.progress <- progress{
|
||||||
case 0:
|
message: fmt.Sprintf(format, v...),
|
||||||
l.DebugLog.Print(v...)
|
stop: true,
|
||||||
case 1:
|
|
||||||
l.InfoLog.Print(v...)
|
|
||||||
case 2:
|
|
||||||
l.ErrLog.Print(v...)
|
|
||||||
}
|
}
|
||||||
}
|
<-l.done
|
||||||
|
|
||||||
type loggerWriter struct {
|
|
||||||
io.Writer
|
|
||||||
|
|
||||||
original io.Writer
|
|
||||||
color string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lw *loggerWriter) Write(p []byte) (n int, err error) {
|
|
||||||
if lw.color != "" {
|
|
||||||
p = append([]byte(lw.color), p...)
|
|
||||||
p = append(p, []byte("\033[0m")...)
|
|
||||||
}
|
|
||||||
return lw.original.Write(p)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue