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

Configure Feed

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

1// Copyright 2016 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package gitindex 16 17import ( 18 "bytes" 19 "fmt" 20 "log" 21 "maps" 22 "os" 23 "os/exec" 24 "path/filepath" 25 "sort" 26 27 git "github.com/go-git/go-git/v5" 28 "github.com/go-git/go-git/v5/config" 29) 30 31// Updates the zoekt.* git config options after a repo is cloned. 32// Once a repo is cloned, we can no longer use the --config flag to update all 33// of it's zoekt.* settings at once. `git config` is limited to one option at once. 34func updateZoektGitConfig(repoDest string, settings map[string]string) error { 35 var keys []string 36 for k := range settings { 37 keys = append(keys, k) 38 } 39 sort.Strings(keys) 40 41 for _, k := range keys { 42 if settings[k] != "" { 43 if err := exec.Command("git", "-C", repoDest, "config", k, settings[k]).Run(); err != nil { 44 return err 45 } 46 } 47 } 48 49 return nil 50} 51 52// CloneRepo clones one repository, adding the given config 53// settings. It returns the bare repo directory. The `name` argument 54// determines where the repo is stored relative to `destDir`. Returns 55// the directory of the repository. 56func CloneRepo(destDir, name, cloneURL string, settings map[string]string) (string, error) { 57 parent := filepath.Join(destDir, filepath.Dir(name)) 58 if err := os.MkdirAll(parent, 0o755); err != nil { 59 return "", err 60 } 61 62 repoDest := filepath.Join(parent, filepath.Base(name)+".git") 63 if _, err := os.Lstat(repoDest); err == nil { 64 // Repository exists, ensure settings are in sync including the clone URL 65 settings := maps.Clone(settings) 66 settings["remote.origin.url"] = cloneURL 67 if err := updateZoektGitConfig(repoDest, settings); err != nil { 68 return "", fmt.Errorf("failed to update repository settings: %w", err) 69 } 70 return "", nil 71 } 72 73 var keys []string 74 for k := range settings { 75 keys = append(keys, k) 76 } 77 sort.Strings(keys) 78 79 var config []string 80 for _, k := range keys { 81 if settings[k] != "" { 82 config = append(config, "--config", k+"="+settings[k]) 83 } 84 } 85 86 cmd := exec.Command( 87 "git", "clone", "--bare", "--verbose", "--progress", 88 ) 89 cmd.Args = append(cmd.Args, config...) 90 cmd.Args = append(cmd.Args, cloneURL, repoDest) 91 92 // Prevent prompting 93 cmd.Stdin = &bytes.Buffer{} 94 log.Println("running:", cmd.Args) 95 if err := cmd.Run(); err != nil { 96 return "", err 97 } 98 99 if err := setFetch(repoDest, "origin", "+refs/heads/*:refs/heads/*"); err != nil { 100 log.Printf("addFetch: %v", err) 101 } 102 return repoDest, nil 103} 104 105func setFetch(repoDir, remote, refspec string) error { 106 repo, err := git.PlainOpen(repoDir) 107 if err != nil { 108 return err 109 } 110 111 cfg, err := repo.Config() 112 if err != nil { 113 return err 114 } 115 116 rm := cfg.Remotes[remote] 117 if rm != nil { 118 rm.Fetch = []config.RefSpec{config.RefSpec(refspec)} 119 } 120 if err := repo.Storer.SetConfig(cfg); err != nil { 121 return err 122 } 123 124 return nil 125}