]> Cypherpunks.ru repositories - goredo.git/blob - cleanup.go
a1f04bd1c667ec8012568404fb971828867b7a67
[goredo.git] / cleanup.go
1 /*
2 goredo -- djb's redo implementation on pure Go
3 Copyright (C) 2020-2024 Sergey Matveev <stargrave@stargrave.org>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, version 3 of the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 package main
19
20 import (
21         "flag"
22         "fmt"
23         "io"
24         "log"
25         "os"
26         "path"
27         "strings"
28 )
29
30 const (
31         CleanupFull = "full"
32         CleanupLog  = "log"
33         CleanupTmp  = "tmp"
34         CleanupLock = "lock"
35 )
36
37 var DryRun *bool
38
39 func init() {
40         if CmdName() != CmdNameRedoCleanup {
41                 return
42         }
43         DryRun = flag.Bool("n", false, "do no delete files during cleanup, just show them")
44 }
45
46 func redoDirClean(root, what string) error {
47         root = mustAbs(root)
48         dir, err := os.Open(root)
49         if err != nil {
50                 return ErrLine(err)
51         }
52         defer dir.Close()
53         for {
54                 entries, err := dir.ReadDir(1 << 10)
55                 if err != nil {
56                         if err == io.EOF {
57                                 break
58                         }
59                         return ErrLine(err)
60                 }
61                 var pth string
62                 for _, entry := range entries {
63                         pth = cwdMustRel(root, entry.Name())
64                         switch what {
65                         case CleanupLog:
66                                 if strings.HasSuffix(entry.Name(), LogSuffix) ||
67                                         strings.HasSuffix(entry.Name(), LogRecSuffix) {
68                                         fmt.Println(pth)
69                                         if !*DryRun {
70                                                 if err = os.Remove(pth); err != nil {
71                                                         return ErrLine(err)
72                                                 }
73                                         }
74                                 }
75                         case CleanupLock:
76                                 if strings.HasSuffix(entry.Name(), LockSuffix) {
77                                         fmt.Println(pth)
78                                         if !*DryRun {
79                                                 if err = os.Remove(pth); err != nil {
80                                                         return ErrLine(err)
81                                                 }
82                                         }
83                                 }
84                         case CleanupTmp:
85                                 if strings.HasPrefix(entry.Name(), TmpPrefix) {
86                                         fmt.Println(pth)
87                                         if !*DryRun {
88                                                 if err = os.Remove(pth); err != nil {
89                                                         return ErrLine(err)
90                                                 }
91                                         }
92                                 }
93                         default:
94                                 log.Fatal("unknown cleanup target")
95                         }
96                 }
97         }
98         return nil
99 }
100
101 func cleanupWalker(root, what string) error {
102         root = mustAbs(root)
103         dir, err := os.Open(root)
104         if err != nil {
105                 return ErrLine(err)
106         }
107         defer dir.Close()
108         for {
109                 entries, err := dir.ReadDir(1 << 10)
110                 if err != nil {
111                         if err == io.EOF {
112                                 break
113                         }
114                         return ErrLine(err)
115                 }
116                 for _, entry := range entries {
117                         pth := path.Join(root, entry.Name())
118                         pthRel := cwdMustRel(root, entry.Name())
119                         if entry.IsDir() {
120                                 if entry.Name() == RedoDir {
121                                         if what == CleanupFull {
122                                                 fmt.Println(pthRel)
123                                                 if !*DryRun {
124                                                         err = ErrLine(os.RemoveAll(pth))
125                                                 }
126                                         } else {
127                                                 err = redoDirClean(pth, what)
128                                         }
129                                 } else if (what == CleanupTmp || what == CleanupFull) &&
130                                         strings.HasPrefix(entry.Name(), TmpPrefix) {
131                                         fmt.Println(pthRel)
132                                         if !*DryRun {
133                                                 err = ErrLine(os.RemoveAll(pth))
134                                         }
135                                 } else {
136                                         err = cleanupWalker(pth, what)
137                                 }
138                                 if err != nil {
139                                         return err
140                                 }
141                                 continue
142                         }
143                         if (what == CleanupTmp || what == CleanupFull) &&
144                                 strings.HasPrefix(entry.Name(), TmpPrefix) {
145                                 fmt.Println(pthRel)
146                                 if !*DryRun {
147                                         if err = os.Remove(pth); err != nil {
148                                                 return ErrLine(err)
149                                         }
150                                 }
151                         }
152                 }
153         }
154         return nil
155 }