This commit is contained in:
Christian Zangl 2024-08-21 13:46:29 +02:00
parent a1327a4d0c
commit d3f4629994
No known key found for this signature in database
GPG Key ID: 6D468AC36E2A4B3D
3 changed files with 51 additions and 45 deletions

View File

@ -63,6 +63,7 @@ var cli struct {
} }
type Main struct { type Main struct {
context *chkbit.Context
dmgList []string dmgList []string
errList []string errList []string
verbose bool verbose bool
@ -104,12 +105,12 @@ func (m *Main) logStatus(stat chkbit.Status, message string) bool {
return false return false
} }
func (m *Main) showStatus(context *chkbit.Context) { func (m *Main) showStatus() {
last := time.Now().Add(-updateInterval) last := time.Now().Add(-updateInterval)
stat := "" stat := ""
for { for {
select { select {
case item := <-context.LogQueue: case item := <-m.context.LogQueue:
if item == nil { if item == nil {
if m.progress == Fancy { if m.progress == Fancy {
lterm.Printline("") lterm.Printline("")
@ -120,10 +121,10 @@ func (m *Main) showStatus(context *chkbit.Context) {
if m.progress == Fancy { if m.progress == Fancy {
lterm.Write(termBG, termFG1, stat, lterm.ClearLine(0), lterm.Reset, "\r") lterm.Write(termBG, termFG1, stat, lterm.ClearLine(0), lterm.Reset, "\r")
} else { } else {
fmt.Print(context.NumTotal, "\r") fmt.Print(m.context.NumTotal, "\r")
} }
} }
case perf := <-context.PerfQueue: case perf := <-m.context.PerfQueue:
now := time.Now() now := time.Now()
m.fps.Push(now, perf.NumFiles) m.fps.Push(now, perf.NumFiles)
m.bps.Push(now, perf.NumBytes) m.bps.Push(now, perf.NumBytes)
@ -133,11 +134,11 @@ func (m *Main) showStatus(context *chkbit.Context) {
statF := fmt.Sprintf("%d files/s", m.fps.Last()) statF := fmt.Sprintf("%d files/s", m.fps.Last())
statB := fmt.Sprintf("%d MB/s", m.bps.Last()/sizeMB) statB := fmt.Sprintf("%d MB/s", m.bps.Last()/sizeMB)
stat = "RW" stat = "RW"
if !context.UpdateIndex { if !m.context.UpdateIndex {
stat = "RO" stat = "RO"
} }
stat = fmt.Sprintf("[%s:%d] %5d files $ %s %-13s $ %s %-13s", stat = fmt.Sprintf("[%s:%d] %5d files $ %s %-13s $ %s %-13s",
stat, context.NumWorkers, context.NumTotal, stat, m.context.NumWorkers, m.context.NumTotal,
util.Sparkline(m.fps.Stats), statF, util.Sparkline(m.fps.Stats), statF,
util.Sparkline(m.bps.Stats), statB) util.Sparkline(m.bps.Stats), statB)
stat = util.LeftTruncate(stat, m.termWidth-1) stat = util.LeftTruncate(stat, m.termWidth-1)
@ -145,44 +146,45 @@ func (m *Main) showStatus(context *chkbit.Context) {
stat = strings.Replace(stat, "$", termSepFG+termSep+termFG3, 1) stat = strings.Replace(stat, "$", termSepFG+termSep+termFG3, 1)
lterm.Write(termBG, termFG1, stat, lterm.ClearLine(0), lterm.Reset, "\r") lterm.Write(termBG, termFG1, stat, lterm.ClearLine(0), lterm.Reset, "\r")
} else if m.progress == Plain { } else if m.progress == Plain {
fmt.Print(context.NumTotal, "\r") fmt.Print(m.context.NumTotal, "\r")
} }
} }
} }
} }
} }
func (m *Main) process() *chkbit.Context { func (m *Main) process() bool {
if cli.Update && cli.ShowIgnoredOnly { if cli.Update && cli.ShowIgnoredOnly {
fmt.Println("Error: use either --update or --show-ignored-only!") fmt.Println("Error: use either --update or --show-ignored-only!")
return nil return false
} }
context, err := chkbit.NewContext(cli.Workers, cli.Algo, cli.IndexName, cli.IgnoreName) var err error
m.context, err = chkbit.NewContext(cli.Workers, cli.Algo, cli.IndexName, cli.IgnoreName)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return nil return false
} }
context.ForceUpdateDmg = cli.Force m.context.ForceUpdateDmg = cli.Force
context.UpdateIndex = cli.Update m.context.UpdateIndex = cli.Update
context.ShowIgnoredOnly = cli.ShowIgnoredOnly m.context.ShowIgnoredOnly = cli.ShowIgnoredOnly
context.ShowMissing = cli.ShowMissing m.context.ShowMissing = cli.ShowMissing
context.SkipSymlinks = cli.SkipSymlinks m.context.SkipSymlinks = cli.SkipSymlinks
context.TrackDirectories = !cli.NoDirInIndex m.context.TrackDirectories = !cli.NoDirInIndex
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Add(1) wg.Add(1)
go func() { go func() {
defer wg.Done() defer wg.Done()
m.showStatus(context) m.showStatus()
}() }()
context.Start(cli.Paths) m.context.Start(cli.Paths)
wg.Wait() wg.Wait()
return context return true
} }
func (m *Main) printResult(context *chkbit.Context) { func (m *Main) printResult() {
cprint := func(col, text string) { cprint := func(col, text string) {
if m.progress != Quiet { if m.progress != Quiet {
if m.progress == Fancy { if m.progress == Fancy {
@ -205,14 +207,14 @@ func (m *Main) printResult(context *chkbit.Context) {
if m.progress != Quiet { if m.progress != Quiet {
mode := "" mode := ""
if !context.UpdateIndex { if !m.context.UpdateIndex {
mode = " in readonly mode" mode = " in readonly mode"
} }
status := fmt.Sprintf("Processed %s%s.", util.LangNum1MutateSuffix(context.NumTotal, "file"), mode) status := fmt.Sprintf("Processed %s%s.", util.LangNum1MutateSuffix(m.context.NumTotal, "file"), mode)
cprint(termOKFG, status) cprint(termOKFG, status)
m.log(status) m.log(status)
if m.progress == Fancy && context.NumTotal > 0 { if m.progress == Fancy && m.context.NumTotal > 0 {
elapsed := time.Since(m.fps.Start) elapsed := time.Since(m.fps.Start)
elapsedS := elapsed.Seconds() elapsedS := elapsed.Seconds()
fmt.Println("-", elapsed.Truncate(time.Second), "elapsed") fmt.Println("-", elapsed.Truncate(time.Second), "elapsed")
@ -221,24 +223,24 @@ func (m *Main) printResult(context *chkbit.Context) {
} }
del := "" del := ""
if context.UpdateIndex { if m.context.UpdateIndex {
if context.NumIdxUpd > 0 { if m.context.NumIdxUpd > 0 {
if context.NumDel > 0 { if m.context.NumDel > 0 {
del = fmt.Sprintf("\n- %s been removed", util.LangNum1Choice(context.NumDel, "file/directory has", "files/directories have")) del = fmt.Sprintf("\n- %s been removed", util.LangNum1Choice(m.context.NumDel, "file/directory has", "files/directories have"))
} }
cprint(termOKFG, fmt.Sprintf("- %s updated\n- %s added\n- %s updated%s", cprint(termOKFG, fmt.Sprintf("- %s updated\n- %s added\n- %s updated%s",
util.LangNum1Choice(context.NumIdxUpd, "directory was", "directories were"), util.LangNum1Choice(m.context.NumIdxUpd, "directory was", "directories were"),
util.LangNum1Choice(context.NumNew, "file hash was", "file hashes were"), util.LangNum1Choice(m.context.NumNew, "file hash was", "file hashes were"),
util.LangNum1Choice(context.NumUpd, "file hash was", "file hashes were"), util.LangNum1Choice(m.context.NumUpd, "file hash was", "file hashes were"),
del)) del))
} }
} else if context.NumNew+context.NumUpd+context.NumDel > 0 { } else if m.context.NumNew+m.context.NumUpd+m.context.NumDel > 0 {
if context.NumDel > 0 { if m.context.NumDel > 0 {
del = fmt.Sprintf("\n- %s would have been removed", util.LangNum1Choice(context.NumDel, "file/directory", "files/directories")) del = fmt.Sprintf("\n- %s would have been removed", util.LangNum1Choice(m.context.NumDel, "file/directory", "files/directories"))
} }
cprint(termAlertFG, fmt.Sprintf("No changes were made (specify -u to update):\n- %s would have been added\n- %s would have been updated%s", cprint(termAlertFG, fmt.Sprintf("No changes were made (specify -u to update):\n- %s would have been added\n- %s would have been updated%s",
util.LangNum1MutateSuffix(context.NumNew, "file"), util.LangNum1MutateSuffix(m.context.NumNew, "file"),
util.LangNum1MutateSuffix(context.NumUpd, "file"), util.LangNum1MutateSuffix(m.context.NumUpd, "file"),
del)) del))
} }
} }
@ -315,9 +317,8 @@ func (m *Main) run() {
if len(cli.Paths) > 0 { if len(cli.Paths) > 0 {
m.log("chkbit " + strings.Join(cli.Paths, ", ")) m.log("chkbit " + strings.Join(cli.Paths, ", "))
context := m.process() if m.process() && !m.context.ShowIgnoredOnly {
if context != nil && !context.ShowIgnoredOnly { m.printResult()
m.printResult(context)
} }
} else { } else {
fmt.Println("specify a path to check, see -h") fmt.Println("specify a path to check, see -h")

View File

@ -23,6 +23,7 @@ type Context struct {
PerfQueue chan *PerfEvent PerfQueue chan *PerfEvent
wg sync.WaitGroup wg sync.WaitGroup
mutex sync.Mutex
NumTotal int NumTotal int
NumIdxUpd int NumIdxUpd int
NumNew int NumNew int
@ -52,6 +53,8 @@ func NewContext(numWorkers int, hashAlgo string, indexFilename string, ignoreFil
} }
func (context *Context) log(stat Status, message string) { func (context *Context) log(stat Status, message string) {
context.mutex.Lock()
defer context.mutex.Unlock()
switch stat { switch stat {
case STATUS_ERR_DMG: case STATUS_ERR_DMG:
context.NumTotal++ context.NumTotal++

View File

@ -182,13 +182,15 @@ func TestRoot(t *testing.T) {
checkOut(t, sout, "2 files/directories have been removed") checkOut(t, sout, "2 files/directories have been removed")
// step4: check again // step4: check again
cmd = exec.Command(tool, "-u", root) for i := 0; i < 10; i++ {
out, err = cmd.Output() cmd = exec.Command(tool, "-u", root)
if err != nil { out, err = cmd.Output()
t.Fatalf("step4 failed with '%s'\n", err) if err != nil {
t.Fatalf("step4 failed with '%s'\n", err)
}
sout = string(out)
checkOut(t, sout, "Processed 289 files")
} }
sout = string(out)
checkOut(t, sout, "Processed 289 files")
} }
func TestDMG(t *testing.T) { func TestDMG(t *testing.T) {