@@ -6,11 +6,22 @@ import (
66 "os"
77 "path"
88 "path/filepath"
9+ "time"
910)
1011
12+ // Set of allowed file extensions for the safety check before clearing the objects folder
13+ var allowedExtensions = map [string ]struct {}{
14+ ".json" : {},
15+ ".gmnotes" : {},
16+ ".luascriptstate" : {},
17+ ".ttslua" : {},
18+ ".xml" : {},
19+ }
20+
1121// DirCreator abstracts folder creation
1222type DirCreator interface {
1323 CreateDir (relpath string , suggestion string ) (string , error )
24+ Clear () error
1425}
1526
1627// DirExplorer allows files and folders to be enumerated
@@ -51,6 +62,59 @@ func (d *DirOps) CreateDir(relpath, suggestion string) (string, error) {
5162 return dirname , nil
5263}
5364
65+ // preClearCheck walks the directory and ensures all files have an allowed extension.
66+ // It returns an error if a file with a disallowed extension is found.
67+ func (d * DirOps ) preClearCheck () error {
68+ walkErr := filepath .Walk (d .base , func (path string , info os.FileInfo , err error ) error {
69+ if err != nil {
70+ return err
71+ }
72+
73+ // Skip directories
74+ if info .IsDir () {
75+ return nil
76+ }
77+
78+ ext := filepath .Ext (info .Name ())
79+ if _ , isAllowed := allowedExtensions [ext ]; ! isAllowed {
80+ return fmt .Errorf ("unsafe file type found: %s" , path )
81+ }
82+ return nil
83+ })
84+
85+ // If the directory doesn't exist, Walk returns an error. We treat this as "safe".
86+ if os .IsNotExist (walkErr ) {
87+ return nil
88+ }
89+ return walkErr
90+ }
91+
92+ // Clear removes all contents from the base directory and recreates it.
93+ func (d * DirOps ) Clear () error {
94+ log .Println ("Performing safety check..." )
95+ startTime := time .Now ()
96+
97+ if err := d .preClearCheck (); err != nil {
98+ return fmt .Errorf ("pre-clear safety check failed, operation aborted: %w" , err )
99+ }
100+
101+ duration := time .Since (startTime )
102+ log .Printf ("Safety check passed in %v. Proceeding with clear." , duration )
103+
104+ // Remove the directory and all its contents
105+ if err := os .RemoveAll (d .base ); err != nil {
106+ return fmt .Errorf ("error clearing directory %s: %w" , d .base , err )
107+ }
108+
109+ // Recreate the empty directory
110+ if err := os .MkdirAll (d .base , 0755 ); err != nil {
111+ return fmt .Errorf ("error recreating directory %s: %w" , d .base , err )
112+ }
113+
114+ log .Printf ("Cleared and recreated directory: %s" , d .base )
115+ return nil
116+ }
117+
54118// ListFilesAndFolders allows for file exploration. returns relateive file or folder names
55119func (d * DirOps ) ListFilesAndFolders (relpath string ) ([]string , []string , error ) {
56120 p := filepath .Join (d .base , relpath )
0 commit comments