fork of https://github.com/sourcegraph/zoekt
0

Configure Feed

Select the types of activity you want to include in your feed.

1package main 2 3import ( 4 "encoding/json" 5 "fmt" 6 "os" 7 "path/filepath" 8 9 "golang.org/x/sys/unix" 10 11 "github.com/sourcegraph/zoekt" 12 "github.com/sourcegraph/zoekt/index" 13) 14 15// mergeMeta updates the .meta files for the shards on disk for o. 16// 17// This process is best effort. If anything fails we return on the first 18// failure. This means you might have an inconsistent state on disk if an 19// error is returned. It is recommended to fallback to re-indexing in that 20// case. 21func mergeMeta(o *index.Options) error { 22 todo := map[string]string{} 23 for _, fn := range o.FindAllShards() { 24 repos, md, err := index.ReadMetadataPath(fn) 25 if err != nil { 26 return err 27 } 28 29 var repo *zoekt.Repository 30 for _, cand := range repos { 31 if cand.Name == o.RepositoryDescription.Name { 32 repo = cand 33 break 34 } 35 } 36 37 if repo == nil { 38 return fmt.Errorf("mergeMeta: could not find repo %s in shard %s", o.RepositoryDescription.Name, fn) 39 } 40 41 if updated, err := repo.MergeMutable(&o.RepositoryDescription); err != nil { 42 return err 43 } else if !updated { 44 // This shouldn't happen, but ignore it if it does. We may be working on 45 // an interrupted shard. This helps us converge to something correct. 46 continue 47 } 48 49 var merged any 50 if md.IndexFormatVersion >= 17 { 51 merged = repos 52 } else { 53 // <= v16 expects a single repo, not a list. 54 merged = repo 55 } 56 57 dst := fn + ".meta" 58 tmp, err := jsonMarshalTmpFile(merged, dst) 59 if err != nil { 60 return err 61 } 62 63 todo[tmp] = dst 64 65 // if we fail to rename, this defer will attempt to remove the tmp file. 66 defer os.Remove(tmp) 67 } 68 69 // best effort once we get here. Rename everything. Return error of last 70 // failure. 71 var renameErr error 72 for tmp, dst := range todo { 73 if err := os.Rename(tmp, dst); err != nil { 74 renameErr = err 75 } 76 } 77 78 return renameErr 79} 80 81// jsonMarshalFileTmp marshals v to the temporary file p + ".*.tmp" and 82// returns the file name. 83// 84// Note: .tmp is the same suffix used by Builder. indexserver knows to clean 85// them up. 86func jsonMarshalTmpFile(v any, p string) (_ string, err error) { 87 b, err := json.Marshal(v) 88 if err != nil { 89 return "", err 90 } 91 92 f, err := os.CreateTemp(filepath.Dir(p), filepath.Base(p)+".*.tmp") 93 if err != nil { 94 return "", err 95 } 96 defer func() { 97 f.Close() 98 if err != nil { 99 _ = os.Remove(f.Name()) 100 } 101 }() 102 103 if err := f.Chmod(0o666 &^ umask); err != nil { 104 return "", err 105 } 106 if _, err := f.Write(b); err != nil { 107 return "", err 108 } 109 110 return f.Name(), f.Close() 111} 112 113// respect process umask. build does this. 114var umask os.FileMode 115 116func init() { 117 umask = os.FileMode(unix.Umask(0)) 118 unix.Umask(int(umask)) 119}