-
Notifications
You must be signed in to change notification settings - Fork 59
/
Copy pathbust_ghosts.go
96 lines (81 loc) · 2.4 KB
/
bust_ghosts.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package bfs
import (
"os"
"path/filepath"
"github.com/itchio/wharf/state"
)
var debugGhostBusting = os.Getenv("BUTLER_LOUD_GHOSTS") == "1"
type BustGhostsParams struct {
Consumer *state.Consumer
Folder string
NewFiles []string
Receipt *Receipt
}
/**
* A ghost busting is performed after performing an install using a method
* that lets us know exactly what was written to disk.
*
* In this case, we:
* - Install in-place, directly into the destination
* - Compare the previous list of installed files with the list
* of files we just wrote to disk
* - Remove all the ghosts
*
* Ghosts are files that were in the previous install and aren't present
* in the new install. Since we don't want to keep old, unnecessary files
* (that aren't angels) around, we just remove them.
*
* See also: save angels.
*/
func BustGhosts(params *BustGhostsParams) error {
if !params.Receipt.HasFiles() {
// if we didn't have a receipt, we can't know for sure
// which files are ghosts, so we just don't wipe anything
params.Consumer.Infof("No receipt found, leaving potential ghosts alone")
return nil
}
oldFiles := params.Receipt.Files
ghostFiles := Difference(params.NewFiles, oldFiles)
if len(ghostFiles) == 0 {
params.Consumer.Infof("No ghosts there!")
return nil
}
if debugGhostBusting {
params.Consumer.Infof("== old files")
for _, f := range oldFiles {
params.Consumer.Infof(" %s", f)
}
params.Consumer.Infof("== new files")
for _, f := range params.NewFiles {
params.Consumer.Infof(" %s", f)
}
params.Consumer.Infof("== ghosts")
for _, f := range ghostFiles {
params.Consumer.Infof(" %s", f)
}
params.Consumer.Infof("=====================")
}
removeFoundGhosts(params, ghostFiles)
return nil
}
func removeFoundGhosts(params *BustGhostsParams, ghostFiles []string) {
for _, ghostFile := range ghostFiles {
absolutePath := filepath.Join(params.Folder, ghostFile)
err := os.Remove(absolutePath)
if err != nil {
params.Consumer.Infof("Leaving ghost file behind (%s): %s", absolutePath, err.Error())
}
}
dt := NewDirTree(params.Folder)
dt.CommitFiles(ghostFiles)
for _, ghostDir := range dt.ListRelativeDirs() {
if ghostDir == "." {
continue
}
absolutePath := filepath.Join(params.Folder, ghostDir)
err := os.Remove(absolutePath)
if err != nil {
params.Consumer.Infof("Leaving directory behind (%s): %s", absolutePath, err.Error())
}
}
}