diff options
| author | Marc Vertes <mvertes@free.fr> | 2024-09-26 07:22:41 +0200 |
|---|---|---|
| committer | Marc Vertes <mvertes@free.fr> | 2024-09-26 07:22:41 +0200 |
| commit | 9ec19922addee0137f083c66b458c6aefe59191a (patch) | |
| tree | b2ded8c5b3351ed53b9db203eee66b0da78b8e83 /main.go | |
initial commit
Diffstat (limited to 'main.go')
| -rw-r--r-- | main.go | 124 |
1 files changed, 124 insertions, 0 deletions
@@ -0,0 +1,124 @@ +package main + +import ( + "bufio" + "crypto/sha256" + "fmt" + "io/fs" + "log" + "net/url" + "os" + "path/filepath" + "time" +) + +type metadata struct { + size, mtime, mode int64 + // sum [sha256.Size]byte + sum []byte +} + +type metamap map[string]metadata + +func getIndex(root string, mm metamap) (index string, err error) { + filesystem := os.DirFS(root) + err = fs.WalkDir(filesystem, ".", func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + info, err := d.Info() + if err != nil { + return err + } + if info.IsDir() { + if d.Name() == ".bb" { + return fs.SkipDir + } + return nil + } + + b, err := os.ReadFile(path) + if err != nil { + return err + } + + // md := metadata{info.Size(), info.ModTime().Unix(), int64(info.Mode()), sha256.Sum256(b)} + a := sha256.Sum256(b) + md := metadata{info.Size(), info.ModTime().Unix(), int64(info.Mode()), a[:]} + + log.Println(path, md, mm[path]) + + index += fmt.Sprintf("%s %d %d %o %x\n", url.PathEscape(path), md.size, md.mtime, md.mode, md.sum) + return nil + }) + return index, err +} + +func readIndex(path string) (md metamap, err error) { + f, err := os.Open(path) + if err != nil { + return md, err + } + defer f.Close() + md = metamap{} + scan := bufio.NewScanner(f) + for scan.Scan() { + var p string + var d metadata + n, err := fmt.Sscanf(scan.Text(), "%s %d %d %o %64x", &p, &d.size, &d.mtime, &d.mode, &d.sum) + if err != nil || n != 5 { + return md, err + } + path, err := url.PathUnescape(p) + if err != nil { + return md, err + } + md[path] = d + } + if err := scan.Err(); err != nil { + return md, err + } + return md, nil +} + +func initBB(root string) (current, previous string, err error) { + if err = os.MkdirAll(filepath.Join(root, ".bb", "data"), 0o750); err != nil { + return "", "", err + } + prevs, _ := fs.Glob(os.DirFS(root), filepath.Join(".bb", "index-*")) + if len(prevs) > 0 { + previous = prevs[len(prevs)-1] + } + now := time.Now() + y, m, d := now.Date() + h, mn, s := now.Clock() + current = filepath.Join(root, ".bb", fmt.Sprintf("index-%d-%02d%02d-%02d%02d%02d", y, m, d, h, mn, s)) + return current, previous, nil +} + +func main() { + log.SetFlags(log.Lshortfile) + wd, err := os.Getwd() + if err != nil { + log.Fatal(err) + } + index, oldindex, err := initBB(wd) + if err != nil { + log.Fatal(err) + } + + md := metamap{} + if oldindex != "" { + if md, err = readIndex(oldindex); err != nil { + log.Fatal(err) + } + } + data, err := getIndex(wd, md) + if err != nil { + log.Fatal(err) + } + err = os.WriteFile(index, []byte(data), 0o644) + if err != nil { + log.Fatal(err) + } +} |
