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