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