From 2fec8a20fb8f485f2107deb00d29c99dfdfbde47 Mon Sep 17 00:00:00 2001 From: Rose Hogenson Date: Sat, 5 Apr 2025 08:03:18 -0700 Subject: Initial commit --- .gitignore | 1 + go.mod | 7 ++++++ go.sum | 4 +++ progress-bar.go | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+) create mode 100644 .gitignore create mode 100644 go.mod create mode 100644 go.sum create mode 100644 progress-bar.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b5b2c1b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/progress-bar diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..8d19cf8 --- /dev/null +++ b/go.mod @@ -0,0 +1,7 @@ +module gitlab.com/rhogenson/progress-bar + +go 1.24.1 + +require golang.org/x/term v0.28.0 + +require golang.org/x/sys v0.29.0 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..f05f63b --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= +golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= diff --git a/progress-bar.go b/progress-bar.go new file mode 100644 index 0000000..0b1cefe --- /dev/null +++ b/progress-bar.go @@ -0,0 +1,76 @@ +package main + +import ( + "bytes" + "errors" + "flag" + "fmt" + "os" + "os/exec" + "strconv" + "strings" + "time" + + "golang.org/x/term" +) + +var n = flag.Duration("n", 2*time.Minute, "polling interval") + +func run() error { + cols, _, err := term.GetSize(int(os.Stdout.Fd())) + if err != nil { + return err + } + args := flag.Args() + if len(args) < 2 { + return errors.New("usage error") + } + maxStr := args[0] + maxVal, err := strconv.Atoi(maxStr) + if err != nil { + return fmt.Errorf("max: %s", err) + } + cmd := args[1:] + type measurement struct { + t time.Time + i int + } + var measurements []measurement + for i := 0; ; i++ { + outputBytes, err := exec.Command(cmd[0], cmd[1:]...).Output() + if err != nil { + fmt.Println(err) + continue + } + output, err := strconv.Atoi(string(bytes.TrimSuffix(outputBytes, []byte("\n")))) + if err != nil { + fmt.Println(err) + continue + } + p := output * cols / maxVal + if i > 0 { + fmt.Print("\033[2F\033[J") + } + fmt.Printf("%s>\n", strings.Repeat("=", max(p-1, 0))) + measurements = append(measurements, measurement{time.Now(), output}) + if len(measurements) > 20 { + measurements = measurements[1:] + } + deltaT := measurements[len(measurements)-1].t.Sub(measurements[0].t) + delta := measurements[len(measurements)-1].i - measurements[0].i + if delta == 0 { + fmt.Println() + } else { + fmt.Printf("ETA: %s\n", time.Duration(float64(maxVal-output)/float64(delta)*float64(deltaT)).Round(time.Second)) + } + time.Sleep(*n) + } +} + +func main() { + flag.Parse() + if err := run(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} -- cgit v1.3.1