summaryrefslogtreecommitdiff
path: root/reloadCheckDirty.go
blob: 196869d7676a445c6afb9c1fead638200984234e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package gitpb

// runs git, parses output
// types faster than you can

import (
	"fmt"
	"strings"
	"time"

	"go.wit.com/lib/gui/shell"
	"go.wit.com/log"
	"google.golang.org/protobuf/types/known/timestamppb"
)

func (repo *Repo) NoteChange(s string) {
	log.Warn("NoteChange()", s)
}

// just return the current value
func (repo *Repo) IsDirty() bool {
	return repo.Dirty
}

func (repo *Repo) SmartSetState(newstate string) bool {
	if newstate == repo.State {
		// nothing changed
		return false
	}
	repo.State = newstate
	return true
}

// returns true if the repo is dirty
// runs os.Exec('git') every time
func (repo *Repo) CheckDirty() bool {
	cmd := []string{"git", "status", "--porcelain"}
	r := shell.PathRunLog(repo.FullPath, cmd, INFO)
	if r.Error != nil {
		log.Warn("CheckDirty() status cmd =", cmd)
		out := strings.Join(r.Stdout, "\n")
		log.Warn("CheckDirty() status out =", out)
		log.Warn("CheckDirty() status err =", r.Error)
		log.Error(r.Error, "CheckDirty() git status error")
		repo.NoteChange("git status is in error " + fmt.Sprint(r.Error))
		repo.Dirty = true
		repo.State = "dirty porcelain"
		return true
	}
	if len(r.Stdout) == 0 {
		repo.Dirty = false
		repo.SmartSetState("")
	}
	// dirty if anything but go.mod and go.sum
	var bad bool = false
	for _, line := range r.Stdout {
		parts := strings.Fields(line)
		if len(parts) == 2 {
			switch parts[1] {
			case "go.mod":
			case "go.sum":
			default:
				bad = true
			}
		} else {
			bad = true
		}
	}
	repo.DirtyList = r.Stdout

	pbnow := timestamppb.New(time.Now())
	repo.Times.LastDirty = pbnow
	repo.Dirty = bad
	if bad {
		repo.Dirty = true
		repo.SmartSetState("dirty")
		return true
	}
	repo.Dirty = false
	repo.SmartSetState("")
	return false
}

func (all *Repos) CheckPorcelain() (string, error) {
	var totals int
	var files []string
	var allerr []error
	for repo := range all.IterByNamespace() {
		s, err := repo.CheckDirtyVerbose()
		lines := strings.Split(s, "\n")
		files = append(files, lines...)
		totals += len(lines)
		if err != nil {
			allerr = append(allerr, err)
		}
		repo.Dirty = false
		repo.State = "pcheck 1"
		repo.StateChange = "pcheck 2"
	}
	for _, filename := range files {
		log.Info(filename)
	}
	return fmt.Sprintf("%d lines %d errors %d repos", totals, len(allerr), all.Len()), nil
}

// returns true if the repo is dirty
// runs os.Exec('git') every time
func (repo *Repo) CheckDirtyVerbose() (string, error) {
	cmd := []string{"git", "status", "--porcelain"}
	r := shell.PathRunLog(repo.FullPath, cmd, INFO)
	if r.Error != nil {
		log.Warn("CheckDirty() status cmd =", cmd)
		out := strings.Join(r.Stdout, "\n")
		log.Warn("CheckDirty() status out =", out)
		log.Warn("CheckDirty() status err =", r.Error)
		log.Error(r.Error, "CheckDirty() git status error")
		repo.NoteChange("git status is in error " + fmt.Sprint(r.Error))
		repo.Dirty = true
		repo.State = "dirty porcelain"
		return "dirty porcelain", r.Error
	}
	if len(r.Stdout) == 0 {
		repo.Dirty = false
		repo.SmartSetState("")
	}
	// dirty if anything but go.mod and go.sum
	var bad bool = false
	for _, line := range r.Stdout {
		parts := strings.Fields(line)
		log.Info("Dirty:", repo.FullPath, line)
		if len(parts) == 2 {
			switch parts[1] {
			case "go.mod":
			case "go.sum":
			default:
				bad = true
			}
		} else {
			bad = true
		}
	}
	repo.DirtyList = r.Stdout

	pbnow := timestamppb.New(time.Now())
	repo.Times.LastDirty = pbnow
	repo.Dirty = bad
	if bad {
		repo.Dirty = true
		repo.SmartSetState("dirty")
		s := fmt.Sprintf("git status --porcelain report %d dirty files", len(r.Stdout))
		return s, nil
	}
	repo.Dirty = false
	repo.SmartSetState("")
	return "seems clean", nil
}