Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7e502de16a |
No files matched your search
@@ -33,10 +33,6 @@
|
|||||||
under its operand, and counts their sizes in the size census, instead of
|
under its operand, and counts their sizes in the size census, instead of
|
||||||
deleting them (2026-10-14, https://git.eeqj.de/sneak/sfdupes/issues/99)
|
deleting them (2026-10-14, https://git.eeqj.de/sneak/sfdupes/issues/99)
|
||||||
|
|
||||||
- on a terminal, a warning for the last file of a phase no longer erases the
|
|
||||||
phase's finished bar: the bar is drawn again below the warning (2026-10-14,
|
|
||||||
https://git.eeqj.de/sneak/sfdupes/issues/102)
|
|
||||||
|
|
||||||
- `scan` records mtime to the nanosecond, as whole seconds in `mtime` plus
|
- `scan` records mtime to the nanosecond, as whole seconds in `mtime` plus
|
||||||
`mtime_nsec`, and compares it at that resolution, so a same-size rewrite
|
`mtime_nsec`, and compares it at that resolution, so a same-size rewrite
|
||||||
within the same second is re-hashed (2026-10-07,
|
within the same second is re-hashed (2026-10-07,
|
||||||
|
|||||||
@@ -139,13 +139,6 @@ func (p *progress) warnf(format string, args ...any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintln(os.Stderr, msg)
|
fmt.Fprintln(os.Stderr, msg)
|
||||||
|
|
||||||
// The library never draws a finished bar again, so the warning for
|
|
||||||
// a pass's last item would erase it for good: draw its last frame
|
|
||||||
// again below the warning.
|
|
||||||
if p.bar != nil && p.bar.IsFinished() {
|
|
||||||
fmt.Fprint(os.Stderr, p.bar.String())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// finish terminates the pass's display. A bar whose pass stopped short
|
// finish terminates the pass's display. A bar whose pass stopped short
|
||||||
|
|||||||
@@ -187,25 +187,3 @@ func TestBarStoppedShortKeepsCount(t *testing.T) {
|
|||||||
t.Errorf("terminal shows %q, want a count of 2 of 10", shown)
|
t.Errorf("terminal shows %q, want a count of 2 of 10", shown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestWarningAfterLastItemKeepsBar checks that a warning printed after
|
|
||||||
// a pass's last item, as for a failed read of the last file, leaves the
|
|
||||||
// pass's finished bar on the terminal below the warning.
|
|
||||||
//
|
|
||||||
//nolint:paralleltest // captureStderr replaces the process-wide os.Stderr
|
|
||||||
func TestWarningAfterLastItemKeepsBar(t *testing.T) {
|
|
||||||
stderr := captureStderr(t)
|
|
||||||
p := &progress{
|
|
||||||
label: "hash", total: 2, start: time.Now(),
|
|
||||||
bar: newBar("hash", 2),
|
|
||||||
}
|
|
||||||
|
|
||||||
p.increment()
|
|
||||||
p.increment()
|
|
||||||
p.warnf("warning")
|
|
||||||
p.finish()
|
|
||||||
|
|
||||||
if shown := lastFrame(stderr()); !strings.Contains(shown, "(2/2,") {
|
|
||||||
t.Errorf("terminal shows %q, want a count of 2 of 2", shown)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+5
-18
@@ -1138,28 +1138,20 @@ func TestSubdirJobStatError(t *testing.T) {
|
|||||||
// TestScanOneFilesystemKeepsOtherFilesystemRecords checks that with -x a
|
// TestScanOneFilesystemKeepsOtherFilesystemRecords checks that with -x a
|
||||||
// record below a directory the walk does not enter, because it is on
|
// record below a directory the walk does not enter, because it is on
|
||||||
// another filesystem than its operand, counts as outside the operands:
|
// another filesystem than its operand, counts as outside the operands:
|
||||||
// it is not deleted, and its size joins the size census. The record of
|
// it is not deleted, and its size joins the size census. The walk starts
|
||||||
// a gone file that is not below that directory is still deleted, even
|
// from an operand device that no directory here is on, so no second
|
||||||
// when its path begins with the directory's name. The walk starts from
|
// real filesystem is needed; the phases after it run as runPhases runs
|
||||||
// an operand device that no directory here is on, so no second real
|
// them.
|
||||||
// filesystem is needed; the phases after it run as runPhases runs them.
|
|
||||||
func TestScanOneFilesystemKeepsOtherFilesystemRecords(t *testing.T) {
|
func TestScanOneFilesystemKeepsOtherFilesystemRecords(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
db := openTestDB(t)
|
db := openTestDB(t)
|
||||||
|
|
||||||
// A scan without -x records the file below mnt, and mnt2, which is
|
// A scan without -x records the file below mnt.
|
||||||
// beside mnt, not below it.
|
|
||||||
mounted := writeFile(t, dir, "mnt/f", pattern(1, 100))
|
mounted := writeFile(t, dir, "mnt/f", pattern(1, 100))
|
||||||
gone := writeFile(t, dir, "mnt2", pattern(3, 50))
|
|
||||||
syncTree(t, db, dir)
|
syncTree(t, db, dir)
|
||||||
|
|
||||||
err := os.Remove(gone)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The same size as mnt/f, so it is hashed only if mnt/f's size is
|
// The same size as mnt/f, so it is hashed only if mnt/f's size is
|
||||||
// in the census.
|
// in the census.
|
||||||
added := writeFile(t, dir, "added", pattern(2, 100))
|
added := writeFile(t, dir, "added", pattern(2, 100))
|
||||||
@@ -1206,11 +1198,6 @@ func TestScanOneFilesystemKeepsOtherFilesystemRecords(t *testing.T) {
|
|||||||
t.Errorf("%s not hashed: the census lacks the size of %s",
|
t.Errorf("%s not hashed: the census lacks the size of %s",
|
||||||
added, mounted)
|
added, mounted)
|
||||||
}
|
}
|
||||||
|
|
||||||
if slices.Contains(recordPaths(recs), gone) {
|
|
||||||
t.Errorf("record for %s kept: the file is gone and not below mnt",
|
|
||||||
gone)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// buildSmokeTree recreates the README smoke-test filesystem layout
|
// buildSmokeTree recreates the README smoke-test filesystem layout
|
||||||
|
|||||||
Reference in new issue
Block a user