main pico / cmd / scripts / clean-keep-dirs / main.go
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}