]> Cypherpunks.ru repositories - goredo.git/blob - status.go
Unify dep*Read/Write name
[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 *bool
41 )
42
43 func init() {
44         cmdName := CmdName()
45         if !(cmdName == CmdNameRedo || cmdName == CmdNameRedoIfchange) {
46                 return
47         }
48         flagNoStatus = flag.Bool("no-status", false, "disable statusline (REDO_NO_STATUS=1)")
49 }
50
51 func statusInit() {
52         if NoProgress || *flagNoStatus {
53                 return
54         }
55         if v := os.Getenv(EnvNoStatus); v == "1" {
56                 return
57         }
58         if v := os.Getenv(EnvStatusFd); v != "" {
59                 if v == "NO" {
60                         return
61                 }
62                 FdStatus = mustParseFd(v, EnvStatusFd)
63                 return
64         }
65         var r *os.File
66         var err error
67         r, FdStatus, err = os.Pipe()
68         if err != nil {
69                 log.Fatalln(err)
70         }
71         go func() {
72                 running := 0
73                 waiting := 0
74                 done := 0
75                 var out string
76                 buf := make([]byte, 1)
77                 var n int
78                 for {
79                         n, err = r.Read(buf)
80                         if err != nil || n != 1 {
81                                 break
82                         }
83                         switch buf[0] {
84                         case StatusRun:
85                                 running++
86                         case StatusDone:
87                                 running--
88                                 done++
89                         case StatusWait:
90                                 waiting++
91                         case StatusWaited:
92                                 waiting--
93                         }
94                         if NoColor {
95                                 out = fmt.Sprintf(
96                                         "\rrun: %d wait: %d done: %d",
97                                         running, waiting, done,
98                                 )
99                         } else {
100                                 out = fmt.Sprintf(
101                                         "\rrun: %s%d%s wait: %s%d%s done: %s%d%s",
102                                         CRedo, running, CReset,
103                                         CWait, waiting, CReset,
104                                         CJS, done, CReset,
105                                 )
106                         }
107                         out = erasedStatus(out, "\r")
108                         LogMutex.Lock()
109                         os.Stderr.WriteString(out)
110                         LogMutex.Unlock()
111                 }
112         }()
113 }