Antonio Mika
·
2026-10-09
1// clean-keep-dirs removes the ._pico_keep_dir markers pgs used to write to
2// keep empty directories. Filesystem storage keeps real directories now, so
3// removing a marker leaves its directory in place.
4package main
5
6import (
7 "flag"
8 "fmt"
9 "io/fs"
10 "log/slog"
11 "os"
12 "path/filepath"
13
14 "github.com/picosh/pico/pkg/storage"
15)
16
17const keepDirName = "._pico_keep_dir"
18
19func main() {
20 deleteFlag := flag.Bool("delete", false, "delete the markers found")
21 flag.Parse()
22
23 logger := slog.Default()
24
25 adapter := storage.GetStorageTypeFromEnv()
26 if adapter != "fs" {
27 logger.Error("markers only exist on filesystem storage", "adapter", adapter)
28 os.Exit(1)
29 }
30 st, err := storage.NewStorage(logger, adapter)
31 if err != nil {
32 logger.Error("failed to create storage", "err", err)
33 os.Exit(1)
34 }
35 root := st.(*storage.StorageFS).Dir
36
37 found, deleted, failed := 0, 0, 0
38 err = filepath.WalkDir(root, func(p string, d fs.DirEntry, err error) error {
39 if err != nil {
40 logger.Error("failed to read", "path", p, "err", err)
41 failed++
42 return nil
43 }
44 if d.IsDir() || d.Name() != keepDirName {
45 return nil
46 }
47 found++
48 if !*deleteFlag {
49 fmt.Println(p)
50 return nil
51 }
52 if err := os.Remove(p); err != nil {
53 logger.Error("failed to delete marker", "path", p, "err", err)
54 failed++
55 return nil
56 }
57 deleted++
58 return nil
59 })
60 if err != nil {
61 logger.Error("failed to walk storage", "root", root, "err", err)
62 os.Exit(1)
63 }
64
65 if !*deleteFlag {
66 fmt.Printf("\nFound %d marker(s) under %s. Use --delete to remove them.\n", found, root)
67 return
68 }
69 fmt.Printf("\nDeleted %d marker(s) under %s, %d failed\n", deleted, root, failed)
70 if failed > 0 {
71 os.Exit(1)
72 }
73}