aboutsummaryrefslogtreecommitdiffstats
path: root/types.go
diff options
context:
space:
mode:
authorBernhard Guillon <Bernhard.Guillon@begu.org>2026-07-07 23:17:20 +0200
committerBernhard Guillon <Bernhard.Guillon@begu.org>2026-07-07 23:17:20 +0200
commita62e42b9be8402301631c9043f640eb7f43eff29 (patch)
treed85b47ba88a15d9aa7a109c1cd6426ba9faee4f5 /types.go
parent2850cd0c3156cdeb42594664cc087641fe740236 (diff)
downloadsourcewatch-a62e42b9be8402301631c9043f640eb7f43eff29.tar.gz
sourcewatch-a62e42b9be8402301631c9043f640eb7f43eff29.zip
Add FNV-1a content hash to detect same-size changesHEADmain
Diffstat (limited to 'types.go')
-rw-r--r--types.go25
1 files changed, 25 insertions, 0 deletions
diff --git a/types.go b/types.go
index bf5dd00..60e1ea9 100644
--- a/types.go
+++ b/types.go
@@ -2,6 +2,7 @@ package main
import (
"encoding/json"
+ "hash/fnv"
"os"
"time"
)
@@ -17,6 +18,7 @@ type FileMeta struct {
Mode os.FileMode
ModTime time.Time
Symlink string
+ Hash uint64
}
type FileMetaJSON struct {
@@ -24,6 +26,7 @@ type FileMetaJSON struct {
Mode uint32 `json:"mode"`
ModTime string `json:"modtime"`
Symlink string `json:"symlink,omitempty"`
+ Hash uint64 `json:"hash,omitempty"`
}
type Manifest struct {
@@ -45,6 +48,7 @@ func (m *Manifest) ToJSON() map[string]FileMetaJSON {
Mode: uint32(v.Mode),
ModTime: v.ModTime.UTC().Format(time.RFC3339Nano),
Symlink: v.Symlink,
+ Hash: v.Hash,
}
}
return files
@@ -59,6 +63,7 @@ func ManifestFromJSON(files map[string]FileMetaJSON) *Manifest {
Mode: os.FileMode(v.Mode),
ModTime: t,
Symlink: v.Symlink,
+ Hash: v.Hash,
}
}
return m
@@ -75,3 +80,23 @@ func DecodeMessage(data []byte) (*ProtocolMessage, error) {
func EncodeMessage(msg *ProtocolMessage) ([]byte, error) {
return json.Marshal(msg)
}
+
+func hashFile(path string) uint64 {
+ f, err := os.Open(path)
+ if err != nil {
+ return 0
+ }
+ defer f.Close()
+ h := fnv.New64a()
+ buf := make([]byte, 32*1024)
+ for {
+ n, err := f.Read(buf)
+ if n > 0 {
+ h.Write(buf[:n])
+ }
+ if err != nil {
+ break
+ }
+ }
+ return h.Sum64()
+}