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 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
// This helper command identifies duplicated metadata across multiple test
// stages, and replaces them with symlinks in order to make changes to them
// easier to read.
package main
import (
"crypto/sha256"
"fmt"
"log"
"os"
"path/filepath"
)
func main() {
for _, consistentSnapshot := range []bool{false, true} {
err := linkifyDir(fmt.Sprintf("consistent-snapshot-%t", consistentSnapshot))
if err != nil {
log.Fatal(err)
}
}
}
func linkifyDir(rootDir string) error {
stepDirs, err := readStepDirs(rootDir)
if err != nil {
return err
}
oldDir := stepDirs[0]
oldHashes := computeHashes(oldDir)
for _, dir := range stepDirs[1:] {
log.Printf("checking: %s", dir)
hashes := computeHashes(dir)
for path, hash := range hashes {
if oldHashes[path] == hash {
newPath := filepath.Join(dir, path)
oldPath := filepath.Join(oldDir, path)
if err = linkifyPath(oldPath, newPath); err != nil {
return err
}
}
}
oldDir = dir
oldHashes = hashes
log.Printf("-----")
}
return nil
}
func readStepDirs(rootDir string) ([]string, error) {
dirEntries, err := os.ReadDir(rootDir)
if err != nil {
return []string{}, err
}
// We only want to consider linkifying directories.
var dirs []string
for _, dirEntry := range dirEntries {
if dirEntry.IsDir() {
dirs = append(dirs, filepath.Join(rootDir, dirEntry.Name()))
}
}
return dirs, nil
}
func computeHashes(dir string) map[string][32]byte {
hashes := make(map[string][32]byte)
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if info.IsDir() || !info.Mode().IsRegular() {
return nil
}
bytes, err := os.ReadFile(path)
if err != nil {
return err
}
hashes[path[len(dir)+1:]] = sha256.Sum256(bytes)
return nil
})
if err != nil {
log.Fatalf("failed to linkify: %s", err)
}
return hashes
}
func linkifyPath(oldPath string, newPath string) error {
p, err := filepath.Rel(filepath.Dir(newPath), oldPath)
if err != nil {
return err
}
log.Printf("symlinking %s to %s", newPath, p)
if err = os.Remove(newPath); err != nil {
return err
}
if err = os.Symlink(p, newPath); err != nil {
return err
}
return nil
}
|