]> Cypherpunks.ru repositories - goredo.git/blob - status.go
Up to date recfile
[goredo.git] / status.go
1 /*
2 goredo -- djb's redo implementation on pure Go
3 Copyright (C) 2020-2021 Sergey Matveev <stargrave@stargrave.org>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, version 3 of the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 package main
19
20 import (
21         "flag"
22         "fmt"
23         "log"
24         "os"
25 )
26
27 const (
28         EnvStatusFd = "REDO_STATUS_FD"
29         EnvNoStatus = "REDO_NO_STATUS"
30
31         StatusRun = iota
32         StatusDone
33         StatusWait
34         StatusWaited
35 )
36
37 var (
38         FdStatus *os.File
39
40         flagNoStatus = flag.Bool("no-status", false, "disable statusline (REDO_NO_STATUS=1)")
41 )
42
43 func statusInit() {
44         if NoProgress || *flagNoStatus {
45                 return
46         }
47         if v := os.Getenv(EnvNoStatus); v == "1" {
48                 return
49         }
50         if v := os.Getenv(EnvStatusFd); v != "" {
51                 if v == "NO" {
52                         return
53                 }
54                 FdStatus = mustParseFd(v, EnvStatusFd)
55                 return
56         }
57         var r *os.File
58         var err error
59         r, FdStatus, err = os.Pipe()
60         if err != nil {
61                 log.Fatalln(err)
62         }
63         go func() {
64                 running := 0
65                 waiting := 0
66                 done := 0
67                 var out string
68                 buf := make([]byte, 1)
69                 var n int
70                 for {
71                         n, err = r.Read(buf)
72                         if err != nil || n != 1 {
73                                 break
74                         }
75                         switch buf[0] {
76                         case StatusRun:
77                                 running++
78                         case StatusDone:
79                                 running--
80                                 done++
81                         case StatusWait:
82                                 waiting++
83                         case StatusWaited:
84                                 waiting--
85                         }
86                         if NoColor {
87                                 out = fmt.Sprintf(
88                                         "\rrun: %d wait: %d done: %d",
89                                         running, waiting, done,
90                                 )
91                         } else {
92                                 out = fmt.Sprintf(
93                                         "\rrun: %s%d%s wait: %s%d%s done: %s%d%s",
94                                         CRedo, running, CReset,
95                                         CWait, waiting, CReset,
96                                         CJS, done, CReset,
97                                 )
98                         }
99                         LogMutex.Lock()
100                         os.Stderr.WriteString(fillUpToTermSize(out, "\r"))
101                         LogMutex.Unlock()
102                 }
103         }()
104 }