fork of https://github.com/sourcegraph/zoekt
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 main
16
17import (
18 "flag"
19 "log"
20 "os"
21 "path/filepath"
22 "runtime/pprof"
23 "strings"
24
25 "go.uber.org/automaxprocs/maxprocs"
26
27 "github.com/sourcegraph/zoekt/cmd"
28 "github.com/sourcegraph/zoekt/ctags"
29 "github.com/sourcegraph/zoekt/gitindex"
30)
31
32func run() int {
33 cpuprofile := flag.String("cpuprofile", "", "write cpu profile to `file`")
34
35 allowMissing := flag.Bool("allow_missing_branches", false, "allow missing branches.")
36 submodules := flag.Bool("submodules", true, "if set to false, do not recurse into submodules")
37 branchesStr := flag.String("branches", "HEAD", "git branches to index.")
38 branchPrefix := flag.String("prefix", "refs/heads/", "prefix for branch names")
39
40 incremental := flag.Bool("incremental", true, "only index changed repositories")
41 repoCacheDir := flag.String("repo_cache", "", "directory holding bare git repos, named by URL. "+
42 "this is used to find repositories for submodules. "+
43 "It also affects name if the indexed repository is under this directory.")
44 isDelta := flag.Bool("delta", false, "whether we should use delta build")
45 deltaShardNumberFallbackThreshold := flag.Uint64("delta_threshold", 0, "upper limit on the number of preexisting shards that can exist before attempting a delta build (0 to disable fallback behavior)")
46 offlineRanking := flag.String("offline_ranking", "", "the name of the file that contains the ranking info.")
47 offlineRankingVersion := flag.String("offline_ranking_version", "", "a version string identifying the contents in offline_ranking.")
48 languageMap := flag.String("language_map", "", "a mapping between a language and its ctags processor (a:0,b:3).")
49 flag.Parse()
50
51 // Tune GOMAXPROCS to match Linux container CPU quota.
52 _, _ = maxprocs.Set()
53
54 if *cpuprofile != "" {
55 f, err := os.Create(*cpuprofile)
56 if err != nil {
57 log.Fatal("could not create CPU profile: ", err)
58 }
59 defer f.Close() // error handling omitted for example
60 if err := pprof.StartCPUProfile(f); err != nil {
61 log.Fatal("could not start CPU profile: ", err)
62 }
63 defer pprof.StopCPUProfile()
64 }
65
66 if *repoCacheDir != "" {
67 dir, err := filepath.Abs(*repoCacheDir)
68 if err != nil {
69 log.Fatalf("Abs: %v", err)
70 }
71 *repoCacheDir = dir
72 }
73 opts := cmd.OptionsFromFlags()
74 opts.IsDelta = *isDelta
75 opts.DocumentRanksPath = *offlineRanking
76 opts.DocumentRanksVersion = *offlineRankingVersion
77
78 var branches []string
79 if *branchesStr != "" {
80 branches = strings.Split(*branchesStr, ",")
81 }
82
83 gitRepos := map[string]string{}
84 for _, repoDir := range flag.Args() {
85 repoDir, err := filepath.Abs(repoDir)
86 if err != nil {
87 log.Fatal(err)
88 }
89 repoDir = filepath.Clean(repoDir)
90
91 name := strings.TrimSuffix(repoDir, "/.git")
92 if *repoCacheDir != "" && strings.HasPrefix(name, *repoCacheDir) {
93 name = strings.TrimPrefix(name, *repoCacheDir+"/")
94 name = strings.TrimSuffix(name, ".git")
95 } else {
96 name = strings.TrimSuffix(filepath.Base(name), ".git")
97 }
98 gitRepos[repoDir] = name
99 }
100
101 opts.LanguageMap = make(ctags.LanguageMap)
102 for _, mapping := range strings.Split(*languageMap, ",") {
103 m := strings.Split(mapping, ":")
104 if len(m) != 2 {
105 continue
106 }
107 opts.LanguageMap[m[0]] = ctags.StringToParser(m[1])
108 }
109
110 exitStatus := 0
111 for dir, name := range gitRepos {
112 opts.RepositoryDescription.Name = name
113 gitOpts := gitindex.Options{
114 BranchPrefix: *branchPrefix,
115 Incremental: *incremental,
116 Submodules: *submodules,
117 RepoCacheDir: *repoCacheDir,
118 AllowMissingBranch: *allowMissing,
119 BuildOptions: *opts,
120 Branches: branches,
121 RepoDir: dir,
122 DeltaShardNumberFallbackThreshold: *deltaShardNumberFallbackThreshold,
123 }
124
125 if err := gitindex.IndexGitRepo(gitOpts); err != nil {
126 log.Printf("indexGitRepo(%s, delta=%t): %v", dir, gitOpts.BuildOptions.IsDelta, err)
127 exitStatus = 1
128 }
129 }
130
131 return exitStatus
132}
133
134func main() {
135 exitStatus := run()
136 os.Exit(exitStatus)
137}