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
|
package main
import (
"encoding/json"
"hash/fnv"
"os"
"time"
)
type FileEvent struct {
Op string `json:"op"`
Path string `json:"path"`
New string `json:"new_path,omitempty"`
}
type FileMeta struct {
Size int64
Mode os.FileMode
ModTime time.Time
Symlink string
Hash uint64
}
type FileMetaJSON struct {
Size int64 `json:"size"`
Mode uint32 `json:"mode"`
ModTime string `json:"modtime"`
Symlink string `json:"symlink,omitempty"`
Hash uint64 `json:"hash,omitempty"`
}
type Manifest struct {
Files map[string]FileMeta
}
type ProtocolMessage struct {
Type string `json:"type"`
Files map[string]FileMetaJSON `json:"files,omitempty"`
Path string `json:"path,omitempty"`
Content []byte `json:"content,omitempty"`
}
func (m *Manifest) ToJSON() map[string]FileMetaJSON {
files := make(map[string]FileMetaJSON, len(m.Files))
for k, v := range m.Files {
files[k] = FileMetaJSON{
Size: v.Size,
Mode: uint32(v.Mode),
ModTime: v.ModTime.UTC().Format(time.RFC3339Nano),
Symlink: v.Symlink,
Hash: v.Hash,
}
}
return files
}
func ManifestFromJSON(files map[string]FileMetaJSON) *Manifest {
m := &Manifest{Files: make(map[string]FileMeta, len(files))}
for k, v := range files {
t, _ := time.Parse(time.RFC3339Nano, v.ModTime)
m.Files[k] = FileMeta{
Size: v.Size,
Mode: os.FileMode(v.Mode),
ModTime: t,
Symlink: v.Symlink,
Hash: v.Hash,
}
}
return m
}
func DecodeMessage(data []byte) (*ProtocolMessage, error) {
var msg ProtocolMessage
if err := json.Unmarshal(data, &msg); err != nil {
return nil, err
}
return &msg, nil
}
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()
}
|