mirror of
https://github.com/crunchy-labs/crunchy-cli.git
synced 2026-01-21 12:12:00 -06:00
196 lines
3.8 KiB
Go
196 lines
3.8 KiB
Go
package commands
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/ByteDream/crunchy-cli/utils"
|
|
"io"
|
|
"log"
|
|
"os"
|
|
"runtime"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
var prefix, progressDown, progressDownFinish string
|
|
|
|
func initPrefixBecauseWindowsSucksBallsHard() {
|
|
// dear windows user, please change to a good OS, linux in the best case.
|
|
// MICROSHIT DOES NOT GET IT DONE TO SHOW THE SYMBOLS IN THE ELSE CLAUSE
|
|
// CORRECTLY. NOT IN THE CMD NOR POWERSHELL. WHY TF, IT IS ONE OF THE MOST
|
|
// PROFITABLE COMPANIES ON THIS PLANET AND CANNOT SHOW A PROPER UTF-8 SYMBOL
|
|
// IN THEIR OWN PRODUCT WHICH GETS USED MILLION TIMES A DAY
|
|
if runtime.GOOS == "windows" {
|
|
prefix = "=>"
|
|
progressDown = "|"
|
|
progressDownFinish = "->"
|
|
} else {
|
|
prefix = "➞"
|
|
progressDown = "↓"
|
|
progressDownFinish = "↳"
|
|
}
|
|
}
|
|
|
|
type progress struct {
|
|
message string
|
|
stop bool
|
|
}
|
|
|
|
func NewLogger(debug, info, err bool) *Logger {
|
|
initPrefixBecauseWindowsSucksBallsHard()
|
|
|
|
debugLog, infoLog, errLog := log.New(io.Discard, prefix+" ", 0), log.New(io.Discard, prefix+" ", 0), log.New(io.Discard, prefix+" ", 0)
|
|
|
|
if debug {
|
|
debugLog.SetOutput(os.Stdout)
|
|
}
|
|
if info {
|
|
infoLog.SetOutput(os.Stdout)
|
|
}
|
|
if err {
|
|
errLog.SetOutput(os.Stderr)
|
|
}
|
|
|
|
if debug {
|
|
debugLog = log.New(debugLog.Writer(), "[debug] ", 0)
|
|
infoLog = log.New(infoLog.Writer(), "[info] ", 0)
|
|
errLog = log.New(errLog.Writer(), "[err] ", 0)
|
|
}
|
|
|
|
return &Logger{
|
|
DebugLog: debugLog,
|
|
InfoLog: infoLog,
|
|
ErrLog: errLog,
|
|
|
|
devView: debug,
|
|
}
|
|
}
|
|
|
|
type Logger struct {
|
|
utils.Logger
|
|
|
|
DebugLog *log.Logger
|
|
InfoLog *log.Logger
|
|
ErrLog *log.Logger
|
|
|
|
devView bool
|
|
|
|
progress chan progress
|
|
done chan interface{}
|
|
lock sync.Mutex
|
|
}
|
|
|
|
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) Warn(format string, v ...interface{}) {
|
|
l.Err(format, v...)
|
|
}
|
|
|
|
func (l *Logger) Err(format string, v ...interface{}) {
|
|
l.ErrLog.Printf(format, v...)
|
|
}
|
|
|
|
func (l *Logger) Empty() {
|
|
if !l.devView && l.InfoLog.Writer() != io.Discard {
|
|
fmt.Println("")
|
|
}
|
|
}
|
|
|
|
func (l *Logger) SetProcess(format string, v ...interface{}) {
|
|
if l.InfoLog.Writer() == io.Discard {
|
|
return
|
|
} else if l.devView {
|
|
l.Debug(format, v...)
|
|
return
|
|
}
|
|
|
|
initialMessage := fmt.Sprintf(format, v...)
|
|
|
|
p := progress{
|
|
message: initialMessage,
|
|
}
|
|
|
|
l.lock.Lock()
|
|
if l.done != nil {
|
|
l.progress <- p
|
|
return
|
|
} else {
|
|
l.progress = make(chan progress, 1)
|
|
l.progress <- p
|
|
l.done = make(chan interface{})
|
|
}
|
|
|
|
go func() {
|
|
states := []string{"-", "\\", "|", "/"}
|
|
|
|
var count int
|
|
|
|
for i := 0; ; i++ {
|
|
select {
|
|
case p := <-l.progress:
|
|
if p.stop {
|
|
fmt.Printf("\r" + strings.Repeat(" ", len(prefix)+len(initialMessage)))
|
|
if count > 1 {
|
|
fmt.Printf("\r%s %s\n", progressDownFinish, p.message)
|
|
} else {
|
|
fmt.Printf("\r%s %s\n", prefix, p.message)
|
|
}
|
|
|
|
if l.done != nil {
|
|
l.done <- nil
|
|
}
|
|
l.progress = nil
|
|
|
|
l.lock.Unlock()
|
|
return
|
|
} else {
|
|
if count > 0 {
|
|
fmt.Printf("\r%s %s\n", progressDown, p.message)
|
|
}
|
|
l.progress = make(chan progress, 1)
|
|
|
|
count++
|
|
|
|
fmt.Printf("\r%s %s", states[i/10%4], initialMessage)
|
|
l.lock.Unlock()
|
|
}
|
|
default:
|
|
if i%10 == 0 {
|
|
fmt.Printf("\r%s %s", states[i/10%4], initialMessage)
|
|
}
|
|
time.Sleep(35 * time.Millisecond)
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
|
|
func (l *Logger) StopProcess(format string, v ...interface{}) {
|
|
if l.InfoLog.Writer() == io.Discard {
|
|
return
|
|
} else if l.devView {
|
|
l.Debug(format, v...)
|
|
return
|
|
}
|
|
|
|
l.lock.Lock()
|
|
l.progress <- progress{
|
|
message: fmt.Sprintf(format, v...),
|
|
stop: true,
|
|
}
|
|
<-l.done
|
|
l.done = nil
|
|
}
|