summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Vertes <mvertes@free.fr>2024-09-26 07:22:41 +0200
committerMarc Vertes <mvertes@free.fr>2024-09-26 07:22:41 +0200
commit9ec19922addee0137f083c66b458c6aefe59191a (patch)
treeb2ded8c5b3351ed53b9db203eee66b0da78b8e83
initial commit
-rw-r--r--.gitignore2
-rw-r--r--doc/README.md0
-rw-r--r--go.mod3
-rw-r--r--index5
-rw-r--r--index.csv2
-rw-r--r--main.go124
6 files changed, 136 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..82be49d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+.bb
+bb
diff --git a/doc/README.md b/doc/README.md
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/doc/README.md
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..6b1a0fa
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,3 @@
+module github.com/mvertes/bb
+
+go 1.23.1
diff --git a/index b/index
new file mode 100644
index 0000000..33da5ba
--- /dev/null
+++ b/index
@@ -0,0 +1,5 @@
+bb 2540306 1727268689 755
+go.mod 40 1727123165 644
+index 132 1727275764 644
+index.csv 23 1727259877 644
+main.go 2203 1727275762 644
diff --git a/index.csv b/index.csv
new file mode 100644
index 0000000..d7a8a50
--- /dev/null
+++ b/index.csv
@@ -0,0 +1,2 @@
+go.mod,40
+main.go,1011
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..9cb32f2
--- /dev/null
+++ b/main.go
@@ -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)
+ }
+}